wip
This commit is contained in:
@@ -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
|
|
||||||
@@ -1,12 +1,9 @@
|
|||||||
use crate::parser::tree_node::*;
|
use crate::parser::tree_node::*;
|
||||||
use crate::parser::Parser as ASTParser;
|
use crate::parser::Parser as ASTParser;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::collections::{HashMap, VecDeque};
|
use std::collections::HashMap;
|
||||||
use std::io::{BufWriter, Write};
|
use std::io::{BufWriter, Write};
|
||||||
|
|
||||||
/// Represents the return keyword. Used as a variable name for the register.
|
|
||||||
const RETURN: &'static str = "ret";
|
|
||||||
|
|
||||||
quick_error! {
|
quick_error! {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum CompileError {
|
pub enum CompileError {
|
||||||
@@ -39,8 +36,6 @@ pub struct Compiler<'a> {
|
|||||||
variable_scope: Vec<HashMap<String, i32>>,
|
variable_scope: Vec<HashMap<String, i32>>,
|
||||||
function_locations: HashMap<String, usize>,
|
function_locations: HashMap<String, usize>,
|
||||||
output: &'a mut BufWriter<Box<dyn Write>>,
|
output: &'a mut BufWriter<Box<dyn Write>>,
|
||||||
/// 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<u8>,
|
|
||||||
current_line: usize,
|
current_line: usize,
|
||||||
declared_main: bool,
|
declared_main: bool,
|
||||||
}
|
}
|
||||||
@@ -52,7 +47,6 @@ impl<'a> Compiler<'a> {
|
|||||||
variable_scope: Vec::new(),
|
variable_scope: Vec::new(),
|
||||||
function_locations: HashMap::new(),
|
function_locations: HashMap::new(),
|
||||||
output: writer,
|
output: writer,
|
||||||
register: VecDeque::new(),
|
|
||||||
current_line: 0,
|
current_line: 0,
|
||||||
declared_main: false,
|
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.
|
// 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)?;
|
self.expression(ast)?;
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -125,14 +119,104 @@ impl<'a> Compiler<'a> {
|
|||||||
Expression::BlockExpression(expr) => self.block_expression(expr)?,
|
Expression::BlockExpression(expr) => self.block_expression(expr)?,
|
||||||
Expression::InvocationExpression(expr) => self.invocation_expression(expr)?,
|
Expression::InvocationExpression(expr) => self.invocation_expression(expr)?,
|
||||||
Expression::BinaryExpression(expr) => self.binary_expression(expr)?,
|
Expression::BinaryExpression(expr) => self.binary_expression(expr)?,
|
||||||
|
Expression::DeclarationExpression(var_name, expr) => {
|
||||||
|
self.declaration_expression(&var_name, *expr)?
|
||||||
|
}
|
||||||
_ => todo!("{:?}", expression),
|
_ => todo!("{:?}", expression),
|
||||||
};
|
};
|
||||||
|
|
||||||
Ok(())
|
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> {
|
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> {
|
fn invocation_expression(&mut self, expr: InvocationExpression) -> Result<(), CompileError> {
|
||||||
@@ -154,16 +238,19 @@ impl<'a> Compiler<'a> {
|
|||||||
}
|
}
|
||||||
Expression::Variable(var_name) => {
|
Expression::Variable(var_name) => {
|
||||||
let index = self.get_variable_index(&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");
|
to_write.push_str("push r0\n");
|
||||||
self.push_stack(&format!("{function_name}{iter_index}"))?;
|
|
||||||
}
|
}
|
||||||
Expression::BinaryExpression(expr) => {
|
Expression::BinaryExpression(expr) => {
|
||||||
self.binary_expression(expr)?;
|
self.binary_expression(expr)?;
|
||||||
|
to_write.push_str("push r0\n");
|
||||||
}
|
}
|
||||||
_ => todo!("something is up with the arguments"),
|
_ => todo!("something is up with the arguments"),
|
||||||
}
|
}
|
||||||
|
self.push_stack(&format!("{function_name}{iter_index}"))?;
|
||||||
|
|
||||||
iter_index += 1;
|
iter_index += 1;
|
||||||
}
|
}
|
||||||
@@ -186,7 +273,7 @@ impl<'a> Compiler<'a> {
|
|||||||
|
|
||||||
self.function_locations.insert(func_name, self.current_line);
|
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)?;
|
self.push_stack(&arg)?;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,13 +1,8 @@
|
|||||||
fn test(a, b, c) {
|
fn doStuff(x, y, z) {
|
||||||
|
let i = x + y + z;
|
||||||
};
|
};
|
||||||
|
|
||||||
fn test2() {
|
let i = 25;
|
||||||
test(1, 2, 3);
|
let j = i + 25;
|
||||||
};
|
|
||||||
|
|
||||||
fn test3() {
|
doStuff(i, j, 100);
|
||||||
test2();
|
|
||||||
};
|
|
||||||
|
|
||||||
test3();
|
|
||||||
Reference in New Issue
Block a user