ran rust format

This commit is contained in:
Andrew Segavac
2021-09-11 12:34:23 -06:00
parent 1e4deadb9c
commit a6620b2a86
6 changed files with 958 additions and 452 deletions

View File

@@ -6,7 +6,9 @@ pub struct IdGenerator {
impl IdGenerator { impl IdGenerator {
pub fn new() -> Self { pub fn new() -> Self {
IdGenerator{counter: RefCell::new(0)} IdGenerator {
counter: RefCell::new(0),
}
} }
pub fn next(&self) -> String { pub fn next(&self) -> String {
@@ -16,32 +18,31 @@ impl IdGenerator {
} }
pub fn new_unit() -> TypeUsage { pub fn new_unit() -> TypeUsage {
TypeUsage::Named(NamedTypeUsage{ TypeUsage::Named(NamedTypeUsage {
name: Identifier{ name: Identifier {
name: Spanned{ name: Spanned {
span: Span{left: 0, right: 0}, //todo: figure out a sane value for these span: Span { left: 0, right: 0 }, //todo: figure out a sane value for these
value: "unit".to_string(), value: "unit".to_string(),
} },
} },
}) })
} }
pub fn new_never() -> TypeUsage { pub fn new_never() -> TypeUsage {
TypeUsage::Named(NamedTypeUsage{ TypeUsage::Named(NamedTypeUsage {
name: Identifier{ name: Identifier {
name: Spanned{ name: Spanned {
span: Span{left: 0, right: 0}, //todo: figure out a sane value for these span: Span { left: 0, right: 0 }, //todo: figure out a sane value for these
value: "!".to_string(), value: "!".to_string(),
} },
} },
}) })
} }
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Span { pub struct Span {
pub left: usize, pub left: usize,
pub right: usize pub right: usize,
} }
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -50,7 +51,6 @@ pub struct Spanned<T> {
pub value: T, pub value: T,
} }
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct FunctionTypeUsage { pub struct FunctionTypeUsage {
pub arguments: Vec<TypeUsage>, pub arguments: Vec<TypeUsage>,
@@ -76,31 +76,33 @@ 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 {
TypeUsage::Named(NamedTypeUsage{ TypeUsage::Named(NamedTypeUsage {
name: Identifier{ name: Identifier {
name: Spanned{ name: Spanned {
span: Span{left: 0, right: 0}, //todo: figure out a sane value for these span: Span { left: 0, right: 0 }, //todo: figure out a sane value for these
value: name, value: name,
} },
} },
}) })
} }
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).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)), return_type: Box::new(TypeUsage::new_unknown(&id_gen)),
}); });
} }

View File

