finished basic traits

This commit is contained in:
Andrew Segavac
2021-09-25 11:45:31 -06:00
parent 223b36080b
commit 44df5f1980
12 changed files with 1116 additions and 1208 deletions

1
.rustfmt.toml Normal file
View File

@@ -0,0 +1 @@
max_width=140 # Not ideal

View File

@@ -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

View File

@@ -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

View File

@@ -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();
// } }
// } }

View File

@@ -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>,
} }

View File

@@ -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);

View File

@@ -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

View File

@@ -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 = {

View File

@@ -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!(""),

View File

@@ -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 }")

View File

@@ -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(),

File diff suppressed because it is too large Load Diff