From 37e083e2a7a00b1622e39eb80b91c5f2efd814db Mon Sep 17 00:00:00 2001 From: Edgar Date: Sat, 3 Feb 2024 10:24:44 +0100 Subject: [PATCH] p --- lib/edlang_lowering/src/lib.rs | 68 ++++++++++++++++++++++++++-------- programs/simple.ed | 5 ++- 2 files changed, 55 insertions(+), 18 deletions(-) diff --git a/lib/edlang_lowering/src/lib.rs b/lib/edlang_lowering/src/lib.rs index c4d5e9fae..8ed67e3b5 100644 --- a/lib/edlang_lowering/src/lib.rs +++ b/lib/edlang_lowering/src/lib.rs @@ -1,5 +1,6 @@ use std::collections::HashMap; +use ast::Function; use edlang_ast as ast; use edlang_ir as ir; use ir::{DefId, Local, Operand, Place, Statement, TypeInfo}; @@ -32,6 +33,12 @@ impl IdGenerator { } } +struct BuildCtx { + pub func_ids: HashMap, + pub functions: HashMap, + pub gen: IdGenerator, +} + pub fn lower_module(gen: &mut IdGenerator, module: &ast::Module) -> ir::ModuleBody { let mut body = ir::ModuleBody { module_id: gen.next_id(), @@ -40,13 +47,27 @@ pub fn lower_module(gen: &mut IdGenerator, module: &ast::Module) -> ir::ModuleBo span: module.span, }; - let mut module_gen_id = IdGenerator::new(body.module_id); + let mut ctx = BuildCtx { + func_ids: Default::default(), + functions: Default::default(), + gen: IdGenerator::new(body.module_id), + }; for stmt in &module.contents { match stmt { ast::ModuleStatement::Function(func) => { - let res = lower_function(&mut module_gen_id, func); + ctx.func_ids.insert(func.name.name.clone(), ctx.gen.next_defid()); + } + _ => {} + } + } + + for stmt in &module.contents { + match stmt { + ast::ModuleStatement::Function(func) => { + let (res, new_ctx) = lower_function(ctx, func); body.functions.insert(res.def_id, res); + ctx = new_ctx; } ast::ModuleStatement::Constant(_) => todo!(), ast::ModuleStatement::Struct(_) => todo!(), @@ -62,12 +83,13 @@ struct BodyBuilder { pub statements: Vec, pub locals: HashMap, pub ret_local: Option, + pub ctx: BuildCtx, } -fn lower_function(gen: &mut IdGenerator, func: &ast::Function) -> ir::Body { +fn lower_function(mut ctx: BuildCtx, func: &ast::Function) -> (ir::Body, BuildCtx) { let body = ir::Body { - def_id: gen.next_defid(), - ret_type: func.return_type.as_ref().map(|x| lower_type(gen, x)), + def_id: *ctx.func_ids.get(&func.name.name).unwrap(), + ret_type: func.return_type.as_ref().map(|x| lower_type(&mut ctx, x)), locals: Default::default(), blocks: Default::default(), fn_span: func.span, @@ -80,12 +102,13 @@ fn lower_function(gen: &mut IdGenerator, func: &ast::Function) -> ir::Body { statements: Vec::new(), locals: HashMap::new(), ret_local: None, + ctx }; // store args ret if let Some(ret_type) = func.return_type.as_ref() { - let ty = lower_type(gen, ret_type); + let ty = lower_type(&mut builder.ctx, ret_type); let local = Local { mutable: false, @@ -99,7 +122,7 @@ fn lower_function(gen: &mut IdGenerator, func: &ast::Function) -> ir::Body { } for arg in &func.params { - let ty = lower_type(gen, &arg.arg_type); + let ty = lower_type(&mut builder.ctx, &arg.arg_type); let local = Local { mutable: false, span: Some(arg.span), @@ -114,26 +137,27 @@ fn lower_function(gen: &mut IdGenerator, func: &ast::Function) -> ir::Body { for stmt in &func.body.body { match stmt { - ast::Statement::Let(info) => lower_let(gen, &mut builder, info), - ast::Statement::Assign(_) => todo!(), + ast::Statement::Let(info) => lower_let(&mut builder, info), + ast::Statement::Assign(info) => lower_assign(&mut builder, info), ast::Statement::For(_) => todo!(), ast::Statement::While(_) => todo!(), ast::Statement::If(_) => todo!(), - ast::Statement::Return(info) => lower_return(gen, &mut builder, info), + ast::Statement::Return(info) => lower_return(&mut builder, info), ast::Statement::FnCall(_) => todo!(), } } - builder.body + (builder.body, builder.ctx) } -fn lower_let(gen: &mut IdGenerator, builder: &mut BodyBuilder, info: &ast::LetStmt) { - let rvalue = lower_expr(builder, &info.value, Some(&lower_type(gen, &info.r#type))); +fn lower_let(builder: &mut BodyBuilder, info: &ast::LetStmt) { + let ty = lower_type(&mut builder.ctx, &info.r#type); + let rvalue = lower_expr(builder, &info.value, Some(&ty)); let local = ir::Local { mutable: info.is_mut, span: Some(info.span), - ty: lower_type(gen, &info.r#type), + ty: lower_type(&mut builder.ctx, &info.r#type), kind: ir::LocalKind::Temp, }; @@ -157,6 +181,18 @@ fn lower_let(gen: &mut IdGenerator, builder: &mut BodyBuilder, info: &ast::LetSt }); } +fn lower_assign(builder: &mut BodyBuilder, info: &ast::AssignStmt) { + let local = *builder.locals.get(&info.name.first.name).unwrap(); + let ty = builder.body.locals[local].ty.clone(); + let rvalue = lower_expr(builder, &info.value, Some(&ty)); + let place = lower_path(builder, &info.name); + + builder.statements.push(Statement { + span: Some(info.span), + kind: ir::StatementKind::Assign(place, rvalue) + }) +} + fn lower_expr( builder: &mut BodyBuilder, info: &ast::Expression, @@ -264,7 +300,7 @@ fn lower_value( } } -fn lower_return(gen: &mut IdGenerator, builder: &mut BodyBuilder, info: &ast::ReturnStmt) { +fn lower_return(builder: &mut BodyBuilder, info: &ast::ReturnStmt) { let ret_type = builder.body.ret_type.clone(); if let Some(value) = &info.value { let rvalue = lower_expr(builder, value, ret_type.as_ref()); @@ -303,7 +339,7 @@ fn lower_path(builder: &mut BodyBuilder, info: &ast::PathExpr) -> ir::Place { } } -pub fn lower_type(gen: &mut IdGenerator, t: &ast::Type) -> ir::TypeInfo { +pub fn lower_type(gen: &mut BuildCtx, t: &ast::Type) -> ir::TypeInfo { match t.name.name.as_str() { "u8" => ir::TypeInfo { span: Some(t.span), diff --git a/programs/simple.ed b/programs/simple.ed index 535da7143..dbb5594c9 100644 --- a/programs/simple.ed +++ b/programs/simple.ed @@ -1,7 +1,8 @@ mod Main { - fn main() -> i32 { - let x: i32 = 2; + fn main(argc: i32) -> i32 { + let mut x: i32 = 2; + x = 4; return x; } }