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
RUN apt update && apt-get install -y llvm clang
RUN rustup component add rustfmt
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] Use
- [ ] Traits
- [x] Basic
- [ ] Default Functions
- [ ] Generics
- [ ] Basic
- [ ] Higher kinded types

View File

@@ -81,19 +81,19 @@ fn main(): i64 {
}
}
// type TestTrait trait {
// fn class_method(id: i64): Self;
// fn instance_method(self: Self): i64;
// fn default_impl(self: Self): i64 {
// return self.instance_method();
// }
// }
//
// impl TestTrait for User {
// fn class_method(id: i64): Self {
// return User{id: id,};
// }
// fn instance_method(self: Self): i64 {
// return self.get_id();
// }
// }
type TestTrait trait {
fn class_method(id: i64): Self;
fn instance_method(self: Self): i64;
fn default_impl(self: Self): i64 {
return self.instance_method();
}
}
impl TestTrait for User {
fn class_method(id: i64): Self {
return User{id: id,};
}
fn instance_method(self: Self): i64 {
return self.get_id();
}
}

View File

@@ -6,9 +6,7 @@ pub struct IdGenerator {
impl IdGenerator {
pub fn new() -> Self {
IdGenerator {
counter: RefCell::new(0),
}
IdGenerator { counter: RefCell::new(0) }
}
pub fn next(&self) -> String {
@@ -76,15 +74,11 @@ pub enum TypeUsage {
impl TypeUsage {
pub fn new_unknown(id_gen: &IdGenerator) -> TypeUsage {
return TypeUsage::Unknown(UnknownTypeUsage {
name: id_gen.next(),
});
return TypeUsage::Unknown(UnknownTypeUsage { name: id_gen.next() });
}
pub fn new_named(identifier: Identifier) -> TypeUsage {
return TypeUsage::Named(NamedTypeUsage {
name: identifier.clone(),
});
return TypeUsage::Named(NamedTypeUsage { name: identifier.clone() });
}
pub fn new_builtin(name: String) -> TypeUsage {
@@ -100,9 +94,7 @@ impl TypeUsage {
pub fn new_function(arg_count: usize, id_gen: &IdGenerator) -> TypeUsage {
return TypeUsage::Function(FunctionTypeUsage {
arguments: (0..arg_count)
.map(|_| TypeUsage::new_unknown(&id_gen))
.collect(),
arguments: (0..arg_count).map(|_| TypeUsage::new_unknown(&id_gen)).collect(),
return_type: Box::new(TypeUsage::new_unknown(&id_gen)),
});
}
@@ -252,6 +244,25 @@ pub struct FunctionDeclaration {
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)]
pub struct Function {
pub declaration: FunctionDeclaration,
@@ -275,6 +286,18 @@ pub struct StructTypeDeclaration {
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)]
pub struct AliasTypeDeclaration {
pub name: Identifier,
@@ -286,10 +309,12 @@ pub enum TypeDeclaration {
Struct(StructTypeDeclaration),
Primitive(PrimitiveTypeDeclaration),
Alias(AliasTypeDeclaration),
Trait(TraitTypeDeclaration),
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Impl {
pub trait_: Option<Identifier>,
pub struct_name: Identifier,
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> {
self.context.i64_type().const_int(
unsafe { mem::transmute::<i64, u64>(literal_int.value) },
true,
)
self.context
.i64_type()
.const_int(unsafe { mem::transmute::<i64, u64>(literal_int.value) }, true)
}
pub fn gen_op_expression(
&mut self,
scope: &Scope<'ctx>,
operation: &ast::Operation,
) -> IntValue<'ctx> {
pub fn gen_op_expression(&mut self, scope: &Scope<'ctx>, operation: &ast::Operation) -> IntValue<'ctx> {
let lhs_result = self.gen_expression(scope, &operation.left);
let rhs_result = self.gen_expression(scope, &operation.right);
self.gen_op_int(&lhs_result, &rhs_result, &operation.op)
}
pub fn gen_op_int(
&mut self,
lhs: &IntValue<'ctx>,
rhs: &IntValue<'ctx>,
op: &ast::Operator,
) -> IntValue<'ctx> {
pub fn gen_op_int(&mut self, lhs: &IntValue<'ctx>, rhs: &IntValue<'ctx>, op: &ast::Operator) -> IntValue<'ctx> {
match *op {
ast::Operator::Plus => self.builder.build_int_add(*lhs, *rhs, "add"),
ast::Operator::Minus => self.builder.build_int_sub(*lhs, *rhs, "sub"),
@@ -58,35 +48,23 @@ impl<'ctx> ModuleCodeGen<'ctx> {
}
}
pub fn gen_expression(
&mut self,
scope: &Scope<'ctx>,
expression: &Box<ast::Expression>,
) -> IntValue<'ctx> {
pub fn gen_expression(&mut self, scope: &Scope<'ctx>, expression: &Box<ast::Expression>) -> IntValue<'ctx> {
match &**expression {
ast::Expression::LiteralInt(literal_int) => self.gen_literal_int(&literal_int),
ast::Expression::Identifier(identifier) => match scope[&identifier.name] {
BasicValueEnum::IntValue(value) => value,
_ => panic!("function returned type other than int, no types yet"),
},
ast::Expression::FunctionCall(function_call) => {
self.gen_function_call(scope, &function_call)
}
ast::Expression::FunctionCall(function_call) => self.gen_function_call(scope, &function_call),
ast::Expression::Op(operation) => self.gen_op_expression(scope, &operation),
}
}
pub fn gen_function_call(
&mut self,
scope: &Scope<'ctx>,
function_call: &ast::FunctionCall,
) -> IntValue<'ctx> {
pub fn gen_function_call(&mut self, scope: &Scope<'ctx>, function_call: &ast::FunctionCall) -> IntValue<'ctx> {
let fn_value = self.module.get_function(&function_call.name.name).unwrap();
let mut arguments = Vec::new();
for expression in (&function_call.arguments).into_iter() {
arguments.push(BasicValueEnum::IntValue(
self.gen_expression(scope, &expression),
));
arguments.push(BasicValueEnum::IntValue(self.gen_expression(scope, &expression)));
}
let result = self
@@ -123,10 +101,7 @@ impl<'ctx> ModuleCodeGen<'ctx> {
let mut scope = self.scope.clone();
for (i, param) in (&function.arguments).into_iter().enumerate() {
scope.insert(
param.name.name.to_string(),
fn_value.get_nth_param(i.try_into().unwrap()).unwrap(),
);
scope.insert(param.name.name.to_string(), fn_value.get_nth_param(i.try_into().unwrap()).unwrap());
}
let body = &function.block;
let return_value = self.gen_expression(&scope, &body.expression);

View File

@@ -18,6 +18,10 @@ pub enum TypingError {
},
#[error("unknown field name")]
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")]
AttributeOfNonstruct { identifier: ast::Identifier },
#[error("name is not a struct, cannot instaniate")]
@@ -27,6 +31,15 @@ pub enum TypingError {
struct_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")]
FunctionCallNotAFunction {
// TODO: add position

View File

@@ -25,7 +25,9 @@ match {
"if",
"else",
"=",
"for",
"type",
"trait",
"struct",
"impl",
",",
@@ -208,13 +210,24 @@ pub AliasTypeDeclaration: ast::AliasTypeDeclaration = {
"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 = {
<s:StructTypeDeclaration> => ast::TypeDeclaration::Struct(s),
<a:AliasTypeDeclaration> => ast::TypeDeclaration::Alias(a),
<t:TraitTypeDeclaration> => ast::TypeDeclaration::Trait(t),
};
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 = {

View File

@@ -58,8 +58,7 @@ struct Context {
impl Context {
fn set_variable(&mut self, name: String, value: &Value) {
self.environment
.insert(name.to_string(), NamedEntity::Variable(value.clone()));
self.environment.insert(name.to_string(), NamedEntity::Variable(value.clone()));
}
fn new_env(&self) -> Context {
@@ -94,8 +93,7 @@ impl Context {
);
}
ast::ModuleItem::Impl(impl_) => {
ctx.impls
.insert(impl_.struct_name.name.value.to_string(), impl_.clone());
ctx.impls.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();
result.insert(
"i8".to_string(),
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(
ast::PrimitiveTypeDeclaration {
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
name: "i8".to_string(),
},
)),
})),
);
result.insert(
"i16".to_string(),
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(
ast::PrimitiveTypeDeclaration {
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
name: "i16".to_string(),
},
)),
})),
);
result.insert(
"i32".to_string(),
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(
ast::PrimitiveTypeDeclaration {
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
name: "i32".to_string(),
},
)),
})),
);
result.insert(
"i64".to_string(),
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(
ast::PrimitiveTypeDeclaration {
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
name: "i64".to_string(),
},
)),
})),
);
result.insert(
"isize".to_string(),
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(
ast::PrimitiveTypeDeclaration {
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
name: "isize".to_string(),
},
)),
})),
);
result.insert(
"u8".to_string(),
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(
ast::PrimitiveTypeDeclaration {
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
name: "u8".to_string(),
},
)),
})),
);
result.insert(
"u16".to_string(),
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(
ast::PrimitiveTypeDeclaration {
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
name: "u16".to_string(),
},
)),
})),
);
result.insert(
"u32".to_string(),
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(
ast::PrimitiveTypeDeclaration {
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
name: "u32".to_string(),
},
)),
})),
);
result.insert(
"u64".to_string(),
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(
ast::PrimitiveTypeDeclaration {
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
name: "u64".to_string(),
},
)),
})),
);
result.insert(
"usize".to_string(),
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(
ast::PrimitiveTypeDeclaration {
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
name: "usize".to_string(),
},
)),
})),
);
result.insert(
"f32".to_string(),
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(
ast::PrimitiveTypeDeclaration {
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
name: "f32".to_string(),
},
)),
})),
);
result.insert(
"f64".to_string(),
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(
ast::PrimitiveTypeDeclaration {
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
name: "f64".to_string(),
},
)),
})),
);
result.insert(
"bool".to_string(),
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(
ast::PrimitiveTypeDeclaration {
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
name: "bool".to_string(),
},
)),
})),
);
result.insert(
"!".to_string(),
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(
ast::PrimitiveTypeDeclaration {
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
name: "!".to_string(),
},
)),
})),
);
result.insert(
"unit".to_string(),
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(
ast::PrimitiveTypeDeclaration {
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Primitive(ast::PrimitiveTypeDeclaration {
name: "!".to_string(),
},
)),
})),
);
return result;
@@ -277,11 +245,7 @@ impl TreeWalkInterpreter {
return last;
}
fn with_statement(
self: &Self,
ctx: &mut Context,
statement: &ast::Statement,
) -> ExpressionResult {
fn with_statement(self: &Self, ctx: &mut Context, statement: &ast::Statement) -> ExpressionResult {
match statement {
ast::Statement::Return(return_statement) => {
let result = match self.with_expression(ctx, &return_statement.source) {
@@ -311,11 +275,7 @@ impl TreeWalkInterpreter {
}
}
fn with_assignment_statement(
self: &Self,
ctx: &mut Context,
statement: &ast::AssignmentStatement,
) -> ExpressionResult {
fn with_assignment_statement(self: &Self, ctx: &mut Context, statement: &ast::AssignmentStatement) -> ExpressionResult {
let result = match self.with_expression(ctx, &statement.expression) {
ExpressionResult::Value(r) => r,
ExpressionResult::Return(r) => {
@@ -336,9 +296,7 @@ impl TreeWalkInterpreter {
match &mut source {
Value::Struct(s) => {
let mut struct_ = s.lock().unwrap();
struct_
.fields
.insert(struct_attr.attribute.name.value.clone(), result);
struct_.fields.insert(struct_attr.attribute.name.value.clone(), result);
}
_ => panic!("set attr on nonstruct, should never happen due to type system"),
}
@@ -347,11 +305,7 @@ impl TreeWalkInterpreter {
return ExpressionResult::Value(Value::Unit);
}
fn with_expression(
self: &Self,
ctx: &mut Context,
expression: &ast::Expression,
) -> ExpressionResult {
fn with_expression(self: &Self, ctx: &mut Context, expression: &ast::Expression) -> ExpressionResult {
match &*expression.subexpression {
ast::Subexpression::LiteralInt(literal_int) => {
let value: i64 = literal_int.value.value.parse().unwrap();
@@ -362,18 +316,12 @@ impl TreeWalkInterpreter {
return ExpressionResult::Value(Value::Numeric(NumericValue::F64(value)));
}
ast::Subexpression::LiteralBool(literal_bool) => {
let value: bool = if &literal_bool.value.value == "true" {
true
} else {
false
};
let value: bool = if &literal_bool.value.value == "true" { true } else { false };
return ExpressionResult::Value(Value::Bool(value));
}
ast::Subexpression::LiteralStruct(literal_struct) => {
let declaration = match &ctx.environment[&literal_struct.name.name.value] {
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Struct(declaration)) => {
declaration.clone()
}
NamedEntity::TypeDeclaration(ast::TypeDeclaration::Struct(declaration)) => declaration.clone(),
_ => panic!("not a struct"),
};
@@ -416,17 +364,10 @@ impl TreeWalkInterpreter {
match &source {
Value::Function(Function::User(user_function)) => {
let mut fn_ctx = ctx.new_env();
for (i, function_arg) in
user_function.declaration.arguments.iter().enumerate()
{
fn_ctx.set_variable(
function_arg.name.name.value.to_string(),
&argument_values[i].clone(),
);
for (i, function_arg) in user_function.declaration.arguments.iter().enumerate() {
fn_ctx.set_variable(function_arg.name.name.value.to_string(), &argument_values[i].clone());
}
return ExpressionResult::Value(
self.with_function(&mut fn_ctx, user_function),
);
return ExpressionResult::Value(self.with_function(&mut fn_ctx, user_function));
}
Value::Function(Function::Builtin(builtin_function)) => {
return ExpressionResult::Value(builtin_function(argument_values));
@@ -473,9 +414,7 @@ impl TreeWalkInterpreter {
match &source {
Value::Struct(struct_) => {
let s = struct_.lock().unwrap();
return ExpressionResult::Value(
s.fields[&struct_getter.attribute.name.value].clone(),
);
return ExpressionResult::Value(s.fields[&struct_getter.attribute.name.value].clone());
}
_ => {
panic!("TypeError: struct getter used with non-struct");
@@ -500,217 +439,137 @@ impl TreeWalkInterpreter {
};
let result = match (&left, &op.op, &right) {
//I
(
Value::Numeric(NumericValue::I8(l)),
ast::Operator::Plus,
Value::Numeric(NumericValue::I8(r)),
) => Value::Numeric(NumericValue::I8(l + 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)),
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::I8(l)), ast::Operator::Plus, Value::Numeric(NumericValue::I8(r))) => {
Value::Numeric(NumericValue::I8(l + 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)), 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 + 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)),
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::I16(l)), ast::Operator::Plus, Value::Numeric(NumericValue::I16(r))) => {
Value::Numeric(NumericValue::I16(l + 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)), 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 + 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)),
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::I32(l)), ast::Operator::Plus, Value::Numeric(NumericValue::I32(r))) => {
Value::Numeric(NumericValue::I32(l + 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)), 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 + 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)),
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)),
(Value::Numeric(NumericValue::I64(l)), ast::Operator::Plus, Value::Numeric(NumericValue::I64(r))) => {
Value::Numeric(NumericValue::I64(l + 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)), 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
(
Value::Numeric(NumericValue::U8(l)),
ast::Operator::Plus,
Value::Numeric(NumericValue::U8(r)),
) => Value::Numeric(NumericValue::U8(l + 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)),
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::U8(l)), ast::Operator::Plus, Value::Numeric(NumericValue::U8(r))) => {
Value::Numeric(NumericValue::U8(l + 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)), 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 + 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)),
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::U16(l)), ast::Operator::Plus, Value::Numeric(NumericValue::U16(r))) => {
Value::Numeric(NumericValue::U16(l + 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)), 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 + 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)),
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::U32(l)), ast::Operator::Plus, Value::Numeric(NumericValue::U32(r))) => {
Value::Numeric(NumericValue::U32(l + 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)), 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 + 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)),
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)),
(Value::Numeric(NumericValue::U64(l)), ast::Operator::Plus, Value::Numeric(NumericValue::U64(r))) => {
Value::Numeric(NumericValue::U64(l + 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)), 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
(
Value::Numeric(NumericValue::F32(l)),
ast::Operator::Plus,
Value::Numeric(NumericValue::F32(r)),
) => Value::Numeric(NumericValue::F32(l + 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)),
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::F32(l)), ast::Operator::Plus, Value::Numeric(NumericValue::F32(r))) => {
Value::Numeric(NumericValue::F32(l + 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)), 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 + 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)),
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)),
(Value::Numeric(NumericValue::F64(l)), ast::Operator::Plus, Value::Numeric(NumericValue::F64(r))) => {
Value::Numeric(NumericValue::F64(l + 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)), 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
_ => panic!(""),

View File

@@ -27,34 +27,17 @@ fn main() {
.help("Sets an output file")
.takes_value(true),
)
.arg(
Arg::with_name("INPUT")
.help("Sets the input file")
.required(true)
.index(1),
)
.arg(
Arg::with_name("v")
.short("v")
.multiple(true)
.help("Sets the level of verbosity"),
)
.arg(Arg::with_name("INPUT").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();
let input = matches.value_of("INPUT").unwrap();
let default_output = input
.rsplitn(2, ".")
.collect::<Vec<&str>>()
.last()
.unwrap()
.clone();
let default_output = input.rsplitn(2, ".").collect::<Vec<&str>>().last().unwrap().clone();
let _output = matches.value_of("OUTPUT").unwrap_or(default_output);
let contents = fs::read_to_string(input).expect("input file not found");
let unknown_id_gen = ast::IdGenerator::new();
let module_ast = grammar::ModuleParser::new()
.parse(&unknown_id_gen, &contents)
.unwrap(); //TODO: convert to error
let module_ast = grammar::ModuleParser::new().parse(&unknown_id_gen, &contents).unwrap(); //TODO: convert to error
// println!("ast: {:#?}", &module_ast);
let alias_resolver = type_alias_resolution::TypeAliasResolver {};
let resolved_ast = alias_resolver.with_module(&module_ast);
@@ -85,47 +68,25 @@ fn main() {
#[test]
fn grammar() {
let id_gen = ast::IdGenerator::new();
assert!(grammar::LiteralIntParser::new()
.parse(&id_gen, "22")
.is_ok());
assert!(grammar::IdentifierParser::new()
.parse(&id_gen, "foo")
.is_ok());
assert!(grammar::LiteralIntParser::new()
.parse(&id_gen, "2a")
.is_err());
assert!(grammar::LiteralIntParser::new().parse(&id_gen, "22").is_ok());
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, "foo").is_ok());
assert!(grammar::ExpressionParser::new()
.parse(&id_gen, "22 * foo")
.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::ExpressionParser::new().parse(&id_gen, "22 * foo").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()
.parse(&id_gen, "{ (22 * 33) + 24 }")
.is_ok());
assert!(grammar::BlockParser::new()
.parse(&id_gen, "{ (22 * 33) + 24; 25 }")
.is_ok());
assert!(grammar::BlockParser::new().parse(&id_gen, "{ (22 * 33) + 24 }").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(&id_gen, "{ }").is_ok());
assert!(grammar::VariableDeclarationParser::new()
.parse(&id_gen, "foo: i32")
.is_ok());
assert!(grammar::VariableDeclarationParser::new()
.parse(&id_gen, "foo")
.is_err());
assert!(grammar::VariableDeclarationParser::new()
.parse(&id_gen, "1234")
.is_err());
assert!(grammar::VariableDeclarationParser::new().parse(&id_gen, "foo: i32").is_ok());
assert!(grammar::VariableDeclarationParser::new().parse(&id_gen, "foo").is_err());
assert!(grammar::VariableDeclarationParser::new().parse(&id_gen, "1234").is_err());
assert!(grammar::FunctionParser::new()
.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")
.is_err());
assert!(grammar::FunctionCallParser::new()
.parse(&id_gen, "foo(1, 2)")
.is_ok());
assert!(grammar::FunctionCallParser::new().parse(&id_gen, "foo(1, 2)").is_ok());
assert!(grammar::ModuleParser::new()
.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) => {
return ast::TypeUsage::Function(ast::FunctionTypeUsage {
arguments: function
.arguments
.iter()
.map(|a| process_type(ctx, &a.clone()))
.collect(),
arguments: function.arguments.iter().map(|a| process_type(ctx, &a.clone())).collect(),
return_type: Box::new(process_type(ctx, &function.return_type.clone())),
});
}
@@ -51,9 +47,7 @@ pub struct TypeAliasResolver {}
impl TypeAliasResolver {
pub fn with_module(self: &Self, module: &ast::Module) -> ast::Module {
let mut ctx = Context {
type_aliases: vec![],
};
let mut ctx = Context { type_aliases: vec![] };
for item in module.items.iter() {
match item {
ast::ModuleItem::TypeDeclaration(ast::TypeDeclaration::Alias(alias)) => {
@@ -68,17 +62,11 @@ impl TypeAliasResolver {
.items
.iter()
.map(|item| match item {
ast::ModuleItem::Function(function) => {
ast::ModuleItem::Function(self.with_function(&ctx, function))
}
ast::ModuleItem::Function(function) => ast::ModuleItem::Function(self.with_function(&ctx, function)),
ast::ModuleItem::TypeDeclaration(type_declaration) => {
ast::ModuleItem::TypeDeclaration(
self.with_type_declaration(&ctx, type_declaration),
)
}
ast::ModuleItem::Impl(impl_) => {
ast::ModuleItem::Impl(self.with_impl(&ctx, impl_))
ast::ModuleItem::TypeDeclaration(self.with_type_declaration(&ctx, type_declaration))
}
ast::ModuleItem::Impl(impl_) => ast::ModuleItem::Impl(self.with_impl(&ctx, impl_)),
})
.collect(),
};
@@ -86,10 +74,15 @@ impl TypeAliasResolver {
fn with_function(self: &Self, ctx: &Context, function: &ast::Function) -> ast::Function {
return ast::Function {
declaration: ast::FunctionDeclaration {
name: function.declaration.name.clone(),
arguments: function
.declaration
declaration: self.with_function_declaration(ctx, &function.declaration),
block: self.with_block(ctx, &function.block),
};
}
fn with_function_declaration(self: &Self, ctx: &Context, declaration: &ast::FunctionDeclaration) -> ast::FunctionDeclaration {
return ast::FunctionDeclaration {
name: declaration.name.clone(),
arguments: declaration
.arguments
.iter()
.map(|arg| ast::VariableDeclaration {
@@ -97,17 +90,11 @@ impl TypeAliasResolver {
type_: process_type(ctx, &arg.type_),
})
.collect(),
return_type: process_type(ctx, &function.declaration.return_type),
},
block: self.with_block(ctx, &function.block),
return_type: process_type(ctx, &declaration.return_type),
};
}
fn with_type_declaration(
self: &Self,
ctx: &Context,
type_declaration: &ast::TypeDeclaration,
) -> ast::TypeDeclaration {
fn with_type_declaration(self: &Self, ctx: &Context, type_declaration: &ast::TypeDeclaration) -> ast::TypeDeclaration {
match type_declaration {
ast::TypeDeclaration::Struct(struct_) => {
return ast::TypeDeclaration::Struct(self.with_struct_declaration(ctx, struct_));
@@ -118,14 +105,13 @@ impl TypeAliasResolver {
ast::TypeDeclaration::Alias(alias) => {
return ast::TypeDeclaration::Alias(alias.clone());
}
ast::TypeDeclaration::Trait(trait_) => {
return ast::TypeDeclaration::Trait(self.with_trait(ctx, trait_));
}
}
}
fn with_struct_declaration(
self: &Self,
ctx: &Context,
struct_: &ast::StructTypeDeclaration,
) -> ast::StructTypeDeclaration {
fn with_struct_declaration(self: &Self, ctx: &Context, struct_: &ast::StructTypeDeclaration) -> ast::StructTypeDeclaration {
return ast::StructTypeDeclaration {
name: struct_.name.clone(),
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 {
let mut impl_ctx = ctx.clone();
impl_ctx.type_aliases.push(ast::AliasTypeDeclaration {
@@ -153,22 +167,15 @@ impl TypeAliasResolver {
}),
});
return ast::Impl {
trait_: impl_.trait_.clone(),
struct_name: impl_.struct_name.clone(),
functions: impl_
.functions
.iter()
.map(|f| self.with_function(&impl_ctx, f))
.collect(),
functions: impl_.functions.iter().map(|f| self.with_function(&impl_ctx, f)).collect(),
};
}
fn with_block(self: &Self, ctx: &Context, block: &ast::Block) -> ast::Block {
return ast::Block {
statements: block
.statements
.iter()
.map(|s| self.with_statement(ctx, s))
.collect(),
statements: block.statements.iter().map(|s| self.with_statement(ctx, s)).collect(),
type_: process_type(ctx, &block.type_),
};
}
@@ -182,9 +189,7 @@ impl TypeAliasResolver {
return ast::Statement::Let(self.with_let_statement(ctx, let_statement));
}
ast::Statement::Assignment(assignment_statement) => {
return ast::Statement::Assignment(
self.with_assignment_statement(ctx, assignment_statement),
);
return ast::Statement::Assignment(self.with_assignment_statement(ctx, assignment_statement));
}
ast::Statement::Expression(expression) => {
return ast::Statement::Expression(self.with_expression(ctx, expression));
@@ -192,21 +197,13 @@ impl TypeAliasResolver {
}
}
fn with_return_statement(
self: &Self,
ctx: &Context,
statement: &ast::ReturnStatement,
) -> ast::ReturnStatement {
fn with_return_statement(self: &Self, ctx: &Context, statement: &ast::ReturnStatement) -> ast::ReturnStatement {
return ast::ReturnStatement {
source: self.with_expression(ctx, &statement.source),
};
}
fn with_let_statement(
self: &Self,
ctx: &Context,
statement: &ast::LetStatement,
) -> ast::LetStatement {
fn with_let_statement(self: &Self, ctx: &Context, statement: &ast::LetStatement) -> ast::LetStatement {
return ast::LetStatement {
variable_name: statement.variable_name.clone(),
expression: self.with_expression(ctx, &statement.expression),
@@ -214,56 +211,38 @@ impl TypeAliasResolver {
};
}
fn with_assignment_statement(
self: &Self,
ctx: &Context,
statement: &ast::AssignmentStatement,
) -> ast::AssignmentStatement {
fn with_assignment_statement(self: &Self, ctx: &Context, statement: &ast::AssignmentStatement) -> ast::AssignmentStatement {
return ast::AssignmentStatement {
source: match &statement.source {
ast::AssignmentTarget::Variable(variable) => {
ast::AssignmentTarget::Variable(ast::VariableUsage {
ast::AssignmentTarget::Variable(variable) => ast::AssignmentTarget::Variable(ast::VariableUsage {
name: variable.name.clone(),
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),
attribute: struct_attr.attribute.clone(),
type_: process_type(ctx, &struct_attr.type_),
})
}
}),
},
expression: self.with_expression(ctx, &statement.expression),
};
}
fn with_expression(
self: &Self,
ctx: &Context,
expression: &ast::Expression,
) -> ast::Expression {
fn with_expression(self: &Self, ctx: &Context, expression: &ast::Expression) -> ast::Expression {
return ast::Expression {
subexpression: Box::new(match &*expression.subexpression {
ast::Subexpression::LiteralInt(literal_int) => {
ast::Subexpression::LiteralInt(ast::LiteralInt {
ast::Subexpression::LiteralInt(literal_int) => ast::Subexpression::LiteralInt(ast::LiteralInt {
value: literal_int.value.clone(),
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(),
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(),
type_: process_type(ctx, &literal_bool.type_),
})
}
}),
ast::Subexpression::LiteralStruct(literal_struct) => {
let result = resolve_type(
ctx,
@@ -285,25 +264,16 @@ impl TypeAliasResolver {
type_: process_type(ctx, &literal_struct.type_),
})
}
ast::Subexpression::FunctionCall(function_call) => {
ast::Subexpression::FunctionCall(ast::FunctionCall {
ast::Subexpression::FunctionCall(function_call) => ast::Subexpression::FunctionCall(ast::FunctionCall {
source: self.with_expression(ctx, &function_call.source),
arguments: function_call
.arguments
.iter()
.map(|arg| self.with_expression(ctx, arg))
.collect(),
arguments: function_call.arguments.iter().map(|arg| self.with_expression(ctx, arg)).collect(),
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(),
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),
block: self.with_block(ctx, &if_expression.block),
else_: match &if_expression.else_ {
@@ -311,18 +281,13 @@ impl TypeAliasResolver {
None => None,
},
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),
attribute: struct_getter.attribute.clone(),
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 {
left: self.with_expression(ctx, &op.left),
op: op.op.clone(),

File diff suppressed because it is too large Load Diff