@@ -1,10 +1,10 @@
use std::collections::HashMap;
use std::mem;
use std::convert::TryInto;
use inkwell::builder::Builder; use inkwell::builder::Builder;
use inkwell::context::Context; use inkwell::context::Context;
use inkwell::module::Module; use inkwell::module::Module;
use inkwell::values::{BasicValueEnum, FunctionValue, IntValue}; use inkwell::values::{BasicValueEnum, FunctionValue, IntValue};
use std::collections::HashMap;
use std::convert::TryInto;
use std::mem;
use crate::ast; use crate::ast;
@@ -17,28 +17,39 @@ pub struct ModuleCodeGen<'ctx> {
scope: Scope<'ctx>, scope: Scope<'ctx>,
} }
impl<'ctx> ModuleCodeGen<'ctx> { impl<'ctx> ModuleCodeGen<'ctx> {
pub fn new(context: &'ctx Context, name: String) -> Self { pub fn new(context: &'ctx Context, name: String) -> Self {
return ModuleCodeGen{ return ModuleCodeGen {
context: context, context: context,
module: context.create_module(&name), module: context.create_module(&name),
builder: context.create_builder(), builder: context.create_builder(),
scope: Scope::new(), scope: Scope::new(),
} };
} }
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(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 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(&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 { 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"),
@@ -47,28 +58,40 @@ 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 { 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) => { ast::Expression::Identifier(identifier) => match scope[&identifier.name] {
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) => 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), 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 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(self.gen_expression(scope, &expression))); arguments.push(BasicValueEnum::IntValue(
self.gen_expression(scope, &expression),
));
} }
let result = self.builder.build_call(fn_value, &arguments, &function_call.name.name) let result = self
.builder
.build_call(fn_value, &arguments, &function_call.name.name)
.try_as_basic_value() .try_as_basic_value()
.left() .left()
.unwrap(); .unwrap();
@@ -100,7 +123,10 @@ 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(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 body = &function.block;
let return_value = self.gen_expression(&scope, &body.expression); let return_value = self.gen_expression(&scope, &body.expression);

View File

@@ -2,7 +2,8 @@
mod ast; mod ast;
mod type_alias_resolution; mod type_alias_resolution;
mod type_checking; mod type_checking;
#[macro_use] extern crate lalrpop_util; #[macro_use]
extern crate lalrpop_util;
lalrpop_mod!(pub grammar); // synthesized by LALRPOP lalrpop_mod!(pub grammar); // synthesized by LALRPOP
@@ -11,42 +12,54 @@ use std::io::Write;
// mod compiler; // mod compiler;
// use inkwell::context::Context; // use inkwell::context::Context;
extern crate clap; extern crate clap;
use clap::{Arg, App}; use clap::{App, Arg};
fn main() { fn main() {
let matches = App::new("Boring Language Compiler") let matches = App::new("Boring Language Compiler")
.version("0.0.1") .version("0.0.1")
.author("Andrew Segavac") .author("Andrew Segavac")
.about("Compiles boring language files to LLVM IR.") .about("Compiles boring language files to LLVM IR.")
.arg(Arg::with_name("OUTPUT") .arg(
Arg::with_name("OUTPUT")
.short("o") .short("o")
.long("out") .long("out")
.value_name("OUTOUT") .value_name("OUTOUT")
.help("Sets an output file") .help("Sets an output file")
.takes_value(true)) .takes_value(true),
.arg(Arg::with_name("INPUT") )
.arg(
Arg::with_name("INPUT")
.help("Sets the input file") .help("Sets the input file")
.required(true) .required(true)
.index(1)) .index(1),
.arg(Arg::with_name("v") )
.arg(
Arg::with_name("v")
.short("v") .short("v")
.multiple(true) .multiple(true)
.help("Sets the level of verbosity")) .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.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 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().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); 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);
println!("resolved ast: {:#?}", &resolved_ast); println!("resolved ast: {:#?}", &resolved_ast);
let type_checker = type_checking::TypeChecker{}; let type_checker = type_checking::TypeChecker {};
let (checked_ast, subst) = type_checker.with_module(&resolved_ast); let (checked_ast, subst) = type_checker.with_module(&resolved_ast);
println!("checked ast: {:#?}", &checked_ast); println!("checked ast: {:#?}", &checked_ast);
println!("substitutions: {:#?}", &subst); println!("substitutions: {:#?}", &subst);
@@ -59,37 +72,70 @@ fn main() {
// f.write_all(code_gen.dump().as_bytes()).expect("Unable to write data"); // f.write_all(code_gen.dump().as_bytes()).expect("Unable to write data");
} }
#[test] #[test]
fn grammar() { fn grammar() {
let id_gen = ast::IdGenerator::new(); let id_gen = ast::IdGenerator::new();
assert!(grammar::LiteralIntParser::new().parse(&id_gen, "22").is_ok()); assert!(grammar::LiteralIntParser::new()
assert!(grammar::IdentifierParser::new().parse(&id_gen, "foo").is_ok()); .parse(&id_gen, "22")
assert!(grammar::LiteralIntParser::new().parse(&id_gen, "2a").is_err()); .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, "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().parse(&id_gen, "22 * foo").is_ok()); assert!(grammar::ExpressionParser::new()
assert!(grammar::ExpressionParser::new().parse(&id_gen, "22 * 33").is_ok()); .parse(&id_gen, "22 * foo")
assert!(grammar::ExpressionParser::new().parse(&id_gen, "(22 * 33) + 24").is_ok()); .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()
assert!(grammar::BlockParser::new().parse(&id_gen, "{ (22 * 33) + 24; 25 }").is_ok()); .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("{ (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().parse(&id_gen, "foo: Int32").is_ok()); assert!(grammar::VariableDeclarationParser::new()
assert!(grammar::VariableDeclarationParser::new().parse(&id_gen, "foo").is_err()); .parse(&id_gen, "foo: Int32")
assert!(grammar::VariableDeclarationParser::new().parse(&id_gen, "1234").is_err()); .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: Int32, b: Int32): Int32 { a + b }").is_ok()); assert!(grammar::FunctionParser::new()
assert!(grammar::FunctionParser::new().parse(&id_gen, "fn random_dice_roll(): Int32 { 4 }").is_ok()); .parse(&id_gen, "fn add(a: Int32, b: Int32): Int32 { a + b }")
assert!(grammar::FunctionParser::new().parse(&id_gen, "fn add(a: Int32, b: Int32): Int32 { a + }").is_err()); .is_ok());
assert!(grammar::FunctionParser::new().parse(&id_gen, "fn add(a: Int32, b: Int32): Int32").is_err()); assert!(grammar::FunctionParser::new()
.parse(&id_gen, "fn random_dice_roll(): Int32 { 4 }")
.is_ok());
assert!(grammar::FunctionParser::new()
.parse(&id_gen, "fn add(a: Int32, b: Int32): Int32 { a + }")
.is_err());
assert!(grammar::FunctionParser::new()
.parse(&id_gen, "fn add(a: Int32, b: Int32): Int32")
.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: Int32, b: Int32): Int32 { a + b }").is_ok()); assert!(grammar::ModuleParser::new()
.parse(&id_gen, "fn add(a: Int32, b: Int32): Int32 { a + b }")
.is_ok());
assert!(grammar::ModuleParser::new().parse(&id_gen, "fn add(a: Int32, b: Int32): Int32 { a + b } fn subtract(a: Int32, b: Int32): Int32 { a - b }").is_ok()); assert!(grammar::ModuleParser::new().parse(&id_gen, "fn add(a: Int32, b: Int32): Int32 { a + b } fn subtract(a: Int32, b: Int32): Int32 { a - b }").is_ok());
} }

View File

@@ -1,6 +1,5 @@
use crate::ast; use crate::ast;
#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[derive(Debug, Clone, PartialEq, Eq, Hash)]
struct Context { struct Context {
pub type_aliases: Vec<ast::AliasTypeDeclaration>, pub type_aliases: Vec<ast::AliasTypeDeclaration>,
@@ -20,7 +19,7 @@ fn resolve_type(ctx: &Context, type_: &ast::NamedTypeUsage) -> ast::TypeUsage {
result = alias.replaces.clone(); result = alias.replaces.clone();
} }
} }
}, }
_ => break, _ => break,
} }
} }
@@ -31,16 +30,20 @@ fn process_type(ctx: &Context, type_: &ast::TypeUsage) -> ast::TypeUsage {
match type_ { match type_ {
ast::TypeUsage::Named(named) => { ast::TypeUsage::Named(named) => {
return resolve_type(ctx, named); return resolve_type(ctx, named);
}, }
ast::TypeUsage::Function(function) => { ast::TypeUsage::Function(function) => {
return ast::TypeUsage::Function(ast::FunctionTypeUsage{ 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())), return_type: Box::new(process_type(ctx, &function.return_type.clone())),
}); });
}, }
ast::TypeUsage::Unknown(unknown) => { ast::TypeUsage::Unknown(unknown) => {
return ast::TypeUsage::Unknown(unknown.clone()); return ast::TypeUsage::Unknown(unknown.clone());
}, }
} }
} }
@@ -48,98 +51,124 @@ 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)) => {
ctx.type_aliases.push(alias.clone()); ctx.type_aliases.push(alias.clone());
}, }
_ => {}, _ => {}
} }
} }
return ast::Module{ return ast::Module {
items: module.items.iter().map(|item|{ items: module
match item { .items
.iter()
.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(self.with_type_declaration(&ctx, type_declaration)) ast::ModuleItem::TypeDeclaration(
}, self.with_type_declaration(&ctx, type_declaration),
)
}
ast::ModuleItem::Impl(impl_) => { ast::ModuleItem::Impl(impl_) => {
ast::ModuleItem::Impl(self.with_impl(&ctx, impl_)) ast::ModuleItem::Impl(self.with_impl(&ctx, impl_))
},
} }
}).collect() })
.collect(),
}; };
} }
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: ast::FunctionDeclaration {
name: function.declaration.name.clone(), name: function.declaration.name.clone(),
arguments: function.declaration.arguments.iter().map(|arg| { arguments: function
ast::VariableDeclaration{name: arg.name.clone(), type_: process_type(ctx, &arg.type_)} .declaration
}).collect(), .arguments
.iter()
.map(|arg| ast::VariableDeclaration {
name: arg.name.clone(),
type_: process_type(ctx, &arg.type_),
})
.collect(),
return_type: process_type(ctx, &function.declaration.return_type), return_type: process_type(ctx, &function.declaration.return_type),
}, },
block: self.with_block(ctx, &function.block), block: self.with_block(ctx, &function.block),
}; };
} }
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 { 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_));
}, }
ast::TypeDeclaration::Primitive(primitive) => { ast::TypeDeclaration::Primitive(primitive) => {
return ast::TypeDeclaration::Primitive(primitive.clone()); return ast::TypeDeclaration::Primitive(primitive.clone());
}, }
ast::TypeDeclaration::Alias(alias) => { ast::TypeDeclaration::Alias(alias) => {
return ast::TypeDeclaration::Alias(alias.clone()); return ast::TypeDeclaration::Alias(alias.clone());
}, }
} }
} }
fn with_struct_declaration(self: &Self, ctx: &Context, struct_: &ast::StructTypeDeclaration) -> ast::StructTypeDeclaration { fn with_struct_declaration(
return ast::StructTypeDeclaration{ self: &Self,
ctx: &Context,
struct_: &ast::StructTypeDeclaration,
) -> ast::StructTypeDeclaration {
return ast::StructTypeDeclaration {
name: struct_.name.clone(), name: struct_.name.clone(),
fields: struct_.fields.iter().map(|field|{ fields: struct_
ast::StructField{ .fields
.iter()
.map(|field| ast::StructField {
name: field.name.clone(), name: field.name.clone(),
type_: process_type(ctx, &field.type_), type_: process_type(ctx, &field.type_),
} })
}).collect(), .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 {
name: ast::Identifier{ name: ast::Identifier {
name: ast::Spanned{ name: ast::Spanned {
span: ast::Span{left: 0, right: 0}, //todo: figure out a sane value for these span: ast::Span { left: 0, right: 0 }, //todo: figure out a sane value for these
value: "Self".to_string(), value: "Self".to_string(),
}
}, },
replaces: ast::TypeUsage::Named(ast::NamedTypeUsage{name: impl_.struct_name.clone()}) },
replaces: ast::TypeUsage::Named(ast::NamedTypeUsage {
name: impl_.struct_name.clone(),
}),
}); });
return ast::Impl{ return ast::Impl {
struct_name: impl_.struct_name.clone(), struct_name: impl_.struct_name.clone(),
functions: impl_.functions.iter().map(|f|{ functions: impl_
self.with_function(&impl_ctx, f) .functions
}).collect(), .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.iter().map(|s| { statements: block
self.with_statement(ctx, s) .statements
}).collect(), .iter()
.map(|s| self.with_statement(ctx, s))
.collect(),
type_: process_type(ctx, &block.type_), type_: process_type(ctx, &block.type_),
}; };
} }
@@ -148,115 +177,142 @@ impl TypeAliasResolver {
match statement { match statement {
ast::Statement::Return(return_statement) => { ast::Statement::Return(return_statement) => {
return ast::Statement::Return(self.with_return_statement(ctx, return_statement)); return ast::Statement::Return(self.with_return_statement(ctx, return_statement));
}, }
ast::Statement::Let(let_statement) => { ast::Statement::Let(let_statement) => {
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(self.with_assignment_statement(ctx, assignment_statement)); return ast::Statement::Assignment(
}, 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));
}, }
} }
} }
fn with_return_statement(self: &Self, ctx: &Context, statement: &ast::ReturnStatement) -> ast::ReturnStatement { fn with_return_statement(
return ast::ReturnStatement{ self: &Self,
ctx: &Context,
statement: &ast::ReturnStatement,
) -> ast::ReturnStatement {
return ast::ReturnStatement {
source: self.with_expression(ctx, &statement.source), source: self.with_expression(ctx, &statement.source),
}; };
} }
fn with_let_statement(self: &Self, ctx: &Context, statement: &ast::LetStatement) -> ast::LetStatement { fn with_let_statement(
return ast::LetStatement{ self: &Self,
ctx: &Context,
statement: &ast::LetStatement,
) -> 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),
type_: process_type(ctx, &statement.type_), type_: process_type(ctx, &statement.type_),
}; };
} }
fn with_assignment_statement(self: &Self, ctx: &Context, statement: &ast::AssignmentStatement) -> ast::AssignmentStatement { fn with_assignment_statement(
return ast::AssignmentStatement{ self: &Self,
ctx: &Context,
statement: &ast::AssignmentStatement,
) -> 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(struct_attr) => {
ast::AssignmentTarget::StructAttr(ast::StructGetter{ 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(self: &Self, ctx: &Context, expression: &ast::Expression) -> ast::Expression { fn with_expression(
return ast::Expression{ self: &Self,
ctx: &Context,
expression: &ast::Expression,
) -> 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(literal_float) => {
ast::Subexpression::LiteralFloat(ast::LiteralFloat{ 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::LiteralStruct(literal_struct) => { ast::Subexpression::LiteralStruct(literal_struct) => {
let result = resolve_type(ctx, &ast::NamedTypeUsage{name: literal_struct.name.clone()}); let result = resolve_type(
ctx,
&ast::NamedTypeUsage {
name: literal_struct.name.clone(),
},
);
let new_name = match &result { let new_name = match &result {
ast::TypeUsage::Named(named) => { named.name.clone() }, ast::TypeUsage::Named(named) => named.name.clone(),
_ => panic!("LiteralStruct resolved to non-named-type"), _ => panic!("LiteralStruct resolved to non-named-type"),
}; };
ast::Subexpression::LiteralStruct(ast::LiteralStruct{ ast::Subexpression::LiteralStruct(ast::LiteralStruct {
name: new_name.clone(), name: new_name.clone(),
fields: literal_struct.fields.iter().map(|field|{ fields: literal_struct
(field.0.clone(), self.with_expression(ctx, &field.1)) .fields
}).collect(), .iter()
.map(|field| (field.0.clone(), self.with_expression(ctx, &field.1)))
.collect(),
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.iter().map(|arg| {self.with_expression(ctx, arg)}).collect(), arguments: function_call
type_: process_type(ctx, &function_call.type_) .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(variable_usage) => {
ast::Subexpression::VariableUsage(ast::VariableUsage{ 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::StructGetter(struct_getter) => { ast::Subexpression::StructGetter(struct_getter) => {
ast::Subexpression::StructGetter(ast::StructGetter{ 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(block) => {
ast::Subexpression::Block(self.with_block(ctx, &block)) ast::Subexpression::Block(self.with_block(ctx, &block))
}, }
ast::Subexpression::Op(op) => { ast::Subexpression::Op(op) => ast::Subexpression::Op(ast::Operation {
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(),
right: self.with_expression(ctx, &op.right), right: self.with_expression(ctx, &op.right),
}) }),
},
}), }),
type_: process_type(ctx, &expression.type_), type_: process_type(ctx, &expression.type_),
} };
} }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -4,7 +4,6 @@ pub enum Signedness {
Unsigned, Unsigned,
} }
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum IntBitness { pub enum IntBitness {
X8, X8,
@@ -14,7 +13,6 @@ pub enum IntBitness {
X128, X128,
} }
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)] #[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum FloatBitness { pub enum FloatBitness {
X32, X32,
@@ -22,14 +20,12 @@ pub enum FloatBitness {
X128, X128,
} }
#[derive(Clone, Eq, PartialEq, Hash)] #[derive(Clone, Eq, PartialEq, Hash)]
pub struct IntTypeDef { pub struct IntTypeDef {
pub signedness: Signedness, pub signedness: Signedness,
pub bitness: IntBitness, pub bitness: IntBitness,
} }
#[derive(Clone, PartialEq, Eq, Hash)] #[derive(Clone, PartialEq, Eq, Hash)]
pub struct FloatTypeDef { pub struct FloatTypeDef {
pub bitness: FloatBitness, pub bitness: FloatBitness,
@@ -41,7 +37,6 @@ pub struct FunctionTypeDef {
pub return_type: Box<Type>, pub return_type: Box<Type>,
} }
#[derive(Clone, PartialEq, Eq, Hash)] #[derive(Clone, PartialEq, Eq, Hash)]
pub enum Type { pub enum Type {
Bool, Bool,
@@ -55,7 +50,6 @@ pub enum Type {
// Never, // Never,
} }
/// Used for places where type info may or may not be solved. /// Used for places where type info may or may not be solved.
#[derive(Clone, Eq, PartialEq, Hash)] #[derive(Clone, Eq, PartialEq, Hash)]
pub enum SpecifiedType { pub enum SpecifiedType {