diff --git a/drimc_rs/src/ir_untyped.rs b/drimc_rs/src/ir_untyped.rs index 1e16848..17349d7 100644 --- a/drimc_rs/src/ir_untyped.rs +++ b/drimc_rs/src/ir_untyped.rs @@ -148,6 +148,7 @@ enum Location { /// Converts a program's abstract syntax tree into untyped IR code. pub fn ast_to_untyped_ir(ast: SyntaxTree) -> Program { let mut defs = vec![]; + let mut counter = 0; for stmt in ast.0.into_iter() { match stmt { syntax::Statement::TypeDefinition { @@ -169,7 +170,14 @@ pub fn ast_to_untyped_ir(ast: SyntaxTree) -> Program { arguments, definition, }) => { - todo!(); + defs.push(( + name, + convert_fn( + &mut counter, + arguments, + definition.expect("Empty functions unimplemented"), + ), + )); } syntax::Statement::ClassMember(syntax::ClassMember::TypeAlias { left: _, @@ -203,14 +211,21 @@ fn convert_fn( let arg_loc = temporary(counter); vec![ Instruction::DefLambda { - target: lambda_loc, - param: arg_loc, - body: todo!(), + target: lambda_loc.clone(), + param: arg_loc.clone(), + body: bind_pattern(counter, first, &arg_loc) + .into_iter() + .chain(convert_fn(counter, arguments, definition)) + .collect(), }, Instruction::Return { target: lambda_loc }, ] } else { - todo!() + let ret_loc = temporary(counter); + eval_expr(counter, definition, &ret_loc) + .into_iter() + .chain(std::iter::once(Instruction::Return { target: ret_loc })) + .collect() } } @@ -287,7 +302,19 @@ fn eval_expr(counter: &mut u64, e: syntax::Expr, l: &Location) -> Vec todo!(), syntax::Expr::DotSubscript { value, subscript } => todo!(), syntax::Expr::BracketSubscript { value, subscript } => todo!(), - syntax::Expr::Tuple(_) => todo!(), + syntax::Expr::Tuple(elems) => { + let elem_locs: Vec<_> = elems.iter().map(|_| temporary(counter)).collect(); + elems + .into_iter() + .zip(elem_locs.iter()) + .map(|(elem, elem_loc)| eval_expr(counter, elem, elem_loc)) + .flatten() + .chain(std::iter::once(Instruction::Collect { + target: l.to_owned(), + source: elem_locs.clone(), + })) + .collect() + } syntax::Expr::VariableReference(_) => todo!(), syntax::Expr::Literal(_) => todo!(), } diff --git a/drimc_rs/src/main.rs b/drimc_rs/src/main.rs index 8383065..5d47a25 100644 --- a/drimc_rs/src/main.rs +++ b/drimc_rs/src/main.rs @@ -5,7 +5,7 @@ use std::{error::Error, fmt::Display, process::exit, str::FromStr}; use clap::Parser; use drimc_rs::{ parser::{parser, ParserError, ParserMeta}, - typeck::typeck, + typeck::typeck, ir_untyped::ast_to_untyped_ir, }; /// Optimization levels. @@ -254,9 +254,9 @@ fn main() { let source = std::fs::read_to_string(&args.source_file)?; let meta = ParserMeta::default(); let ast = chumsky::Parser::parse(&parser(&meta), source).map_err(ParserError)?; - let ast = typeck(ast)?; + let untyped_ir = ast_to_untyped_ir(ast); - println!("{ast:?}"); + println!("{untyped_ir:#?}"); Ok(()) } diff --git a/drimc_rs/uir_test.drim b/drimc_rs/uir_test.drim new file mode 100644 index 0000000..b0539f3 --- /dev/null +++ b/drimc_rs/uir_test.drim @@ -0,0 +1,3 @@ +// IR Test + +def nul (a, b) = ();