mirror of
https://github.com/edg-l/edlang.git
synced 2024-11-23 00:18:24 +00:00
p
This commit is contained in:
parent
167a7cf001
commit
37e083e2a7
|
@ -1,5 +1,6 @@
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
use ast::Function;
|
||||||
use edlang_ast as ast;
|
use edlang_ast as ast;
|
||||||
use edlang_ir as ir;
|
use edlang_ir as ir;
|
||||||
use ir::{DefId, Local, Operand, Place, Statement, TypeInfo};
|
use ir::{DefId, Local, Operand, Place, Statement, TypeInfo};
|
||||||
|
@ -32,6 +33,12 @@ impl IdGenerator {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct BuildCtx {
|
||||||
|
pub func_ids: HashMap<String, DefId>,
|
||||||
|
pub functions: HashMap<DefId, Function>,
|
||||||
|
pub gen: IdGenerator,
|
||||||
|
}
|
||||||
|
|
||||||
pub fn lower_module(gen: &mut IdGenerator, module: &ast::Module) -> ir::ModuleBody {
|
pub fn lower_module(gen: &mut IdGenerator, module: &ast::Module) -> ir::ModuleBody {
|
||||||
let mut body = ir::ModuleBody {
|
let mut body = ir::ModuleBody {
|
||||||
module_id: gen.next_id(),
|
module_id: gen.next_id(),
|
||||||
|
@ -40,13 +47,27 @@ pub fn lower_module(gen: &mut IdGenerator, module: &ast::Module) -> ir::ModuleBo
|
||||||
span: module.span,
|
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 {
|
for stmt in &module.contents {
|
||||||
match stmt {
|
match stmt {
|
||||||
ast::ModuleStatement::Function(func) => {
|
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);
|
body.functions.insert(res.def_id, res);
|
||||||
|
ctx = new_ctx;
|
||||||
}
|
}
|
||||||
ast::ModuleStatement::Constant(_) => todo!(),
|
ast::ModuleStatement::Constant(_) => todo!(),
|
||||||
ast::ModuleStatement::Struct(_) => todo!(),
|
ast::ModuleStatement::Struct(_) => todo!(),
|
||||||
|
@ -62,12 +83,13 @@ struct BodyBuilder {
|
||||||
pub statements: Vec<ir::Statement>,
|
pub statements: Vec<ir::Statement>,
|
||||||
pub locals: HashMap<String, usize>,
|
pub locals: HashMap<String, usize>,
|
||||||
pub ret_local: Option<usize>,
|
pub ret_local: Option<usize>,
|
||||||
|
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 {
|
let body = ir::Body {
|
||||||
def_id: gen.next_defid(),
|
def_id: *ctx.func_ids.get(&func.name.name).unwrap(),
|
||||||
ret_type: func.return_type.as_ref().map(|x| lower_type(gen, x)),
|
ret_type: func.return_type.as_ref().map(|x| lower_type(&mut ctx, x)),
|
||||||
locals: Default::default(),
|
locals: Default::default(),
|
||||||
blocks: Default::default(),
|
blocks: Default::default(),
|
||||||
fn_span: func.span,
|
fn_span: func.span,
|
||||||
|
@ -80,12 +102,13 @@ fn lower_function(gen: &mut IdGenerator, func: &ast::Function) -> ir::Body {
|
||||||
statements: Vec::new(),
|
statements: Vec::new(),
|
||||||
locals: HashMap::new(),
|
locals: HashMap::new(),
|
||||||
ret_local: None,
|
ret_local: None,
|
||||||
|
ctx
|
||||||
};
|
};
|
||||||
|
|
||||||
// store args ret
|
// store args ret
|
||||||
|
|
||||||
if let Some(ret_type) = func.return_type.as_ref() {
|
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 {
|
let local = Local {
|
||||||
mutable: false,
|
mutable: false,
|
||||||
|
@ -99,7 +122,7 @@ fn lower_function(gen: &mut IdGenerator, func: &ast::Function) -> ir::Body {
|
||||||
}
|
}
|
||||||
|
|
||||||
for arg in &func.params {
|
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 {
|
let local = Local {
|
||||||
mutable: false,
|
mutable: false,
|
||||||
span: Some(arg.span),
|
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 {
|
for stmt in &func.body.body {
|
||||||
match stmt {
|
match stmt {
|
||||||
ast::Statement::Let(info) => lower_let(gen, &mut builder, info),
|
ast::Statement::Let(info) => lower_let(&mut builder, info),
|
||||||
ast::Statement::Assign(_) => todo!(),
|
ast::Statement::Assign(info) => lower_assign(&mut builder, info),
|
||||||
ast::Statement::For(_) => todo!(),
|
ast::Statement::For(_) => todo!(),
|
||||||
ast::Statement::While(_) => todo!(),
|
ast::Statement::While(_) => todo!(),
|
||||||
ast::Statement::If(_) => 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!(),
|
ast::Statement::FnCall(_) => todo!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
builder.body
|
(builder.body, builder.ctx)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn lower_let(gen: &mut IdGenerator, builder: &mut BodyBuilder, info: &ast::LetStmt) {
|
fn lower_let(builder: &mut BodyBuilder, info: &ast::LetStmt) {
|
||||||
let rvalue = lower_expr(builder, &info.value, Some(&lower_type(gen, &info.r#type)));
|
let ty = lower_type(&mut builder.ctx, &info.r#type);
|
||||||
|
let rvalue = lower_expr(builder, &info.value, Some(&ty));
|
||||||
|
|
||||||
let local = ir::Local {
|
let local = ir::Local {
|
||||||
mutable: info.is_mut,
|
mutable: info.is_mut,
|
||||||
span: Some(info.span),
|
span: Some(info.span),
|
||||||
ty: lower_type(gen, &info.r#type),
|
ty: lower_type(&mut builder.ctx, &info.r#type),
|
||||||
kind: ir::LocalKind::Temp,
|
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(
|
fn lower_expr(
|
||||||
builder: &mut BodyBuilder,
|
builder: &mut BodyBuilder,
|
||||||
info: &ast::Expression,
|
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();
|
let ret_type = builder.body.ret_type.clone();
|
||||||
if let Some(value) = &info.value {
|
if let Some(value) = &info.value {
|
||||||
let rvalue = lower_expr(builder, value, ret_type.as_ref());
|
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() {
|
match t.name.name.as_str() {
|
||||||
"u8" => ir::TypeInfo {
|
"u8" => ir::TypeInfo {
|
||||||
span: Some(t.span),
|
span: Some(t.span),
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
mod Main {
|
mod Main {
|
||||||
|
|
||||||
fn main() -> i32 {
|
fn main(argc: i32) -> i32 {
|
||||||
let x: i32 = 2;
|
let mut x: i32 = 2;
|
||||||
|
x = 4;
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue