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 {
pub fn new() -> Self {
IdGenerator{counter: RefCell::new(0)}
IdGenerator {
counter: RefCell::new(0),
}
}
pub fn next(&self) -> String {
@@ -16,32 +18,31 @@ impl IdGenerator {
}
pub fn new_unit() -> TypeUsage {
TypeUsage::Named(NamedTypeUsage{
name: Identifier{
name: Spanned{
span: Span{left: 0, right: 0}, //todo: figure out a sane value for these
TypeUsage::Named(NamedTypeUsage {
name: Identifier {
name: Spanned {
span: Span { left: 0, right: 0 }, //todo: figure out a sane value for these
value: "unit".to_string(),
}
}
},
},
})
}
pub fn new_never() -> TypeUsage {
TypeUsage::Named(NamedTypeUsage{
name: Identifier{
name: Spanned{
span: Span{left: 0, right: 0}, //todo: figure out a sane value for these
TypeUsage::Named(NamedTypeUsage {
name: Identifier {
name: Spanned {
span: Span { left: 0, right: 0 }, //todo: figure out a sane value for these
value: "!".to_string(),
}
}
},
},
})
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct Span {
pub left: usize,
pub right: usize
pub right: usize,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
@@ -50,7 +51,6 @@ pub struct Spanned<T> {
pub value: T,
}
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
pub struct FunctionTypeUsage {
pub arguments: Vec<TypeUsage>,
@@ -76,31 +76,33 @@ pub enum TypeUsage {
impl TypeUsage {
pub fn new_unknown(id_gen: &IdGenerator) -> TypeUsage {
return TypeUsage::Unknown(UnknownTypeUsage{
return TypeUsage::Unknown(UnknownTypeUsage {
name: id_gen.next(),
});
}
pub fn new_named(identifier: Identifier) -> TypeUsage {
return TypeUsage::Named(NamedTypeUsage{
return TypeUsage::Named(NamedTypeUsage {
name: identifier.clone(),
});
}
pub fn new_builtin(name: String) -> TypeUsage {
TypeUsage::Named(NamedTypeUsage{
name: Identifier{
name: Spanned{
span: Span{left: 0, right: 0}, //todo: figure out a sane value for these
TypeUsage::Named(NamedTypeUsage {
name: Identifier {
name: Spanned {
span: Span { left: 0, right: 0 }, //todo: figure out a sane value for these
value: name,
}
}
},
},
})
}
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(),
return TypeUsage::Function(FunctionTypeUsage {
arguments: (0..arg_count)
.map(|_| TypeUsage::new_unknown(&id_gen))
.collect(),
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::context::Context;
use inkwell::module::Module;
use inkwell::values::{BasicValueEnum, FunctionValue, IntValue};
use std::collections::HashMap;
use std::convert::TryInto;
use std::mem;
use crate::ast;
@@ -17,28 +17,39 @@ pub struct ModuleCodeGen<'ctx> {
scope: Scope<'ctx>,
}
impl<'ctx> ModuleCodeGen<'ctx> {
pub fn new(context: &'ctx Context, name: String) -> Self {
return ModuleCodeGen{
return ModuleCodeGen {
context: context,
module: context.create_module(&name),
builder: context.create_builder(),
scope: Scope::new(),
}
};
}
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"),
@@ -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 {
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::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.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()
.left()
.unwrap();
@@ -100,7 +123,10 @@ 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

@@ -2,7 +2,8 @@
mod ast;
mod type_alias_resolution;
mod type_checking;
#[macro_use] extern crate lalrpop_util;
#[macro_use]
extern crate lalrpop_util;
lalrpop_mod!(pub grammar); // synthesized by LALRPOP
@@ -11,42 +12,54 @@ use std::io::Write;
// mod compiler;
// use inkwell::context::Context;
extern crate clap;
use clap::{Arg, App};
use clap::{App, Arg};
fn main() {
let matches = App::new("Boring Language Compiler")
.version("0.0.1")
.author("Andrew Segavac")
.about("Compiles boring language files to LLVM IR.")
.arg(Arg::with_name("OUTPUT")
.short("o")
.long("out")
.value_name("OUTOUT")
.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"))
.get_matches();
.version("0.0.1")
.author("Andrew Segavac")
.about("Compiles boring language files to LLVM IR.")
.arg(
Arg::with_name("OUTPUT")
.short("o")
.long("out")
.value_name("OUTOUT")
.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"),
)
.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 alias_resolver = type_alias_resolution::TypeAliasResolver {};
let resolved_ast = alias_resolver.with_module(&module_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);
println!("checked ast: {:#?}", &checked_ast);
println!("substitutions: {:#?}", &subst);
@@ -59,37 +72,70 @@ fn main() {
// f.write_all(code_gen.dump().as_bytes()).expect("Unable to write data");
}
#[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: Int32").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: Int32")
.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().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::FunctionParser::new()
.parse(&id_gen, "fn add(a: Int32, b: Int32): Int32 { a + b }")
.is_ok());
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());
}

View File

@@ -1,6 +1,5 @@
use crate::ast;
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
struct Context {
pub type_aliases: Vec<ast::AliasTypeDeclaration>,
@@ -20,7 +19,7 @@ fn resolve_type(ctx: &Context, type_: &ast::NamedTypeUsage) -> ast::TypeUsage {
result = alias.replaces.clone();
}
}
},
}
_ => break,
}
}
@@ -31,16 +30,20 @@ fn process_type(ctx: &Context, type_: &ast::TypeUsage) -> ast::TypeUsage {
match type_ {
ast::TypeUsage::Named(named) => {
return resolve_type(ctx, named);
},
}
ast::TypeUsage::Function(function) => {
return ast::TypeUsage::Function(ast::FunctionTypeUsage{
arguments: function.arguments.iter().map(|a|{process_type(ctx, &a.clone())}).collect(),
return ast::TypeUsage::Function(ast::FunctionTypeUsage {
arguments: function
.arguments
.iter()
.map(|a| process_type(ctx, &a.clone()))
.collect(),
return_type: Box::new(process_type(ctx, &function.return_type.clone())),
});
},
}
ast::TypeUsage::Unknown(unknown) => {
return ast::TypeUsage::Unknown(unknown.clone());
},
}
}
}
@@ -48,98 +51,124 @@ 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)) => {
ctx.type_aliases.push(alias.clone());
},
_ => {},
}
_ => {}
}
}
return ast::Module{
items: module.items.iter().map(|item|{
match item {
return ast::Module {
items: module
.items
.iter()
.map(|item| match item {
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::TypeDeclaration(
self.with_type_declaration(&ctx, type_declaration),
)
}
ast::ModuleItem::Impl(impl_) => {
ast::ModuleItem::Impl(self.with_impl(&ctx, impl_))
},
}
}).collect()
}
})
.collect(),
};
}
fn with_function(self: &Self, ctx: &Context, function: &ast::Function) -> ast::Function {
return ast::Function{
declaration: ast::FunctionDeclaration{
return ast::Function {
declaration: ast::FunctionDeclaration {
name: function.declaration.name.clone(),
arguments: function.declaration.arguments.iter().map(|arg| {
ast::VariableDeclaration{name: arg.name.clone(), type_: process_type(ctx, &arg.type_)}
}).collect(),
arguments: function
.declaration
.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),
},
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 {
ast::TypeDeclaration::Struct(struct_) => {
return ast::TypeDeclaration::Struct(self.with_struct_declaration(ctx, struct_));
},
}
ast::TypeDeclaration::Primitive(primitive) => {
return ast::TypeDeclaration::Primitive(primitive.clone());
},
}
ast::TypeDeclaration::Alias(alias) => {
return ast::TypeDeclaration::Alias(alias.clone());
},
}
}
}
fn with_struct_declaration(self: &Self, ctx: &Context, struct_: &ast::StructTypeDeclaration) -> ast::StructTypeDeclaration {
return ast::StructTypeDeclaration{
fn with_struct_declaration(
self: &Self,
ctx: &Context,
struct_: &ast::StructTypeDeclaration,
) -> ast::StructTypeDeclaration {
return ast::StructTypeDeclaration {
name: struct_.name.clone(),
fields: struct_.fields.iter().map(|field|{
ast::StructField{
fields: struct_
.fields
.iter()
.map(|field| ast::StructField {
name: field.name.clone(),
type_: process_type(ctx, &field.type_),
}
}).collect(),
})
.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{
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(),
}
impl_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: 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(),
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(),
return ast::Block {
statements: block
.statements
.iter()
.map(|s| self.with_statement(ctx, s))
.collect(),
type_: process_type(ctx, &block.type_),
};
}
@@ -148,115 +177,142 @@ impl TypeAliasResolver {
match statement {
ast::Statement::Return(return_statement) => {
return ast::Statement::Return(self.with_return_statement(ctx, return_statement));
},
}
ast::Statement::Let(let_statement) => {
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));
},
}
}
}
fn with_return_statement(self: &Self, ctx: &Context, statement: &ast::ReturnStatement) -> ast::ReturnStatement {
return 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 {
return 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),
type_: process_type(ctx, &statement.type_),
};
}
fn with_assignment_statement(self: &Self, ctx: &Context, statement: &ast::AssignmentStatement) -> ast::AssignmentStatement {
return 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(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(ast::StructGetter {
source: self.with_expression(ctx, &struct_attr.source),
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),
}
};
}
fn with_expression(self: &Self, ctx: &Context, expression: &ast::Expression) -> ast::Expression {
return 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(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(ast::LiteralFloat {
value: literal_float.value.clone(),
type_: process_type(ctx, &literal_float.type_),
})
},
}
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 {
ast::TypeUsage::Named(named) => { named.name.clone() },
ast::TypeUsage::Named(named) => named.name.clone(),
_ => panic!("LiteralStruct resolved to non-named-type"),
};
ast::Subexpression::LiteralStruct(ast::LiteralStruct{
ast::Subexpression::LiteralStruct(ast::LiteralStruct {
name: new_name.clone(),
fields: literal_struct.fields.iter().map(|field|{
(field.0.clone(), self.with_expression(ctx, &field.1))
}).collect(),
fields: literal_struct
.fields
.iter()
.map(|field| (field.0.clone(), self.with_expression(ctx, &field.1)))
.collect(),
type_: process_type(ctx, &literal_struct.type_),
})
},
}
ast::Subexpression::FunctionCall(function_call) => {
ast::Subexpression::FunctionCall(ast::FunctionCall{
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(),
type_: process_type(ctx, &function_call.type_)
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(ast::VariableUsage {
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(ast::StructGetter{
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::Op(op) => {
ast::Subexpression::Op(ast::Operation{
left: self.with_expression(ctx, &op.left),
op: op.op.clone(),
right: self.with_expression(ctx, &op.right),
})
},
}
ast::Subexpression::Op(op) => ast::Subexpression::Op(ast::Operation {
left: self.with_expression(ctx, &op.left),
op: op.op.clone(),
right: self.with_expression(ctx, &op.right),
}),
}),
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,
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum IntBitness {
X8,
@@ -14,7 +13,6 @@ pub enum IntBitness {
X128,
}
#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
pub enum FloatBitness {
X32,
@@ -22,14 +20,12 @@ pub enum FloatBitness {
X128,
}
#[derive(Clone, Eq, PartialEq, Hash)]
pub struct IntTypeDef {
pub signedness: Signedness,
pub bitness: IntBitness,
}
#[derive(Clone, PartialEq, Eq, Hash)]
pub struct FloatTypeDef {
pub bitness: FloatBitness,
@@ -41,7 +37,6 @@ pub struct FunctionTypeDef {
pub return_type: Box<Type>,
}
#[derive(Clone, PartialEq, Eq, Hash)]
pub enum Type {
Bool,
@@ -55,7 +50,6 @@ pub enum Type {
// Never,
}
/// Used for places where type info may or may not be solved.
#[derive(Clone, Eq, PartialEq, Hash)]
pub enum SpecifiedType {