finished basic traits
This commit is contained in:
1
.rustfmt.toml
Normal file
1
.rustfmt.toml
Normal file
@@ -0,0 +1 @@
|
|||||||
|
max_width=140 # Not ideal
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
FROM rust:1.54
|
FROM rust:1.54
|
||||||
|
|
||||||
RUN apt update && apt-get install -y llvm clang
|
RUN apt update && apt-get install -y llvm clang
|
||||||
|
RUN rustup component add rustfmt
|
||||||
WORKDIR /code
|
WORKDIR /code
|
||||||
|
|||||||
@@ -33,6 +33,8 @@ This language is under active development, progress will be marked here as the l
|
|||||||
- [x] Declaration
|
- [x] Declaration
|
||||||
- [x] Use
|
- [x] Use
|
||||||
- [ ] Traits
|
- [ ] Traits
|
||||||
|
- [x] Basic
|
||||||
|
- [ ] Default Functions
|
||||||
- [ ] Generics
|
- [ ] Generics
|
||||||
- [ ] Basic
|
- [ ] Basic
|
||||||
- [ ] Higher kinded types
|
- [ ] Higher kinded types
|
||||||
|
|||||||
@@ -81,19 +81,19 @@ fn main(): i64 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// type TestTrait trait {
|
type TestTrait trait {
|
||||||
// fn class_method(id: i64): Self;
|
fn class_method(id: i64): Self;
|
||||||
// fn instance_method(self: Self): i64;
|
fn instance_method(self: Self): i64;
|
||||||
// fn default_impl(self: Self): i64 {
|
fn default_impl(self: Self): i64 {
|
||||||
// return self.instance_method();
|
return self.instance_method();
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
//
|
|
||||||
// impl TestTrait for User {
|
impl TestTrait for User {
|
||||||
// fn class_method(id: i64): Self {
|
fn class_method(id: i64): Self {
|
||||||
// return User{id: id,};
|
return User{id: id,};
|
||||||
// }
|
}
|
||||||
// fn instance_method(self: Self): i64 {
|
fn instance_method(self: Self): i64 {
|
||||||
// return self.get_id();
|
return self.get_id();
|
||||||
// }
|
}
|
||||||
// }
|
}
|
||||||
|
|||||||
49
src/ast.rs
49
src/ast.rs
@@ -6,9 +6,7 @@ pub struct IdGenerator {
|
|||||||
|
|
||||||
impl IdGenerator {
|
impl IdGenerator {
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
IdGenerator {
|
IdGenerator { counter: RefCell::new(0) }
|
||||||
counter: RefCell::new(0),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next(&self) -> String {
|
pub fn next(&self) -> String {
|
||||||
@@ -76,15 +74,11 @@ pub enum TypeUsage {
|
|||||||
|
|
||||||
impl TypeUsage {
|
impl TypeUsage {
|
||||||
pub fn new_unknown(id_gen: &IdGenerator) -> TypeUsage {
|
pub fn new_unknown(id_gen: &IdGenerator) -> TypeUsage {
|
||||||
return TypeUsage::Unknown(UnknownTypeUsage {
|
return TypeUsage::Unknown(UnknownTypeUsage { name: id_gen.next() });
|
||||||
name: id_gen.next(),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_named(identifier: Identifier) -> TypeUsage {
|
pub fn new_named(identifier: Identifier) -> TypeUsage {
|
||||||
return TypeUsage::Named(NamedTypeUsage {
|
return TypeUsage::Named(NamedTypeUsage { name: identifier.clone() });
|
||||||
name: identifier.clone(),
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_builtin(name: String) -> TypeUsage {
|
pub fn new_builtin(name: String) -> TypeUsage {
|
||||||
@@ -100,9 +94,7 @@ impl TypeUsage {
|
|||||||
|
|
||||||
pub fn new_function(arg_count: usize, id_gen: &IdGenerator) -> TypeUsage {
|
pub fn new_function(arg_count: usize, id_gen: &IdGenerator) -> TypeUsage {
|
||||||
return TypeUsage::Function(FunctionTypeUsage {
|
return TypeUsage::Function(FunctionTypeUsage {
|
||||||
arguments: (0..arg_count)
|
arguments: (0..arg_count).map(|_| TypeUsage::new_unknown(&id_gen)).collect(),
|
||||||
.map(|_| TypeUsage::new_unknown(&id_gen))
|
|
||||||
.collect(),
|
|
||||||
return_type: Box::new(TypeUsage::new_unknown(&id_gen)),
|
return_type: Box::new(TypeUsage::new_unknown(&id_gen)),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -252,6 +244,25 @@ pub struct FunctionDeclaration {
|
|||||||
pub return_type: TypeUsage,
|
pub return_type: TypeUsage,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl FunctionDeclaration {
|
||||||
|
pub fn to_type(&self) -> TypeUsage {
|
||||||
|
TypeUsage::Function(FunctionTypeUsage {
|
||||||
|
arguments: self.arguments.iter().map(|arg| arg.type_.clone()).collect(),
|
||||||
|
return_type: Box::new(self.return_type.clone()),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_method_type(&self) -> TypeUsage {
|
||||||
|
TypeUsage::Function(FunctionTypeUsage {
|
||||||
|
arguments: self.arguments[1..self.arguments.len()]
|
||||||
|
.iter()
|
||||||
|
.map(|arg| arg.type_.clone())
|
||||||
|
.collect(),
|
||||||
|
return_type: Box::new(self.return_type.clone()),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct Function {
|
pub struct Function {
|
||||||
pub declaration: FunctionDeclaration,
|
pub declaration: FunctionDeclaration,
|
||||||
@@ -275,6 +286,18 @@ pub struct StructTypeDeclaration {
|
|||||||
pub fields: Vec<StructField>,
|
pub fields: Vec<StructField>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub enum TraitItem {
|
||||||
|
FunctionDeclaration(FunctionDeclaration),
|
||||||
|
Function(Function),
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
|
pub struct TraitTypeDeclaration {
|
||||||
|
pub name: Identifier,
|
||||||
|
pub functions: Vec<TraitItem>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct AliasTypeDeclaration {
|
pub struct AliasTypeDeclaration {
|
||||||
pub name: Identifier,
|
pub name: Identifier,
|
||||||
@@ -286,10 +309,12 @@ pub enum TypeDeclaration {
|
|||||||
Struct(StructTypeDeclaration),
|
Struct(StructTypeDeclaration),
|
||||||
Primitive(PrimitiveTypeDeclaration),
|
Primitive(PrimitiveTypeDeclaration),
|
||||||
Alias(AliasTypeDeclaration),
|
Alias(AliasTypeDeclaration),
|
||||||
|
Trait(TraitTypeDeclaration),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||||
pub struct Impl {
|
pub struct Impl {
|
||||||
|
pub trait_: Option<Identifier>,
|
||||||
pub struct_name: Identifier,
|
pub struct_name: Identifier,
|
||||||
pub functions: Vec<Function>,
|
pub functions: Vec<Function>,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,28 +28,18 @@ impl<'ctx> ModuleCodeGen<'ctx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn gen_literal_int(&mut self, literal_int: &ast::LiteralInt) -> IntValue<'ctx> {
|
pub fn gen_literal_int(&mut self, literal_int: &ast::LiteralInt) -> IntValue<'ctx> {
|
||||||
self.context.i64_type().const_int(
|
self.context
|
||||||
unsafe { mem::transmute::<i64, u64>(literal_int.value) },
|
.i64_type()
|
||||||
true,
|
.const_int(unsafe { mem::transmute::<i64, u64>(literal_int.value) }, true)
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gen_op_expression(
|
pub fn gen_op_expression(&mut self, scope: &Scope<'ctx>, operation: &ast::Operation) -> IntValue<'ctx> {
|
||||||
&mut self,
|
|
||||||
scope: &Scope<'ctx>,
|
|
||||||
operation: &ast::Operation,
|
|
||||||
) -> IntValue<'ctx> {
|
|
||||||
let lhs_result = self.gen_expression(scope, &operation.left);
|
let lhs_result = self.gen_expression(scope, &operation.left);
|
||||||
let rhs_result = self.gen_expression(scope, &operation.right);
|
let rhs_result = self.gen_expression(scope, &operation.right);
|
||||||
self.gen_op_int(&lhs_result, &rhs_result, &operation.op)
|
self.gen_op_int(&lhs_result, &rhs_result, &operation.op)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gen_op_int(
|
pub fn gen_op_int(&mut self, lhs: &IntValue<'ctx>, rhs: &IntValue<'ctx>, op: &ast::Operator) -> IntValue<'ctx> {
|
||||||
&mut self,
|
|
||||||
lhs: &IntValue<'ctx>,
|
|
||||||
rhs: &IntValue<'ctx>,
|
|
||||||
op: &ast::Operator,
|
|
||||||
) -> IntValue<'ctx> {
|
|
||||||
match *op {
|
match *op {
|
||||||
ast::Operator::Plus => self.builder.build_int_add(*lhs, *rhs, "add"),
|
ast::Operator::Plus => self.builder.build_int_add(*lhs, *rhs, "add"),
|
||||||
ast::Operator::Minus => self.builder.build_int_sub(*lhs, *rhs, "sub"),
|
ast::Operator::Minus => self.builder.build_int_sub(*lhs, *rhs, "sub"),
|
||||||
@@ -58,35 +48,23 @@ impl<'ctx> ModuleCodeGen<'ctx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gen_expression(
|
pub fn gen_expression(&mut self, scope: &Scope<'ctx>, expression: &Box<ast::Expression>) -> IntValue<'ctx> {
|
||||||
&mut self,
|
|
||||||
scope: &Scope<'ctx>,
|
|
||||||
expression: &Box<ast::Expression>,
|
|
||||||
) -> IntValue<'ctx> {
|
|
||||||
match &**expression {
|
match &**expression {
|
||||||
ast::Expression::LiteralInt(literal_int) => self.gen_literal_int(&literal_int),
|
ast::Expression::LiteralInt(literal_int) => self.gen_literal_int(&literal_int),
|
||||||
ast::Expression::Identifier(identifier) => match scope[&identifier.name] {
|
ast::Expression::Identifier(identifier) => match scope[&identifier.name] {
|
||||||
BasicValueEnum::IntValue(value) => value,
|
BasicValueEnum::IntValue(value) => value,
|
||||||
_ => panic!("function returned type other than int, no types yet"),
|
_ => panic!("function returned type other than int, no types yet"),
|
||||||
},
|
},
|
||||||
ast::Expression::FunctionCall(function_call) => {
|
ast::Expression::FunctionCall(function_call) => self.gen_function_call(scope, &function_call),
|
||||||
self.gen_function_call(scope, &function_call)
|
|
||||||
}
|
|
||||||
ast::Expression::Op(operation) => self.gen_op_expression(scope, &operation),
|
ast::Expression::Op(operation) => self.gen_op_expression(scope, &operation),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn gen_function_call(
|
pub fn gen_function_call(&mut self, scope: &Scope<'ctx>, function_call: &ast::FunctionCall) -> IntValue<'ctx> {
|
||||||
&mut self,
|
|
||||||
scope: &Scope<'ctx>,
|
|
||||||
function_call: &ast::FunctionCall,
|
|
||||||
) -> IntValue<'ctx> {
|
|
||||||
let fn_value = self.module.get_function(&function_call.name.name).unwrap();
|
let fn_value = self.module.get_function(&function_call.name.name).unwrap();
|
||||||
let mut arguments = Vec::new();
|
let mut arguments = Vec::new();
|
||||||
for expression in (&function_call.arguments).into_iter() {
|
for expression in (&function_call.arguments).into_iter() {
|
||||||
arguments.push(BasicValueEnum::IntValue(
|
arguments.push(BasicValueEnum::IntValue(self.gen_expression(scope, &expression)));
|
||||||
self.gen_expression(scope, &expression),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let result = self
|
let result = self
|
||||||
@@ -123,10 +101,7 @@ impl<'ctx> ModuleCodeGen<'ctx> {
|
|||||||
|
|
||||||
let mut scope = self.scope.clone();
|
let mut scope = self.scope.clone();
|
||||||
for (i, param) in (&function.arguments).into_iter().enumerate() {
|
for (i, param) in (&function.arguments).into_iter().enumerate() {
|
||||||
scope.insert(
|
scope.insert(param.name.name.to_string(), fn_value.get_nth_param(i.try_into().unwrap()).unwrap());
|
||||||
param.name.name.to_string(),
|
|
||||||
fn_value.get_nth_param(i.try_into().unwrap()).unwrap(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
let body = &function.block;
|
let body = &function.block;
|
||||||
let return_value = self.gen_expression(&scope, &body.expression);
|
let return_value = self.gen_expression(&scope, &body.expression);
|
||||||
|
|||||||
@@ -18,6 +18,10 @@ pub enum TypingError {
|
|||||||
},
|
},
|
||||||
#[error("unknown field name")]
|
#[error("unknown field name")]
|
||||||
UnknownFieldName { identifier: ast::Identifier },
|
UnknownFieldName { identifier: ast::Identifier },
|
||||||
|
#[error("cannot assign to method")]
|
||||||
|
CannotAssignToMethod { identifier: ast::Identifier },
|
||||||
|
#[error("multiple field name matches")]
|
||||||
|
MultipleFieldName { identifier: ast::Identifier },
|
||||||
#[error("attribute gotten of non-struct")]
|
#[error("attribute gotten of non-struct")]
|
||||||
AttributeOfNonstruct { identifier: ast::Identifier },
|
AttributeOfNonstruct { identifier: ast::Identifier },
|
||||||
#[error("name is not a struct, cannot instaniate")]
|
#[error("name is not a struct, cannot instaniate")]
|
||||||
@@ -27,6 +31,15 @@ pub enum TypingError {
|
|||||||
struct_name: ast::Identifier,
|
struct_name: ast::Identifier,
|
||||||
struct_definition_name: ast::Identifier,
|
struct_definition_name: ast::Identifier,
|
||||||
},
|
},
|
||||||
|
#[error("missing trait function")]
|
||||||
|
MissingTraitFunction {
|
||||||
|
struct_name: ast::Identifier,
|
||||||
|
function_name: ast::Identifier,
|
||||||
|
},
|
||||||
|
#[error("function not in trait")]
|
||||||
|
FunctionNotInTrait { function_name: ast::Identifier },
|
||||||
|
#[error("impl trait must be trait")]
|
||||||
|
ImplTraitMustBeTrait { trait_name: ast::Identifier },
|
||||||
#[error("function call used with non-function")]
|
#[error("function call used with non-function")]
|
||||||
FunctionCallNotAFunction {
|
FunctionCallNotAFunction {
|
||||||
// TODO: add position
|
// TODO: add position
|
||||||
|
|||||||
@@ -25,7 +25,9 @@ match {
|
|||||||
"if",
|
"if",
|
||||||
"else",
|
"else",
|
||||||
"=",
|
"=",
|
||||||
|
"for",
|
||||||
"type",
|
"type",
|
||||||
|
"trait",
|
||||||
"struct",
|
"struct",
|
||||||
"impl",
|
"impl",
|
||||||
",",
|
",",
|
||||||
@@ -208,13 +210,24 @@ pub AliasTypeDeclaration: ast::AliasTypeDeclaration = {
|
|||||||
"type" <i:SpannedIdentifier> "=" <t:TypeUsage> ";" => ast::AliasTypeDeclaration{name: i, replaces: t}
|
"type" <i:SpannedIdentifier> "=" <t:TypeUsage> ";" => ast::AliasTypeDeclaration{name: i, replaces: t}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
pub TraitItem: ast::TraitItem = {
|
||||||
|
<fd:FunctionDeclaration> ";" => ast::TraitItem::FunctionDeclaration(fd),
|
||||||
|
<f:Function> => ast::TraitItem::Function(f),
|
||||||
|
};
|
||||||
|
|
||||||
|
pub TraitTypeDeclaration: ast::TraitTypeDeclaration = {
|
||||||
|
"type" <i:SpannedIdentifier> "trait" "{" <ti:TraitItem*> "}" => ast::TraitTypeDeclaration{name: i, functions: ti},
|
||||||
|
};
|
||||||
|
|
||||||
pub TypeDeclaration: ast::TypeDeclaration = {
|
pub TypeDeclaration: ast::TypeDeclaration = {
|
||||||
<s:StructTypeDeclaration> => ast::TypeDeclaration::Struct(s),
|
<s:StructTypeDeclaration> => ast::TypeDeclaration::Struct(s),
|
||||||
<a:AliasTypeDeclaration> => ast::TypeDeclaration::Alias(a),
|
<a:AliasTypeDeclaration> => ast::TypeDeclaration::Alias(a),
|
||||||
|
<t:TraitTypeDeclaration> => ast::TypeDeclaration::Trait(t),
|
||||||
};
|
};
|
||||||
|
|
||||||
pub Impl: ast::Impl = {
|
pub Impl: ast::Impl = {
|
||||||
"impl" <i:SpannedIdentifier> "{" <f:Function*> "}" => ast::Impl{struct_name: i, functions: f}
|
"impl" <i:SpannedIdentifier> "{" <f:Function*> "}" => ast::Impl{trait_: None, struct_name: i, functions: f},
|
||||||
|
"impl" <t:SpannedIdentifier> "for" <i:SpannedIdentifier> "{" <f:Function*> "}" => ast::Impl{trait_: Some(t), struct_name: i, functions: f},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub ModuleItem: ast::ModuleItem = {
|
pub ModuleItem: ast::ModuleItem = {
|
||||||
|
|||||||
@@ -58,8 +58,7 @@ struct Context {
|
|||||||
|
|
||||||
impl Context {
|
impl Context {
|
||||||
fn set_variable(&mut self, name: String, value: &Value) {
|
fn set_variable(&mut self, name: String, value: &Value) {
|
||||||
self.environment
|
self.environment.insert(name.to_string(), NamedEntity::Variable(value.clone()));
|
||||||
.insert(name.to_string(), NamedEntity::Variable(value.clone()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn new_env(&self) -> Context {
|
fn new_env(&self) -> Context {
|
||||||
@@ -94,8 +93,7 @@ impl Context {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
ast::ModuleItem::Impl(impl_) => {
|
ast::ModuleItem::Impl(impl_) => {
|
||||||
ctx.impls
|
ctx.impls.insert(impl_.struct_name.name.value.to_string(), impl_.clone());
|
||||||
.insert(impl_.struct_name.name.value.to_string(), impl_.clone());
|
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
}
|
}
|
||||||
@@ -108,127 +106,97 @@ fn create_builtins() -> HashMap<String, NamedEntity> {
|
|||||||
let mut result = HashMap::new();
|
let mut result = HashMap::new();
|
||||||
result.insert(
|
result.insert(
|
||||||
"i8".to_string(),
|
"i8".to_string(),
|
||||||
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(
|
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
|
||||||
ast::PrimitiveTypeDeclaration {
|
|
||||||
name: "i8".to_string(),
|
name: "i8".to_string(),
|
||||||
},
|
})),
|
||||||
)),
|
|
||||||
);
|
);
|
||||||
result.insert(
|
result.insert(
|
||||||
"i16".to_string(),
|
"i16".to_string(),
|
||||||
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(
|
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
|
||||||
ast::PrimitiveTypeDeclaration {
|
|
||||||
name: "i16".to_string(),
|
name: "i16".to_string(),
|
||||||
},
|
})),
|
||||||
)),
|
|
||||||
);
|
);
|
||||||
result.insert(
|
result.insert(
|
||||||
"i32".to_string(),
|
"i32".to_string(),
|
||||||
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(
|
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
|
||||||
ast::PrimitiveTypeDeclaration {
|
|
||||||
name: "i32".to_string(),
|
name: "i32".to_string(),
|
||||||
},
|
})),
|
||||||
)),
|
|
||||||
);
|
);
|
||||||
result.insert(
|
result.insert(
|
||||||
"i64".to_string(),
|
"i64".to_string(),
|
||||||
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(
|
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
|
||||||
ast::PrimitiveTypeDeclaration {
|
|
||||||
name: "i64".to_string(),
|
name: "i64".to_string(),
|
||||||
},
|
})),
|
||||||
)),
|
|
||||||
);
|
);
|
||||||
result.insert(
|
result.insert(
|
||||||
"isize".to_string(),
|
"isize".to_string(),
|
||||||
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(
|
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
|
||||||
ast::PrimitiveTypeDeclaration {
|
|
||||||
name: "isize".to_string(),
|
name: "isize".to_string(),
|
||||||
},
|
})),
|
||||||
)),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
result.insert(
|
result.insert(
|
||||||
"u8".to_string(),
|
"u8".to_string(),
|
||||||
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(
|
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
|
||||||
ast::PrimitiveTypeDeclaration {
|
|
||||||
name: "u8".to_string(),
|
name: "u8".to_string(),
|
||||||
},
|
})),
|
||||||
)),
|
|
||||||
);
|
);
|
||||||
result.insert(
|
result.insert(
|
||||||
"u16".to_string(),
|
"u16".to_string(),
|
||||||
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(
|
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
|
||||||
ast::PrimitiveTypeDeclaration {
|
|
||||||
name: "u16".to_string(),
|
name: "u16".to_string(),
|
||||||
},
|
})),
|
||||||
)),
|
|
||||||
);
|
);
|
||||||
result.insert(
|
result.insert(
|
||||||
"u32".to_string(),
|
"u32".to_string(),
|
||||||
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(
|
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
|
||||||
ast::PrimitiveTypeDeclaration {
|
|
||||||
name: "u32".to_string(),
|
name: "u32".to_string(),
|
||||||
},
|
})),
|
||||||
)),
|
|
||||||
);
|
);
|
||||||
result.insert(
|
result.insert(
|
||||||
"u64".to_string(),
|
"u64".to_string(),
|
||||||
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(
|
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
|
||||||
ast::PrimitiveTypeDeclaration {
|
|
||||||
name: "u64".to_string(),
|
name: "u64".to_string(),
|
||||||
},
|
})),
|
||||||
)),
|
|
||||||
);
|
);
|
||||||
result.insert(
|
result.insert(
|
||||||
"usize".to_string(),
|
"usize".to_string(),
|
||||||
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(
|
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
|
||||||
ast::PrimitiveTypeDeclaration {
|
|
||||||
name: "usize".to_string(),
|
name: "usize".to_string(),
|
||||||
},
|
})),
|
||||||
)),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
result.insert(
|
result.insert(
|
||||||
"f32".to_string(),
|
"f32".to_string(),
|
||||||
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(
|
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
|
||||||
ast::PrimitiveTypeDeclaration {
|
|
||||||
name: "f32".to_string(),
|
name: "f32".to_string(),
|
||||||
},
|
})),
|
||||||
)),
|
|
||||||
);
|
);
|
||||||
result.insert(
|
result.insert(
|
||||||
"f64".to_string(),
|
"f64".to_string(),
|
||||||
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(
|
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
|
||||||
ast::PrimitiveTypeDeclaration {
|
|
||||||
name: "f64".to_string(),
|
name: "f64".to_string(),
|
||||||
},
|
})),
|
||||||
)),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
result.insert(
|
result.insert(
|
||||||
"bool".to_string(),
|
"bool".to_string(),
|
||||||
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(
|
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
|
||||||
ast::PrimitiveTypeDeclaration {
|
|
||||||
name: "bool".to_string(),
|
name: "bool".to_string(),
|
||||||
},
|
})),
|
||||||
)),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
result.insert(
|
result.insert(
|
||||||
"!".to_string(),
|
"!".to_string(),
|
||||||
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(
|
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
|
||||||
ast::PrimitiveTypeDeclaration {
|
|
||||||
name: "!".to_string(),
|
name: "!".to_string(),
|
||||||
},
|
})),
|
||||||
)),
|
|
||||||
);
|
);
|
||||||
result.insert(
|
result.insert(
|
||||||
"unit".to_string(),
|
"unit".to_string(),
|
||||||
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(
|
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
|
||||||
ast::PrimitiveTypeDeclaration {
|
|
||||||
name: "!".to_string(),
|
name: "!".to_string(),
|
||||||
},
|
})),
|
||||||
)),
|
|
||||||
);
|
);
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
@@ -277,11 +245,7 @@ impl TreeWalkInterpreter {
|
|||||||
return last;
|
return last;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_statement(
|
fn with_statement(self: &Self, ctx: &mut Context, statement: &ast::Statement) -> ExpressionResult {
|
||||||
self: &Self,
|
|
||||||
ctx: &mut Context,
|
|
||||||
statement: &ast::Statement,
|
|
||||||
) -> ExpressionResult {
|
|
||||||
match statement {
|
match statement {
|
||||||
ast::Statement::Return(return_statement) => {
|
ast::Statement::Return(return_statement) => {
|
||||||
let result = match self.with_expression(ctx, &return_statement.source) {
|
let result = match self.with_expression(ctx, &return_statement.source) {
|
||||||
@@ -311,11 +275,7 @@ impl TreeWalkInterpreter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_assignment_statement(
|
fn with_assignment_statement(self: &Self, ctx: &mut Context, statement: &ast::AssignmentStatement) -> ExpressionResult {
|
||||||
self: &Self,
|
|
||||||
ctx: &mut Context,
|
|
||||||
statement: &ast::AssignmentStatement,
|
|
||||||
) -> ExpressionResult {
|
|
||||||
let result = match self.with_expression(ctx, &statement.expression) {
|
let result = match self.with_expression(ctx, &statement.expression) {
|
||||||
ExpressionResult::Value(r) => r,
|
ExpressionResult::Value(r) => r,
|
||||||
ExpressionResult::Return(r) => {
|
ExpressionResult::Return(r) => {
|
||||||
@@ -336,9 +296,7 @@ impl TreeWalkInterpreter {
|
|||||||
match &mut source {
|
match &mut source {
|
||||||
Value::Struct(s) => {
|
Value::Struct(s) => {
|
||||||
let mut struct_ = s.lock().unwrap();
|
let mut struct_ = s.lock().unwrap();
|
||||||
struct_
|
struct_.fields.insert(struct_attr.attribute.name.value.clone(), result);
|
||||||
.fields
|
|
||||||
.insert(struct_attr.attribute.name.value.clone(), result);
|
|
||||||
}
|
}
|
||||||
_ => panic!("set attr on nonstruct, should never happen due to type system"),
|
_ => panic!("set attr on nonstruct, should never happen due to type system"),
|
||||||
}
|
}
|
||||||
@@ -347,11 +305,7 @@ impl TreeWalkInterpreter {
|
|||||||
return ExpressionResult::Value(Value::Unit);
|
return ExpressionResult::Value(Value::Unit);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_expression(
|
fn with_expression(self: &Self, ctx: &mut Context, expression: &ast::Expression) -> ExpressionResult {
|
||||||
self: &Self,
|
|
||||||
ctx: &mut Context,
|
|
||||||
expression: &ast::Expression,
|
|
||||||
) -> ExpressionResult {
|
|
||||||
match &*expression.subexpression {
|
match &*expression.subexpression {
|
||||||
ast::Subexpression::LiteralInt(literal_int) => {
|
ast::Subexpression::LiteralInt(literal_int) => {
|
||||||
let value: i64 = literal_int.value.value.parse().unwrap();
|
let value: i64 = literal_int.value.value.parse().unwrap();
|
||||||
@@ -362,18 +316,12 @@ impl TreeWalkInterpreter {
|
|||||||
return ExpressionResult::Value(Value::Numeric(NumericValue::F64(value)));
|
return ExpressionResult::Value(Value::Numeric(NumericValue::F64(value)));
|
||||||
}
|
}
|
||||||
ast::Subexpression::LiteralBool(literal_bool) => {
|
ast::Subexpression::LiteralBool(literal_bool) => {
|
||||||
let value: bool = if &literal_bool.value.value == "true" {
|
let value: bool = if &literal_bool.value.value == "true" { true } else { false };
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
};
|
|
||||||
return ExpressionResult::Value(Value::Bool(value));
|
return ExpressionResult::Value(Value::Bool(value));
|
||||||
}
|
}
|
||||||
ast::Subexpression::LiteralStruct(literal_struct) => {
|
ast::Subexpression::LiteralStruct(literal_struct) => {
|
||||||
let declaration = match &ctx.environment[&literal_struct.name.name.value] {
|
let declaration = match &ctx.environment[&literal_struct.name.name.value] {
|
||||||
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Struct(declaration)) => {
|
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Struct(declaration)) => declaration.clone(),
|
||||||
declaration.clone()
|
|
||||||
}
|
|
||||||
_ => panic!("not a struct"),
|
_ => panic!("not a struct"),
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -416,17 +364,10 @@ impl TreeWalkInterpreter {
|
|||||||
match &source {
|
match &source {
|
||||||
Value::Function(Function::User(user_function)) => {
|
Value::Function(Function::User(user_function)) => {
|
||||||
let mut fn_ctx = ctx.new_env();
|
let mut fn_ctx = ctx.new_env();
|
||||||
for (i, function_arg) in
|
for (i, function_arg) in user_function.declaration.arguments.iter().enumerate() {
|
||||||
user_function.declaration.arguments.iter().enumerate()
|
fn_ctx.set_variable(function_arg.name.name.value.to_string(), &argument_values[i].clone());
|
||||||
{
|
|
||||||
fn_ctx.set_variable(
|
|
||||||
function_arg.name.name.value.to_string(),
|
|
||||||
&argument_values[i].clone(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
return ExpressionResult::Value(
|
return ExpressionResult::Value(self.with_function(&mut fn_ctx, user_function));
|
||||||
self.with_function(&mut fn_ctx, user_function),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
Value::Function(Function::Builtin(builtin_function)) => {
|
Value::Function(Function::Builtin(builtin_function)) => {
|
||||||
return ExpressionResult::Value(builtin_function(argument_values));
|
return ExpressionResult::Value(builtin_function(argument_values));
|
||||||
@@ -473,9 +414,7 @@ impl TreeWalkInterpreter {
|
|||||||
match &source {
|
match &source {
|
||||||
Value::Struct(struct_) => {
|
Value::Struct(struct_) => {
|
||||||
let s = struct_.lock().unwrap();
|
let s = struct_.lock().unwrap();
|
||||||
return ExpressionResult::Value(
|
return ExpressionResult::Value(s.fields[&struct_getter.attribute.name.value].clone());
|
||||||
s.fields[&struct_getter.attribute.name.value].clone(),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
panic!("TypeError: struct getter used with non-struct");
|
panic!("TypeError: struct getter used with non-struct");
|
||||||
@@ -500,217 +439,137 @@ impl TreeWalkInterpreter {
|
|||||||
};
|
};
|
||||||
let result = match (&left, &op.op, &right) {
|
let result = match (&left, &op.op, &right) {
|
||||||
//I
|
//I
|
||||||
(
|
(Value::Numeric(NumericValue::I8(l)), ast::Operator::Plus, Value::Numeric(NumericValue::I8(r))) => {
|
||||||
Value::Numeric(NumericValue::I8(l)),
|
Value::Numeric(NumericValue::I8(l + r))
|
||||||
ast::Operator::Plus,
|
}
|
||||||
Value::Numeric(NumericValue::I8(r)),
|
(Value::Numeric(NumericValue::I8(l)), ast::Operator::Minus, Value::Numeric(NumericValue::I8(r))) => {
|
||||||
) => Value::Numeric(NumericValue::I8(l + r)),
|
Value::Numeric(NumericValue::I8(l - r))
|
||||||
(
|
}
|
||||||
Value::Numeric(NumericValue::I8(l)),
|
(Value::Numeric(NumericValue::I8(l)), ast::Operator::Mul, Value::Numeric(NumericValue::I8(r))) => {
|
||||||
ast::Operator::Minus,
|
Value::Numeric(NumericValue::I8(l * r))
|
||||||
Value::Numeric(NumericValue::I8(r)),
|
}
|
||||||
) => Value::Numeric(NumericValue::I8(l - r)),
|
(Value::Numeric(NumericValue::I8(l)), ast::Operator::Div, Value::Numeric(NumericValue::I8(r))) => {
|
||||||
(
|
Value::Numeric(NumericValue::I8(l / r))
|
||||||
Value::Numeric(NumericValue::I8(l)),
|
}
|
||||||
ast::Operator::Mul,
|
|
||||||
Value::Numeric(NumericValue::I8(r)),
|
|
||||||
) => Value::Numeric(NumericValue::I8(l * r)),
|
|
||||||
(
|
|
||||||
Value::Numeric(NumericValue::I8(l)),
|
|
||||||
ast::Operator::Div,
|
|
||||||
Value::Numeric(NumericValue::I8(r)),
|
|
||||||
) => Value::Numeric(NumericValue::I8(l / r)),
|
|
||||||
|
|
||||||
(
|
(Value::Numeric(NumericValue::I16(l)), ast::Operator::Plus, Value::Numeric(NumericValue::I16(r))) => {
|
||||||
Value::Numeric(NumericValue::I16(l)),
|
Value::Numeric(NumericValue::I16(l + r))
|
||||||
ast::Operator::Plus,
|
}
|
||||||
Value::Numeric(NumericValue::I16(r)),
|
(Value::Numeric(NumericValue::I16(l)), ast::Operator::Minus, Value::Numeric(NumericValue::I16(r))) => {
|
||||||
) => Value::Numeric(NumericValue::I16(l + r)),
|
Value::Numeric(NumericValue::I16(l - r))
|
||||||
(
|
}
|
||||||
Value::Numeric(NumericValue::I16(l)),
|
(Value::Numeric(NumericValue::I16(l)), ast::Operator::Mul, Value::Numeric(NumericValue::I16(r))) => {
|
||||||
ast::Operator::Minus,
|
Value::Numeric(NumericValue::I16(l * r))
|
||||||
Value::Numeric(NumericValue::I16(r)),
|
}
|
||||||
) => Value::Numeric(NumericValue::I16(l - r)),
|
(Value::Numeric(NumericValue::I16(l)), ast::Operator::Div, Value::Numeric(NumericValue::I16(r))) => {
|
||||||
(
|
Value::Numeric(NumericValue::I16(l / r))
|
||||||
Value::Numeric(NumericValue::I16(l)),
|
}
|
||||||
ast::Operator::Mul,
|
|
||||||
Value::Numeric(NumericValue::I16(r)),
|
|
||||||
) => Value::Numeric(NumericValue::I16(l * r)),
|
|
||||||
(
|
|
||||||
Value::Numeric(NumericValue::I16(l)),
|
|
||||||
ast::Operator::Div,
|
|
||||||
Value::Numeric(NumericValue::I16(r)),
|
|
||||||
) => Value::Numeric(NumericValue::I16(l / r)),
|
|
||||||
|
|
||||||
(
|
(Value::Numeric(NumericValue::I32(l)), ast::Operator::Plus, Value::Numeric(NumericValue::I32(r))) => {
|
||||||
Value::Numeric(NumericValue::I32(l)),
|
Value::Numeric(NumericValue::I32(l + r))
|
||||||
ast::Operator::Plus,
|
}
|
||||||
Value::Numeric(NumericValue::I32(r)),
|
(Value::Numeric(NumericValue::I32(l)), ast::Operator::Minus, Value::Numeric(NumericValue::I32(r))) => {
|
||||||
) => Value::Numeric(NumericValue::I32(l + r)),
|
Value::Numeric(NumericValue::I32(l - r))
|
||||||
(
|
}
|
||||||
Value::Numeric(NumericValue::I32(l)),
|
(Value::Numeric(NumericValue::I32(l)), ast::Operator::Mul, Value::Numeric(NumericValue::I32(r))) => {
|
||||||
ast::Operator::Minus,
|
Value::Numeric(NumericValue::I32(l * r))
|
||||||
Value::Numeric(NumericValue::I32(r)),
|
}
|
||||||
) => Value::Numeric(NumericValue::I32(l - r)),
|
(Value::Numeric(NumericValue::I32(l)), ast::Operator::Div, Value::Numeric(NumericValue::I32(r))) => {
|
||||||
(
|
Value::Numeric(NumericValue::I32(l / r))
|
||||||
Value::Numeric(NumericValue::I32(l)),
|
}
|
||||||
ast::Operator::Mul,
|
|
||||||
Value::Numeric(NumericValue::I32(r)),
|
|
||||||
) => Value::Numeric(NumericValue::I32(l * r)),
|
|
||||||
(
|
|
||||||
Value::Numeric(NumericValue::I32(l)),
|
|
||||||
ast::Operator::Div,
|
|
||||||
Value::Numeric(NumericValue::I32(r)),
|
|
||||||
) => Value::Numeric(NumericValue::I32(l / r)),
|
|
||||||
|
|
||||||
(
|
(Value::Numeric(NumericValue::I64(l)), ast::Operator::Plus, Value::Numeric(NumericValue::I64(r))) => {
|
||||||
Value::Numeric(NumericValue::I64(l)),
|
Value::Numeric(NumericValue::I64(l + r))
|
||||||
ast::Operator::Plus,
|
}
|
||||||
Value::Numeric(NumericValue::I64(r)),
|
(Value::Numeric(NumericValue::I64(l)), ast::Operator::Minus, Value::Numeric(NumericValue::I64(r))) => {
|
||||||
) => Value::Numeric(NumericValue::I64(l + r)),
|
Value::Numeric(NumericValue::I64(l - r))
|
||||||
(
|
}
|
||||||
Value::Numeric(NumericValue::I64(l)),
|
(Value::Numeric(NumericValue::I64(l)), ast::Operator::Mul, Value::Numeric(NumericValue::I64(r))) => {
|
||||||
ast::Operator::Minus,
|
Value::Numeric(NumericValue::I64(l * r))
|
||||||
Value::Numeric(NumericValue::I64(r)),
|
}
|
||||||
) => Value::Numeric(NumericValue::I64(l - r)),
|
(Value::Numeric(NumericValue::I64(l)), ast::Operator::Div, Value::Numeric(NumericValue::I64(r))) => {
|
||||||
(
|
Value::Numeric(NumericValue::I64(l / r))
|
||||||
Value::Numeric(NumericValue::I64(l)),
|
}
|
||||||
ast::Operator::Mul,
|
|
||||||
Value::Numeric(NumericValue::I64(r)),
|
|
||||||
) => Value::Numeric(NumericValue::I64(l * r)),
|
|
||||||
(
|
|
||||||
Value::Numeric(NumericValue::I64(l)),
|
|
||||||
ast::Operator::Div,
|
|
||||||
Value::Numeric(NumericValue::I64(r)),
|
|
||||||
) => Value::Numeric(NumericValue::I64(l / r)),
|
|
||||||
|
|
||||||
//U
|
//U
|
||||||
(
|
(Value::Numeric(NumericValue::U8(l)), ast::Operator::Plus, Value::Numeric(NumericValue::U8(r))) => {
|
||||||
Value::Numeric(NumericValue::U8(l)),
|
Value::Numeric(NumericValue::U8(l + r))
|
||||||
ast::Operator::Plus,
|
}
|
||||||
Value::Numeric(NumericValue::U8(r)),
|
(Value::Numeric(NumericValue::U8(l)), ast::Operator::Minus, Value::Numeric(NumericValue::U8(r))) => {
|
||||||
) => Value::Numeric(NumericValue::U8(l + r)),
|
Value::Numeric(NumericValue::U8(l - r))
|
||||||
(
|
}
|
||||||
Value::Numeric(NumericValue::U8(l)),
|
(Value::Numeric(NumericValue::U8(l)), ast::Operator::Mul, Value::Numeric(NumericValue::U8(r))) => {
|
||||||
ast::Operator::Minus,
|
Value::Numeric(NumericValue::U8(l * r))
|
||||||
Value::Numeric(NumericValue::U8(r)),
|
}
|
||||||
) => Value::Numeric(NumericValue::U8(l - r)),
|
(Value::Numeric(NumericValue::U8(l)), ast::Operator::Div, Value::Numeric(NumericValue::U8(r))) => {
|
||||||
(
|
Value::Numeric(NumericValue::U8(l / r))
|
||||||
Value::Numeric(NumericValue::U8(l)),
|
}
|
||||||
ast::Operator::Mul,
|
|
||||||
Value::Numeric(NumericValue::U8(r)),
|
|
||||||
) => Value::Numeric(NumericValue::U8(l * r)),
|
|
||||||
(
|
|
||||||
Value::Numeric(NumericValue::U8(l)),
|
|
||||||
ast::Operator::Div,
|
|
||||||
Value::Numeric(NumericValue::U8(r)),
|
|
||||||
) => Value::Numeric(NumericValue::U8(l / r)),
|
|
||||||
|
|
||||||
(
|
(Value::Numeric(NumericValue::U16(l)), ast::Operator::Plus, Value::Numeric(NumericValue::U16(r))) => {
|
||||||
Value::Numeric(NumericValue::U16(l)),
|
Value::Numeric(NumericValue::U16(l + r))
|
||||||
ast::Operator::Plus,
|
}
|
||||||
Value::Numeric(NumericValue::U16(r)),
|
(Value::Numeric(NumericValue::U16(l)), ast::Operator::Minus, Value::Numeric(NumericValue::U16(r))) => {
|
||||||
) => Value::Numeric(NumericValue::U16(l + r)),
|
Value::Numeric(NumericValue::U16(l - r))
|
||||||
(
|
}
|
||||||
Value::Numeric(NumericValue::U16(l)),
|
(Value::Numeric(NumericValue::U16(l)), ast::Operator::Mul, Value::Numeric(NumericValue::U16(r))) => {
|
||||||
ast::Operator::Minus,
|
Value::Numeric(NumericValue::U16(l * r))
|
||||||
Value::Numeric(NumericValue::U16(r)),
|
}
|
||||||
) => Value::Numeric(NumericValue::U16(l - r)),
|
(Value::Numeric(NumericValue::U16(l)), ast::Operator::Div, Value::Numeric(NumericValue::U16(r))) => {
|
||||||
(
|
Value::Numeric(NumericValue::U16(l / r))
|
||||||
Value::Numeric(NumericValue::U16(l)),
|
}
|
||||||
ast::Operator::Mul,
|
|
||||||
Value::Numeric(NumericValue::U16(r)),
|
|
||||||
) => Value::Numeric(NumericValue::U16(l * r)),
|
|
||||||
(
|
|
||||||
Value::Numeric(NumericValue::U16(l)),
|
|
||||||
ast::Operator::Div,
|
|
||||||
Value::Numeric(NumericValue::U16(r)),
|
|
||||||
) => Value::Numeric(NumericValue::U16(l / r)),
|
|
||||||
|
|
||||||
(
|
(Value::Numeric(NumericValue::U32(l)), ast::Operator::Plus, Value::Numeric(NumericValue::U32(r))) => {
|
||||||
Value::Numeric(NumericValue::U32(l)),
|
Value::Numeric(NumericValue::U32(l + r))
|
||||||
ast::Operator::Plus,
|
}
|
||||||
Value::Numeric(NumericValue::U32(r)),
|
(Value::Numeric(NumericValue::U32(l)), ast::Operator::Minus, Value::Numeric(NumericValue::U32(r))) => {
|
||||||
) => Value::Numeric(NumericValue::U32(l + r)),
|
Value::Numeric(NumericValue::U32(l - r))
|
||||||
(
|
}
|
||||||
Value::Numeric(NumericValue::U32(l)),
|
(Value::Numeric(NumericValue::U32(l)), ast::Operator::Mul, Value::Numeric(NumericValue::U32(r))) => {
|
||||||
ast::Operator::Minus,
|
Value::Numeric(NumericValue::U32(l * r))
|
||||||
Value::Numeric(NumericValue::U32(r)),
|
}
|
||||||
) => Value::Numeric(NumericValue::U32(l - r)),
|
(Value::Numeric(NumericValue::U32(l)), ast::Operator::Div, Value::Numeric(NumericValue::U32(r))) => {
|
||||||
(
|
Value::Numeric(NumericValue::U32(l / r))
|
||||||
Value::Numeric(NumericValue::U32(l)),
|
}
|
||||||
ast::Operator::Mul,
|
|
||||||
Value::Numeric(NumericValue::U32(r)),
|
|
||||||
) => Value::Numeric(NumericValue::U32(l * r)),
|
|
||||||
(
|
|
||||||
Value::Numeric(NumericValue::U32(l)),
|
|
||||||
ast::Operator::Div,
|
|
||||||
Value::Numeric(NumericValue::U32(r)),
|
|
||||||
) => Value::Numeric(NumericValue::U32(l / r)),
|
|
||||||
|
|
||||||
(
|
(Value::Numeric(NumericValue::U64(l)), ast::Operator::Plus, Value::Numeric(NumericValue::U64(r))) => {
|
||||||
Value::Numeric(NumericValue::U64(l)),
|
Value::Numeric(NumericValue::U64(l + r))
|
||||||
ast::Operator::Plus,
|
}
|
||||||
Value::Numeric(NumericValue::U64(r)),
|
(Value::Numeric(NumericValue::U64(l)), ast::Operator::Minus, Value::Numeric(NumericValue::U64(r))) => {
|
||||||
) => Value::Numeric(NumericValue::U64(l + r)),
|
Value::Numeric(NumericValue::U64(l - r))
|
||||||
(
|
}
|
||||||
Value::Numeric(NumericValue::U64(l)),
|
(Value::Numeric(NumericValue::U64(l)), ast::Operator::Mul, Value::Numeric(NumericValue::U64(r))) => {
|
||||||
ast::Operator::Minus,
|
Value::Numeric(NumericValue::U64(l * r))
|
||||||
Value::Numeric(NumericValue::U64(r)),
|
}
|
||||||
) => Value::Numeric(NumericValue::U64(l - r)),
|
(Value::Numeric(NumericValue::U64(l)), ast::Operator::Div, Value::Numeric(NumericValue::U64(r))) => {
|
||||||
(
|
Value::Numeric(NumericValue::U64(l / r))
|
||||||
Value::Numeric(NumericValue::U64(l)),
|
}
|
||||||
ast::Operator::Mul,
|
|
||||||
Value::Numeric(NumericValue::U64(r)),
|
|
||||||
) => Value::Numeric(NumericValue::U64(l * r)),
|
|
||||||
(
|
|
||||||
Value::Numeric(NumericValue::U64(l)),
|
|
||||||
ast::Operator::Div,
|
|
||||||
Value::Numeric(NumericValue::U64(r)),
|
|
||||||
) => Value::Numeric(NumericValue::U64(l / r)),
|
|
||||||
|
|
||||||
//F
|
//F
|
||||||
(
|
(Value::Numeric(NumericValue::F32(l)), ast::Operator::Plus, Value::Numeric(NumericValue::F32(r))) => {
|
||||||
Value::Numeric(NumericValue::F32(l)),
|
Value::Numeric(NumericValue::F32(l + r))
|
||||||
ast::Operator::Plus,
|
}
|
||||||
Value::Numeric(NumericValue::F32(r)),
|
(Value::Numeric(NumericValue::F32(l)), ast::Operator::Minus, Value::Numeric(NumericValue::F32(r))) => {
|
||||||
) => Value::Numeric(NumericValue::F32(l + r)),
|
Value::Numeric(NumericValue::F32(l - r))
|
||||||
(
|
}
|
||||||
Value::Numeric(NumericValue::F32(l)),
|
(Value::Numeric(NumericValue::F32(l)), ast::Operator::Mul, Value::Numeric(NumericValue::F32(r))) => {
|
||||||
ast::Operator::Minus,
|
Value::Numeric(NumericValue::F32(l * r))
|
||||||
Value::Numeric(NumericValue::F32(r)),
|
}
|
||||||
) => Value::Numeric(NumericValue::F32(l - r)),
|
(Value::Numeric(NumericValue::F32(l)), ast::Operator::Div, Value::Numeric(NumericValue::F32(r))) => {
|
||||||
(
|
Value::Numeric(NumericValue::F32(l / r))
|
||||||
Value::Numeric(NumericValue::F32(l)),
|
}
|
||||||
ast::Operator::Mul,
|
|
||||||
Value::Numeric(NumericValue::F32(r)),
|
|
||||||
) => Value::Numeric(NumericValue::F32(l * r)),
|
|
||||||
(
|
|
||||||
Value::Numeric(NumericValue::F32(l)),
|
|
||||||
ast::Operator::Div,
|
|
||||||
Value::Numeric(NumericValue::F32(r)),
|
|
||||||
) => Value::Numeric(NumericValue::F32(l / r)),
|
|
||||||
|
|
||||||
(
|
(Value::Numeric(NumericValue::F64(l)), ast::Operator::Plus, Value::Numeric(NumericValue::F64(r))) => {
|
||||||
Value::Numeric(NumericValue::F64(l)),
|
Value::Numeric(NumericValue::F64(l + r))
|
||||||
ast::Operator::Plus,
|
}
|
||||||
Value::Numeric(NumericValue::F64(r)),
|
(Value::Numeric(NumericValue::F64(l)), ast::Operator::Minus, Value::Numeric(NumericValue::F64(r))) => {
|
||||||
) => Value::Numeric(NumericValue::F64(l + r)),
|
Value::Numeric(NumericValue::F64(l - r))
|
||||||
(
|
}
|
||||||
Value::Numeric(NumericValue::F64(l)),
|
(Value::Numeric(NumericValue::F64(l)), ast::Operator::Mul, Value::Numeric(NumericValue::F64(r))) => {
|
||||||
ast::Operator::Minus,
|
Value::Numeric(NumericValue::F64(l * r))
|
||||||
Value::Numeric(NumericValue::F64(r)),
|
}
|
||||||
) => Value::Numeric(NumericValue::F64(l - r)),
|
(Value::Numeric(NumericValue::F64(l)), ast::Operator::Div, Value::Numeric(NumericValue::F64(r))) => {
|
||||||
(
|
Value::Numeric(NumericValue::F64(l / r))
|
||||||
Value::Numeric(NumericValue::F64(l)),
|
}
|
||||||
ast::Operator::Mul,
|
|
||||||
Value::Numeric(NumericValue::F64(r)),
|
|
||||||
) => Value::Numeric(NumericValue::F64(l * r)),
|
|
||||||
(
|
|
||||||
Value::Numeric(NumericValue::F64(l)),
|
|
||||||
ast::Operator::Div,
|
|
||||||
Value::Numeric(NumericValue::F64(r)),
|
|
||||||
) => Value::Numeric(NumericValue::F64(l / r)),
|
|
||||||
|
|
||||||
//fail
|
//fail
|
||||||
_ => panic!(""),
|
_ => panic!(""),
|
||||||
|
|||||||
73
src/main.rs
73
src/main.rs
@@ -27,34 +27,17 @@ fn main() {
|
|||||||
.help("Sets an output file")
|
.help("Sets an output file")
|
||||||
.takes_value(true),
|
.takes_value(true),
|
||||||
)
|
)
|
||||||
.arg(
|
.arg(Arg::with_name("INPUT").help("Sets the input file").required(true).index(1))
|
||||||
Arg::with_name("INPUT")
|
.arg(Arg::with_name("v").short("v").multiple(true).help("Sets the level of verbosity"))
|
||||||
.help("Sets the input file")
|
|
||||||
.required(true)
|
|
||||||
.index(1),
|
|
||||||
)
|
|
||||||
.arg(
|
|
||||||
Arg::with_name("v")
|
|
||||||
.short("v")
|
|
||||||
.multiple(true)
|
|
||||||
.help("Sets the level of verbosity"),
|
|
||||||
)
|
|
||||||
.get_matches();
|
.get_matches();
|
||||||
let input = matches.value_of("INPUT").unwrap();
|
let input = matches.value_of("INPUT").unwrap();
|
||||||
|
|
||||||
let default_output = input
|
let default_output = input.rsplitn(2, ".").collect::<Vec<&str>>().last().unwrap().clone();
|
||||||
.rsplitn(2, ".")
|
|
||||||
.collect::<Vec<&str>>()
|
|
||||||
.last()
|
|
||||||
.unwrap()
|
|
||||||
.clone();
|
|
||||||
let _output = matches.value_of("OUTPUT").unwrap_or(default_output);
|
let _output = matches.value_of("OUTPUT").unwrap_or(default_output);
|
||||||
|
|
||||||
let contents = fs::read_to_string(input).expect("input file not found");
|
let contents = fs::read_to_string(input).expect("input file not found");
|
||||||
let unknown_id_gen = ast::IdGenerator::new();
|
let unknown_id_gen = ast::IdGenerator::new();
|
||||||
let module_ast = grammar::ModuleParser::new()
|
let module_ast = grammar::ModuleParser::new().parse(&unknown_id_gen, &contents).unwrap(); //TODO: convert to error
|
||||||
.parse(&unknown_id_gen, &contents)
|
|
||||||
.unwrap(); //TODO: convert to error
|
|
||||||
// println!("ast: {:#?}", &module_ast);
|
// println!("ast: {:#?}", &module_ast);
|
||||||
let alias_resolver = type_alias_resolution::TypeAliasResolver {};
|
let alias_resolver = type_alias_resolution::TypeAliasResolver {};
|
||||||
let resolved_ast = alias_resolver.with_module(&module_ast);
|
let resolved_ast = alias_resolver.with_module(&module_ast);
|
||||||
@@ -85,47 +68,25 @@ fn main() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn grammar() {
|
fn grammar() {
|
||||||
let id_gen = ast::IdGenerator::new();
|
let id_gen = ast::IdGenerator::new();
|
||||||
assert!(grammar::LiteralIntParser::new()
|
assert!(grammar::LiteralIntParser::new().parse(&id_gen, "22").is_ok());
|
||||||
.parse(&id_gen, "22")
|
assert!(grammar::IdentifierParser::new().parse(&id_gen, "foo").is_ok());
|
||||||
.is_ok());
|
assert!(grammar::LiteralIntParser::new().parse(&id_gen, "2a").is_err());
|
||||||
assert!(grammar::IdentifierParser::new()
|
|
||||||
.parse(&id_gen, "foo")
|
|
||||||
.is_ok());
|
|
||||||
assert!(grammar::LiteralIntParser::new()
|
|
||||||
.parse(&id_gen, "2a")
|
|
||||||
.is_err());
|
|
||||||
|
|
||||||
assert!(grammar::TermParser::new().parse(&id_gen, "22").is_ok());
|
assert!(grammar::TermParser::new().parse(&id_gen, "22").is_ok());
|
||||||
assert!(grammar::TermParser::new().parse(&id_gen, "foo").is_ok());
|
assert!(grammar::TermParser::new().parse(&id_gen, "foo").is_ok());
|
||||||
|
|
||||||
assert!(grammar::ExpressionParser::new()
|
assert!(grammar::ExpressionParser::new().parse(&id_gen, "22 * foo").is_ok());
|
||||||
.parse(&id_gen, "22 * foo")
|
assert!(grammar::ExpressionParser::new().parse(&id_gen, "22 * 33").is_ok());
|
||||||
.is_ok());
|
assert!(grammar::ExpressionParser::new().parse(&id_gen, "(22 * 33) + 24").is_ok());
|
||||||
assert!(grammar::ExpressionParser::new()
|
|
||||||
.parse(&id_gen, "22 * 33")
|
|
||||||
.is_ok());
|
|
||||||
assert!(grammar::ExpressionParser::new()
|
|
||||||
.parse(&id_gen, "(22 * 33) + 24")
|
|
||||||
.is_ok());
|
|
||||||
|
|
||||||
assert!(grammar::BlockParser::new()
|
assert!(grammar::BlockParser::new().parse(&id_gen, "{ (22 * 33) + 24 }").is_ok());
|
||||||
.parse(&id_gen, "{ (22 * 33) + 24 }")
|
assert!(grammar::BlockParser::new().parse(&id_gen, "{ (22 * 33) + 24; 25 }").is_ok());
|
||||||
.is_ok());
|
|
||||||
assert!(grammar::BlockParser::new()
|
|
||||||
.parse(&id_gen, "{ (22 * 33) + 24; 25 }")
|
|
||||||
.is_ok());
|
|
||||||
// assert!(grammar::BlockParser::new().parse("{ (22 * 33) + 24\n 24 }").is_ok());
|
// assert!(grammar::BlockParser::new().parse("{ (22 * 33) + 24\n 24 }").is_ok());
|
||||||
assert!(grammar::BlockParser::new().parse(&id_gen, "{ }").is_ok());
|
assert!(grammar::BlockParser::new().parse(&id_gen, "{ }").is_ok());
|
||||||
|
|
||||||
assert!(grammar::VariableDeclarationParser::new()
|
assert!(grammar::VariableDeclarationParser::new().parse(&id_gen, "foo: i32").is_ok());
|
||||||
.parse(&id_gen, "foo: i32")
|
assert!(grammar::VariableDeclarationParser::new().parse(&id_gen, "foo").is_err());
|
||||||
.is_ok());
|
assert!(grammar::VariableDeclarationParser::new().parse(&id_gen, "1234").is_err());
|
||||||
assert!(grammar::VariableDeclarationParser::new()
|
|
||||||
.parse(&id_gen, "foo")
|
|
||||||
.is_err());
|
|
||||||
assert!(grammar::VariableDeclarationParser::new()
|
|
||||||
.parse(&id_gen, "1234")
|
|
||||||
.is_err());
|
|
||||||
|
|
||||||
assert!(grammar::FunctionParser::new()
|
assert!(grammar::FunctionParser::new()
|
||||||
.parse(&id_gen, "fn add(a: i32, b: i32): i32 { a + b }")
|
.parse(&id_gen, "fn add(a: i32, b: i32): i32 { a + b }")
|
||||||
@@ -140,9 +101,7 @@ fn grammar() {
|
|||||||
.parse(&id_gen, "fn add(a: i32, b: i32): i32")
|
.parse(&id_gen, "fn add(a: i32, b: i32): i32")
|
||||||
.is_err());
|
.is_err());
|
||||||
|
|
||||||
assert!(grammar::FunctionCallParser::new()
|
assert!(grammar::FunctionCallParser::new().parse(&id_gen, "foo(1, 2)").is_ok());
|
||||||
.parse(&id_gen, "foo(1, 2)")
|
|
||||||
.is_ok());
|
|
||||||
|
|
||||||
assert!(grammar::ModuleParser::new()
|
assert!(grammar::ModuleParser::new()
|
||||||
.parse(&id_gen, "fn add(a: i32, b: i32): i32 { a + b }")
|
.parse(&id_gen, "fn add(a: i32, b: i32): i32 { a + b }")
|
||||||
|
|||||||
@@ -33,11 +33,7 @@ fn process_type(ctx: &Context, type_: &ast::TypeUsage) -> ast::TypeUsage {
|
|||||||
}
|
}
|
||||||
ast::TypeUsage::Function(function) => {
|
ast::TypeUsage::Function(function) => {
|
||||||
return ast::TypeUsage::Function(ast::FunctionTypeUsage {
|
return ast::TypeUsage::Function(ast::FunctionTypeUsage {
|
||||||
arguments: function
|
arguments: function.arguments.iter().map(|a| process_type(ctx, &a.clone())).collect(),
|
||||||
.arguments
|
|
||||||
.iter()
|
|
||||||
.map(|a| process_type(ctx, &a.clone()))
|
|
||||||
.collect(),
|
|
||||||
return_type: Box::new(process_type(ctx, &function.return_type.clone())),
|
return_type: Box::new(process_type(ctx, &function.return_type.clone())),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -51,9 +47,7 @@ pub struct TypeAliasResolver {}
|
|||||||
|
|
||||||
impl TypeAliasResolver {
|
impl TypeAliasResolver {
|
||||||
pub fn with_module(self: &Self, module: &ast::Module) -> ast::Module {
|
pub fn with_module(self: &Self, module: &ast::Module) -> ast::Module {
|
||||||
let mut ctx = Context {
|
let mut ctx = Context { type_aliases: vec![] };
|
||||||
type_aliases: vec![],
|
|
||||||
};
|
|
||||||
for item in module.items.iter() {
|
for item in module.items.iter() {
|
||||||
match item {
|
match item {
|
||||||
ast::ModuleItem::TypeDeclaration(ast::TypeDeclaration::Alias(alias)) => {
|
ast::ModuleItem::TypeDeclaration(ast::TypeDeclaration::Alias(alias)) => {
|
||||||
@@ -68,17 +62,11 @@ impl TypeAliasResolver {
|
|||||||
.items
|
.items
|
||||||
.iter()
|
.iter()
|
||||||
.map(|item| match item {
|
.map(|item| match item {
|
||||||
ast::ModuleItem::Function(function) => {
|
ast::ModuleItem::Function(function) => ast::ModuleItem::Function(self.with_function(&ctx, function)),
|
||||||
ast::ModuleItem::Function(self.with_function(&ctx, function))
|
|
||||||
}
|
|
||||||
ast::ModuleItem::TypeDeclaration(type_declaration) => {
|
ast::ModuleItem::TypeDeclaration(type_declaration) => {
|
||||||
ast::ModuleItem::TypeDeclaration(
|
ast::ModuleItem::TypeDeclaration(self.with_type_declaration(&ctx, type_declaration))
|
||||||
self.with_type_declaration(&ctx, type_declaration),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
ast::ModuleItem::Impl(impl_) => {
|
|
||||||
ast::ModuleItem::Impl(self.with_impl(&ctx, impl_))
|
|
||||||
}
|
}
|
||||||
|
ast::ModuleItem::Impl(impl_) => ast::ModuleItem::Impl(self.with_impl(&ctx, impl_)),
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
};
|
};
|
||||||
@@ -86,10 +74,15 @@ impl TypeAliasResolver {
|
|||||||
|
|
||||||
fn with_function(self: &Self, ctx: &Context, function: &ast::Function) -> ast::Function {
|
fn with_function(self: &Self, ctx: &Context, function: &ast::Function) -> ast::Function {
|
||||||
return ast::Function {
|
return ast::Function {
|
||||||
declaration: ast::FunctionDeclaration {
|
declaration: self.with_function_declaration(ctx, &function.declaration),
|
||||||
name: function.declaration.name.clone(),
|
block: self.with_block(ctx, &function.block),
|
||||||
arguments: function
|
};
|
||||||
.declaration
|
}
|
||||||
|
|
||||||
|
fn with_function_declaration(self: &Self, ctx: &Context, declaration: &ast::FunctionDeclaration) -> ast::FunctionDeclaration {
|
||||||
|
return ast::FunctionDeclaration {
|
||||||
|
name: declaration.name.clone(),
|
||||||
|
arguments: declaration
|
||||||
.arguments
|
.arguments
|
||||||
.iter()
|
.iter()
|
||||||
.map(|arg| ast::VariableDeclaration {
|
.map(|arg| ast::VariableDeclaration {
|
||||||
@@ -97,17 +90,11 @@ impl TypeAliasResolver {
|
|||||||
type_: process_type(ctx, &arg.type_),
|
type_: process_type(ctx, &arg.type_),
|
||||||
})
|
})
|
||||||
.collect(),
|
.collect(),
|
||||||
return_type: process_type(ctx, &function.declaration.return_type),
|
return_type: process_type(ctx, &declaration.return_type),
|
||||||
},
|
|
||||||
block: self.with_block(ctx, &function.block),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_type_declaration(
|
fn with_type_declaration(self: &Self, ctx: &Context, type_declaration: &ast::TypeDeclaration) -> ast::TypeDeclaration {
|
||||||
self: &Self,
|
|
||||||
ctx: &Context,
|
|
||||||
type_declaration: &ast::TypeDeclaration,
|
|
||||||
) -> ast::TypeDeclaration {
|
|
||||||
match type_declaration {
|
match type_declaration {
|
||||||
ast::TypeDeclaration::Struct(struct_) => {
|
ast::TypeDeclaration::Struct(struct_) => {
|
||||||
return ast::TypeDeclaration::Struct(self.with_struct_declaration(ctx, struct_));
|
return ast::TypeDeclaration::Struct(self.with_struct_declaration(ctx, struct_));
|
||||||
@@ -118,14 +105,13 @@ impl TypeAliasResolver {
|
|||||||
ast::TypeDeclaration::Alias(alias) => {
|
ast::TypeDeclaration::Alias(alias) => {
|
||||||
return ast::TypeDeclaration::Alias(alias.clone());
|
return ast::TypeDeclaration::Alias(alias.clone());
|
||||||
}
|
}
|
||||||
|
ast::TypeDeclaration::Trait(trait_) => {
|
||||||
|
return ast::TypeDeclaration::Trait(self.with_trait(ctx, trait_));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_struct_declaration(
|
fn with_struct_declaration(self: &Self, ctx: &Context, struct_: &ast::StructTypeDeclaration) -> ast::StructTypeDeclaration {
|
||||||
self: &Self,
|
|
||||||
ctx: &Context,
|
|
||||||
struct_: &ast::StructTypeDeclaration,
|
|
||||||
) -> ast::StructTypeDeclaration {
|
|
||||||
return ast::StructTypeDeclaration {
|
return ast::StructTypeDeclaration {
|
||||||
name: struct_.name.clone(),
|
name: struct_.name.clone(),
|
||||||
fields: struct_
|
fields: struct_
|
||||||
@@ -139,6 +125,34 @@ impl TypeAliasResolver {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn with_trait(self: &Self, ctx: &Context, trait_: &ast::TraitTypeDeclaration) -> ast::TraitTypeDeclaration {
|
||||||
|
let mut trait_ctx = ctx.clone();
|
||||||
|
trait_ctx.type_aliases.push(ast::AliasTypeDeclaration {
|
||||||
|
name: ast::Identifier {
|
||||||
|
name: ast::Spanned {
|
||||||
|
span: ast::Span { left: 0, right: 0 }, //todo: figure out a sane value for these
|
||||||
|
value: "Self".to_string(),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
replaces: ast::TypeUsage::Named(ast::NamedTypeUsage { name: trait_.name.clone() }),
|
||||||
|
});
|
||||||
|
return ast::TraitTypeDeclaration {
|
||||||
|
name: trait_.name.clone(),
|
||||||
|
functions: trait_
|
||||||
|
.functions
|
||||||
|
.iter()
|
||||||
|
.map(|f| match f {
|
||||||
|
ast::TraitItem::Function(function) => {
|
||||||
|
ast::TraitItem::Function(self.with_function(&trait_ctx, function))
|
||||||
|
},
|
||||||
|
ast::TraitItem::FunctionDeclaration(function_declaration) => {
|
||||||
|
ast::TraitItem::FunctionDeclaration(self.with_function_declaration(&trait_ctx, function_declaration))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.collect(),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
fn with_impl(self: &Self, ctx: &Context, impl_: &ast::Impl) -> ast::Impl {
|
fn with_impl(self: &Self, ctx: &Context, impl_: &ast::Impl) -> ast::Impl {
|
||||||
let mut impl_ctx = ctx.clone();
|
let mut impl_ctx = ctx.clone();
|
||||||
impl_ctx.type_aliases.push(ast::AliasTypeDeclaration {
|
impl_ctx.type_aliases.push(ast::AliasTypeDeclaration {
|
||||||
@@ -153,22 +167,15 @@ impl TypeAliasResolver {
|
|||||||
}),
|
}),
|
||||||
});
|
});
|
||||||
return ast::Impl {
|
return ast::Impl {
|
||||||
|
trait_: impl_.trait_.clone(),
|
||||||
struct_name: impl_.struct_name.clone(),
|
struct_name: impl_.struct_name.clone(),
|
||||||
functions: impl_
|
functions: impl_.functions.iter().map(|f| self.with_function(&impl_ctx, f)).collect(),
|
||||||
.functions
|
|
||||||
.iter()
|
|
||||||
.map(|f| self.with_function(&impl_ctx, f))
|
|
||||||
.collect(),
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_block(self: &Self, ctx: &Context, block: &ast::Block) -> ast::Block {
|
fn with_block(self: &Self, ctx: &Context, block: &ast::Block) -> ast::Block {
|
||||||
return ast::Block {
|
return ast::Block {
|
||||||
statements: block
|
statements: block.statements.iter().map(|s| self.with_statement(ctx, s)).collect(),
|
||||||
.statements
|
|
||||||
.iter()
|
|
||||||
.map(|s| self.with_statement(ctx, s))
|
|
||||||
.collect(),
|
|
||||||
type_: process_type(ctx, &block.type_),
|
type_: process_type(ctx, &block.type_),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@@ -182,9 +189,7 @@ impl TypeAliasResolver {
|
|||||||
return ast::Statement::Let(self.with_let_statement(ctx, let_statement));
|
return ast::Statement::Let(self.with_let_statement(ctx, let_statement));
|
||||||
}
|
}
|
||||||
ast::Statement::Assignment(assignment_statement) => {
|
ast::Statement::Assignment(assignment_statement) => {
|
||||||
return ast::Statement::Assignment(
|
return ast::Statement::Assignment(self.with_assignment_statement(ctx, assignment_statement));
|
||||||
self.with_assignment_statement(ctx, assignment_statement),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
ast::Statement::Expression(expression) => {
|
ast::Statement::Expression(expression) => {
|
||||||
return ast::Statement::Expression(self.with_expression(ctx, expression));
|
return ast::Statement::Expression(self.with_expression(ctx, expression));
|
||||||
@@ -192,21 +197,13 @@ impl TypeAliasResolver {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_return_statement(
|
fn with_return_statement(self: &Self, ctx: &Context, statement: &ast::ReturnStatement) -> ast::ReturnStatement {
|
||||||
self: &Self,
|
|
||||||
ctx: &Context,
|
|
||||||
statement: &ast::ReturnStatement,
|
|
||||||
) -> ast::ReturnStatement {
|
|
||||||
return ast::ReturnStatement {
|
return ast::ReturnStatement {
|
||||||
source: self.with_expression(ctx, &statement.source),
|
source: self.with_expression(ctx, &statement.source),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_let_statement(
|
fn with_let_statement(self: &Self, ctx: &Context, statement: &ast::LetStatement) -> ast::LetStatement {
|
||||||
self: &Self,
|
|
||||||
ctx: &Context,
|
|
||||||
statement: &ast::LetStatement,
|
|
||||||
) -> ast::LetStatement {
|
|
||||||
return ast::LetStatement {
|
return ast::LetStatement {
|
||||||
variable_name: statement.variable_name.clone(),
|
variable_name: statement.variable_name.clone(),
|
||||||
expression: self.with_expression(ctx, &statement.expression),
|
expression: self.with_expression(ctx, &statement.expression),
|
||||||
@@ -214,56 +211,38 @@ impl TypeAliasResolver {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_assignment_statement(
|
fn with_assignment_statement(self: &Self, ctx: &Context, statement: &ast::AssignmentStatement) -> ast::AssignmentStatement {
|
||||||
self: &Self,
|
|
||||||
ctx: &Context,
|
|
||||||
statement: &ast::AssignmentStatement,
|
|
||||||
) -> ast::AssignmentStatement {
|
|
||||||
return ast::AssignmentStatement {
|
return ast::AssignmentStatement {
|
||||||
source: match &statement.source {
|
source: match &statement.source {
|
||||||
ast::AssignmentTarget::Variable(variable) => {
|
ast::AssignmentTarget::Variable(variable) => ast::AssignmentTarget::Variable(ast::VariableUsage {
|
||||||
ast::AssignmentTarget::Variable(ast::VariableUsage {
|
|
||||||
name: variable.name.clone(),
|
name: variable.name.clone(),
|
||||||
type_: process_type(ctx, &variable.type_),
|
type_: process_type(ctx, &variable.type_),
|
||||||
})
|
}),
|
||||||
}
|
ast::AssignmentTarget::StructAttr(struct_attr) => ast::AssignmentTarget::StructAttr(ast::StructGetter {
|
||||||
ast::AssignmentTarget::StructAttr(struct_attr) => {
|
|
||||||
ast::AssignmentTarget::StructAttr(ast::StructGetter {
|
|
||||||
source: self.with_expression(ctx, &struct_attr.source),
|
source: self.with_expression(ctx, &struct_attr.source),
|
||||||
attribute: struct_attr.attribute.clone(),
|
attribute: struct_attr.attribute.clone(),
|
||||||
type_: process_type(ctx, &struct_attr.type_),
|
type_: process_type(ctx, &struct_attr.type_),
|
||||||
})
|
}),
|
||||||
}
|
|
||||||
},
|
},
|
||||||
expression: self.with_expression(ctx, &statement.expression),
|
expression: self.with_expression(ctx, &statement.expression),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_expression(
|
fn with_expression(self: &Self, ctx: &Context, expression: &ast::Expression) -> ast::Expression {
|
||||||
self: &Self,
|
|
||||||
ctx: &Context,
|
|
||||||
expression: &ast::Expression,
|
|
||||||
) -> ast::Expression {
|
|
||||||
return ast::Expression {
|
return ast::Expression {
|
||||||
subexpression: Box::new(match &*expression.subexpression {
|
subexpression: Box::new(match &*expression.subexpression {
|
||||||
ast::Subexpression::LiteralInt(literal_int) => {
|
ast::Subexpression::LiteralInt(literal_int) => ast::Subexpression::LiteralInt(ast::LiteralInt {
|
||||||
ast::Subexpression::LiteralInt(ast::LiteralInt {
|
|
||||||
value: literal_int.value.clone(),
|
value: literal_int.value.clone(),
|
||||||
type_: process_type(ctx, &literal_int.type_),
|
type_: process_type(ctx, &literal_int.type_),
|
||||||
})
|
}),
|
||||||
}
|
ast::Subexpression::LiteralFloat(literal_float) => ast::Subexpression::LiteralFloat(ast::LiteralFloat {
|
||||||
ast::Subexpression::LiteralFloat(literal_float) => {
|
|
||||||
ast::Subexpression::LiteralFloat(ast::LiteralFloat {
|
|
||||||
value: literal_float.value.clone(),
|
value: literal_float.value.clone(),
|
||||||
type_: process_type(ctx, &literal_float.type_),
|
type_: process_type(ctx, &literal_float.type_),
|
||||||
})
|
}),
|
||||||
}
|
ast::Subexpression::LiteralBool(literal_bool) => ast::Subexpression::LiteralBool(ast::LiteralBool {
|
||||||
ast::Subexpression::LiteralBool(literal_bool) => {
|
|
||||||
ast::Subexpression::LiteralBool(ast::LiteralBool {
|
|
||||||
value: literal_bool.value.clone(),
|
value: literal_bool.value.clone(),
|
||||||
type_: process_type(ctx, &literal_bool.type_),
|
type_: process_type(ctx, &literal_bool.type_),
|
||||||
})
|
}),
|
||||||
}
|
|
||||||
ast::Subexpression::LiteralStruct(literal_struct) => {
|
ast::Subexpression::LiteralStruct(literal_struct) => {
|
||||||
let result = resolve_type(
|
let result = resolve_type(
|
||||||
ctx,
|
ctx,
|
||||||
@@ -285,25 +264,16 @@ impl TypeAliasResolver {
|
|||||||
type_: process_type(ctx, &literal_struct.type_),
|
type_: process_type(ctx, &literal_struct.type_),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
ast::Subexpression::FunctionCall(function_call) => {
|
ast::Subexpression::FunctionCall(function_call) => ast::Subexpression::FunctionCall(ast::FunctionCall {
|
||||||
ast::Subexpression::FunctionCall(ast::FunctionCall {
|
|
||||||
source: self.with_expression(ctx, &function_call.source),
|
source: self.with_expression(ctx, &function_call.source),
|
||||||
arguments: function_call
|
arguments: function_call.arguments.iter().map(|arg| self.with_expression(ctx, arg)).collect(),
|
||||||
.arguments
|
|
||||||
.iter()
|
|
||||||
.map(|arg| self.with_expression(ctx, arg))
|
|
||||||
.collect(),
|
|
||||||
type_: process_type(ctx, &function_call.type_),
|
type_: process_type(ctx, &function_call.type_),
|
||||||
})
|
}),
|
||||||
}
|
ast::Subexpression::VariableUsage(variable_usage) => ast::Subexpression::VariableUsage(ast::VariableUsage {
|
||||||
ast::Subexpression::VariableUsage(variable_usage) => {
|
|
||||||
ast::Subexpression::VariableUsage(ast::VariableUsage {
|
|
||||||
name: variable_usage.name.clone(),
|
name: variable_usage.name.clone(),
|
||||||
type_: process_type(ctx, &variable_usage.type_),
|
type_: process_type(ctx, &variable_usage.type_),
|
||||||
})
|
}),
|
||||||
}
|
ast::Subexpression::If(if_expression) => ast::Subexpression::If(ast::IfExpression {
|
||||||
ast::Subexpression::If(if_expression) => {
|
|
||||||
ast::Subexpression::If(ast::IfExpression {
|
|
||||||
condition: self.with_expression(ctx, &if_expression.condition),
|
condition: self.with_expression(ctx, &if_expression.condition),
|
||||||
block: self.with_block(ctx, &if_expression.block),
|
block: self.with_block(ctx, &if_expression.block),
|
||||||
else_: match &if_expression.else_ {
|
else_: match &if_expression.else_ {
|
||||||
@@ -311,18 +281,13 @@ impl TypeAliasResolver {
|
|||||||
None => None,
|
None => None,
|
||||||
},
|
},
|
||||||
type_: process_type(ctx, &if_expression.type_),
|
type_: process_type(ctx, &if_expression.type_),
|
||||||
})
|
}),
|
||||||
}
|
ast::Subexpression::StructGetter(struct_getter) => ast::Subexpression::StructGetter(ast::StructGetter {
|
||||||
ast::Subexpression::StructGetter(struct_getter) => {
|
|
||||||
ast::Subexpression::StructGetter(ast::StructGetter {
|
|
||||||
source: self.with_expression(ctx, &struct_getter.source),
|
source: self.with_expression(ctx, &struct_getter.source),
|
||||||
attribute: struct_getter.attribute.clone(),
|
attribute: struct_getter.attribute.clone(),
|
||||||
type_: process_type(ctx, &struct_getter.type_),
|
type_: process_type(ctx, &struct_getter.type_),
|
||||||
})
|
}),
|
||||||
}
|
ast::Subexpression::Block(block) => ast::Subexpression::Block(self.with_block(ctx, &block)),
|
||||||
ast::Subexpression::Block(block) => {
|
|
||||||
ast::Subexpression::Block(self.with_block(ctx, &block))
|
|
||||||
}
|
|
||||||
ast::Subexpression::Op(op) => ast::Subexpression::Op(ast::Operation {
|
ast::Subexpression::Op(op) => ast::Subexpression::Op(ast::Operation {
|
||||||
left: self.with_expression(ctx, &op.left),
|
left: self.with_expression(ctx, &op.left),
|
||||||
op: op.op.clone(),
|
op: op.op.clone(),
|
||||||
|
|||||||
1047
src/type_checking.rs
1047
src/type_checking.rs
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user