diff --git a/output.stationeers b/output.stationeers deleted file mode 100644 index e96b76f..0000000 --- a/output.stationeers +++ /dev/null @@ -1,20 +0,0 @@ -j main -sub sp sp 3 -pop ra -j ra -push 9 -push 1 -push 2 -push 3 -j 1 -sub sp sp 0 -pop ra -j ra -push 14 -j 4 -sub sp sp 0 -pop ra -j ra -main: -push 20 -j 12 diff --git a/src/compiler/mod.rs b/src/compiler/mod.rs index 17609b1..292eb61 100644 --- a/src/compiler/mod.rs +++ b/src/compiler/mod.rs @@ -1,12 +1,9 @@ use crate::parser::tree_node::*; use crate::parser::Parser as ASTParser; use std::cmp::Ordering; -use std::collections::{HashMap, VecDeque}; +use std::collections::HashMap; use std::io::{BufWriter, Write}; -/// Represents the return keyword. Used as a variable name for the register. -const RETURN: &'static str = "ret"; - quick_error! { #[derive(Debug)] pub enum CompileError { @@ -39,8 +36,6 @@ pub struct Compiler<'a> { variable_scope: Vec>, function_locations: HashMap, output: &'a mut BufWriter>, - /// A map of variable names to register numbers. 0-15 are reserved for variables, 16 is the stack pointer, 17 is the return address - register: VecDeque, current_line: usize, declared_main: bool, } @@ -52,7 +47,6 @@ impl<'a> Compiler<'a> { variable_scope: Vec::new(), function_locations: HashMap::new(), output: writer, - register: VecDeque::new(), current_line: 0, declared_main: false, } @@ -113,7 +107,7 @@ impl<'a> Compiler<'a> { }; // Jump directly to the main block. This will avoid executing functions before the main block. - self.write_output(format!("j main"))?; + self.write_output("j main")?; self.expression(ast)?; Ok(()) @@ -125,14 +119,104 @@ impl<'a> Compiler<'a> { Expression::BlockExpression(expr) => self.block_expression(expr)?, Expression::InvocationExpression(expr) => self.invocation_expression(expr)?, Expression::BinaryExpression(expr) => self.binary_expression(expr)?, + Expression::DeclarationExpression(var_name, expr) => { + self.declaration_expression(&var_name, *expr)? + } _ => todo!("{:?}", expression), }; Ok(()) } + fn declaration_expression( + &mut self, + var_name: &str, + expr: Expression, + ) -> Result<(), CompileError> { + match expr { + Expression::Literal(Literal::Number(num)) => { + self.push_stack(var_name)?; + self.write_output(format!("push {num}"))?; + } + Expression::BinaryExpression(expr) => { + self.binary_expression(expr)?; + self.push_stack(var_name)?; + } + _ => todo!(), + } + + Ok(()) + } + fn binary_expression(&mut self, expr: BinaryExpression) -> Result<(), CompileError> { - todo!() + self.variable_scope.push(HashMap::new()); + + fn perform_operation( + compiler: &mut Compiler, + op: &str, + left: Expression, + right: Expression, + ) -> Result<(), CompileError> { + match left { + Expression::Literal(Literal::Number(num)) => { + compiler.write_output(format!("push {num}"))?; + } + Expression::Variable(var_name) => { + let var_offset = compiler.get_variable_index(&var_name)?; + compiler.write_output(format!("sub sp sp {var_offset}"))?; + compiler.write_output("peek r0")?; + compiler.write_output(format!("add sp sp {var_offset}"))?; + compiler.write_output("push r0")?; + } + Expression::BinaryExpression(expr) => { + compiler.binary_expression(expr)?; + } + _ => todo!(), + }; + + match right { + Expression::Literal(Literal::Number(num)) => { + compiler.write_output(format!("push {num}"))?; + } + Expression::Variable(var_name) => { + let var_offset = compiler.get_variable_index(&var_name)?; + compiler.write_output(format!("sub sp sp {}", var_offset + 1))?; + compiler.write_output("peek r0")?; + compiler.write_output(format!("add sp sp {}", var_offset + 1))?; + compiler.write_output("push r0")?; + } + Expression::BinaryExpression(expr) => { + compiler.binary_expression(expr)?; + } + _ => todo!(), + }; + + compiler.write_output("pop r1")?; + compiler.write_output("pop r0")?; + compiler.write_output(format!("{op} r0 r0 r1"))?; + compiler.write_output("push r0")?; + + Ok(()) + } + + match expr { + BinaryExpression::Add(left, right) => { + perform_operation(self, "add", *left, *right)?; + } + BinaryExpression::Subtract(left, right) => { + perform_operation(self, "sub", *left, *right)?; + } + BinaryExpression::Multiply(left, right) => { + perform_operation(self, "mul", *left, *right)?; + } + BinaryExpression::Divide(left, right) => { + perform_operation(self, "div", *left, *right)?; + } + _ => todo!("Operation not currently supported"), + } + self.variable_scope.pop(); + + Ok(()) } fn invocation_expression(&mut self, expr: InvocationExpression) -> Result<(), CompileError> { @@ -154,16 +238,19 @@ impl<'a> Compiler<'a> { } Expression::Variable(var_name) => { let index = self.get_variable_index(&var_name)?; - to_write.push_str(&format!("sub r0 sp {index}\n")); - to_write.push_str("get r0 db r0\n"); + + to_write.push_str(&format!("sub sp sp {index}\n")); + to_write.push_str("peek r0\n"); + to_write.push_str(&format!("add sp sp {index}\n")); to_write.push_str("push r0\n"); - self.push_stack(&format!("{function_name}{iter_index}"))?; } Expression::BinaryExpression(expr) => { self.binary_expression(expr)?; + to_write.push_str("push r0\n"); } _ => todo!("something is up with the arguments"), } + self.push_stack(&format!("{function_name}{iter_index}"))?; iter_index += 1; } @@ -186,7 +273,7 @@ impl<'a> Compiler<'a> { self.function_locations.insert(func_name, self.current_line); - for arg in expression.arguments { + for arg in expression.arguments.iter().rev() { self.push_stack(&arg)?; } diff --git a/tests/file.stlg b/tests/file.stlg index d1a863f..1036d0e 100644 --- a/tests/file.stlg +++ b/tests/file.stlg @@ -1,13 +1,8 @@ -fn test(a, b, c) { - +fn doStuff(x, y, z) { + let i = x + y + z; }; -fn test2() { - test(1, 2, 3); -}; +let i = 25; +let j = i + 25; -fn test3() { - test2(); -}; - -test3(); \ No newline at end of file +doStuff(i, j, 100); \ No newline at end of file