This commit is contained in:
2025-03-17 11:12:25 -07:00
parent b7f72e7ea4
commit 0f7dd6fb1c
2 changed files with 52 additions and 56 deletions

View File

@@ -104,8 +104,8 @@ impl<'a> Compiler<'a> {
} }
fn write_output(&mut self, output: impl Into<String>) -> Result<(), CompileError> { fn write_output(&mut self, output: impl Into<String>) -> Result<(), CompileError> {
self.output.write(output.into().as_bytes())?; self.output.write_all(output.into().as_bytes())?;
self.output.write(b"\n")?; self.output.write_all(b"\n")?;
self.current_line += 1; self.current_line += 1;
Ok(()) Ok(())
@@ -206,7 +206,7 @@ impl<'a> Compiler<'a> {
compiler.push_stack(&format!("{op}ExpressionLeft"))?; compiler.push_stack(&format!("{op}ExpressionLeft"))?;
} }
Expression::Variable(var_name) => { Expression::Variable(var_name) => {
let var_offset = compiler.get_variable_index(&var_name)?; let var_offset = compiler.get_variable_index(&var_name)? + 1;
compiler.write_output(format!("sub r15 sp {var_offset}"))?; compiler.write_output(format!("sub r15 sp {var_offset}"))?;
compiler.write_output("get r15 db r15")?; compiler.write_output("get r15 db r15")?;
compiler.write_output("push r15")?; compiler.write_output("push r15")?;
@@ -232,7 +232,7 @@ impl<'a> Compiler<'a> {
compiler.push_stack(&format!("{op}ExpressionRight"))?; compiler.push_stack(&format!("{op}ExpressionRight"))?;
} }
Expression::Variable(var_name) => { Expression::Variable(var_name) => {
let var_offset = compiler.get_variable_index(&var_name)?; let var_offset = compiler.get_variable_index(&var_name)? + 1;
compiler.write_output(format!("sub r15 sp {}", var_offset))?; compiler.write_output(format!("sub r15 sp {}", var_offset))?;
compiler.write_output("get r15 db r15")?; compiler.write_output("get r15 db r15")?;
compiler.write_output("push r15")?; compiler.write_output("push r15")?;
@@ -283,18 +283,16 @@ impl<'a> Compiler<'a> {
fn invocation_expression(&mut self, expr: InvocationExpression) -> Result<(), CompileError> { fn invocation_expression(&mut self, expr: InvocationExpression) -> Result<(), CompileError> {
let function_name = expr.name; let function_name = expr.name;
let function_line = self let function_line = *self
.function_locations .function_locations
.get(&function_name) .get(&function_name)
.ok_or(CompileError::MissingFunction(function_name.clone()))? .ok_or(CompileError::MissingFunction(function_name.clone()))?;
.clone();
let mut to_write = String::new(); let mut to_write = String::new();
self.push_stack(&format!("{function_name}ReturnAddress"))?; self.push_stack(&format!("{function_name}ReturnAddress"))?;
let mut iter_index = 0; for (iter_index, arg) in expr.arguments.into_iter().enumerate() {
for arg in expr.arguments {
match arg { match arg {
Expression::Literal(Literal::Number(num)) => { Expression::Literal(Literal::Number(num)) => {
to_write.push_str(&format!("push {}\n", num)); to_write.push_str(&format!("push {}\n", num));
@@ -313,14 +311,12 @@ impl<'a> Compiler<'a> {
_ => todo!("something is up with the arguments"), _ => todo!("something is up with the arguments"),
} }
self.push_stack(&format!("{function_name}Invocation{iter_index}"))?; self.push_stack(&format!("{function_name}Invocation{iter_index}"))?;
iter_index += 1;
} }
// push the return address onto the stack. Current + to write + pushing the return address // push the return address onto the stack. Current + to write + pushing the return address
let return_addr = self.current_line + to_write.lines().count() + 2; let return_addr = self.current_line + to_write.lines().count() + 2;
self.write_output(format!("push {return_addr}"))?; self.write_output(format!("push {return_addr}"))?;
self.output.write(to_write.as_bytes())?; self.output.write_all(to_write.as_bytes())?;
self.current_line = return_addr - 1; self.current_line = return_addr - 1;
self.write_output(format!("j {function_line}"))?; self.write_output(format!("j {function_line}"))?;
@@ -336,7 +332,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.iter().rev() { for arg in expression.arguments.iter().rev() {
self.push_stack(&arg)?; self.push_stack(arg)?;
} }
for expr in expression.body.0 { for expr in expression.body.0 {

View File

@@ -342,7 +342,7 @@ impl Parser {
// build the expressions and operators vectors // build the expressions and operators vectors
while token_matches!(current_token, TokenType::Symbol(s) if s.is_operator()) { while token_matches!(current_token, TokenType::Symbol(s) if s.is_operator()) {
// We are guaranteed to have an operator symbol here as we checked in the while loop // We are guaranteed to have an operator symbol here as we checked in the while loop
let operator = extract_token_data!(current_token, TokenType::Symbol(ref s), s.clone()); let operator = extract_token_data!(current_token, TokenType::Symbol(s), s);
operators.push(operator); operators.push(operator);
self.assign_next()?; self.assign_next()?;
expressions.push(self.get_binary_child_node()?); expressions.push(self.get_binary_child_node()?);
@@ -613,8 +613,8 @@ impl Parser {
fn literal(&mut self) -> Result<Literal, ParseError> { fn literal(&mut self) -> Result<Literal, ParseError> {
let current_token = token_from_option!(self.current_token); let current_token = token_from_option!(self.current_token);
let literal = match current_token.token_type { let literal = match current_token.token_type {
TokenType::Number(ref num) => Literal::Number(num.clone()), TokenType::Number(num) => Literal::Number(num),
TokenType::String(ref string) => Literal::String(string.clone()), TokenType::String(string) => Literal::String(string),
_ => return Err(ParseError::UnexpectedToken(current_token.clone())), _ => return Err(ParseError::UnexpectedToken(current_token.clone())),
}; };
@@ -741,15 +741,15 @@ impl Parser {
match invocation.name.as_str() { match invocation.name.as_str() {
// system calls // system calls
"yield" => return Ok(SysCall::System(sys_call::System::Yield)), "yield" => Ok(SysCall::System(sys_call::System::Yield)),
"sleep" => { "sleep" => {
check_length(self, &invocation.arguments, 1)?; check_length(self, &invocation.arguments, 1)?;
let mut arg = invocation.arguments.iter(); let mut arg = invocation.arguments.iter();
let argument = literal_or_variable!(arg.next()); let argument = literal_or_variable!(arg.next());
return Ok(SysCall::System(sys_call::System::Sleep(argument))); Ok(SysCall::System(sys_call::System::Sleep(argument)))
} }
"loadFromDevice" => { "loadFromDevice" => {
check_length(&self, &invocation.arguments, 2)?; check_length(self, &invocation.arguments, 2)?;
let mut args = invocation.arguments.iter(); let mut args = invocation.arguments.iter();
let device = literal_or_variable!(args.next()); let device = literal_or_variable!(args.next());
@@ -760,13 +760,13 @@ impl Parser {
)); ));
}; };
return Ok(SysCall::System(sys_call::System::LoadFromDevice( Ok(SysCall::System(sys_call::System::LoadFromDevice(
device, device,
variable.clone(), variable.clone(),
))); )))
} }
"setOnDevice" => { "setOnDevice" => {
check_length(&self, &invocation.arguments, 3)?; check_length(self, &invocation.arguments, 3)?;
let mut args = invocation.arguments.iter(); let mut args = invocation.arguments.iter();
let device = literal_or_variable!(args.next()); let device = literal_or_variable!(args.next());
@@ -781,95 +781,95 @@ impl Parser {
let variable = literal_or_variable!(args.next()); let variable = literal_or_variable!(args.next());
return Ok(SysCall::System(sys_call::System::SetOnDevice( Ok(SysCall::System(sys_call::System::SetOnDevice(
device, logic_type, variable, device, logic_type, variable,
))); )))
} }
// math calls // math calls
"acos" => { "acos" => {
check_length(&self, &invocation.arguments, 1)?; check_length(self, &invocation.arguments, 1)?;
let arg = literal_or_variable!(invocation.arguments.first()); let arg = literal_or_variable!(invocation.arguments.first());
return Ok(SysCall::Math(sys_call::Math::Acos(arg))); Ok(SysCall::Math(sys_call::Math::Acos(arg)))
} }
"asin" => { "asin" => {
check_length(&self, &invocation.arguments, 1)?; check_length(self, &invocation.arguments, 1)?;
let arg = literal_or_variable!(invocation.arguments.first()); let arg = literal_or_variable!(invocation.arguments.first());
return Ok(SysCall::Math(sys_call::Math::Asin(arg))); Ok(SysCall::Math(sys_call::Math::Asin(arg)))
} }
"atan" => { "atan" => {
check_length(&self, &invocation.arguments, 1)?; check_length(self, &invocation.arguments, 1)?;
let arg = literal_or_variable!(invocation.arguments.first()); let arg = literal_or_variable!(invocation.arguments.first());
return Ok(SysCall::Math(sys_call::Math::Atan(arg))); Ok(SysCall::Math(sys_call::Math::Atan(arg)))
} }
"atan2" => { "atan2" => {
check_length(&self, &invocation.arguments, 2)?; check_length(self, &invocation.arguments, 2)?;
let mut args = invocation.arguments.iter(); let mut args = invocation.arguments.iter();
let arg1 = literal_or_variable!(args.next()); let arg1 = literal_or_variable!(args.next());
let arg2 = literal_or_variable!(args.next()); let arg2 = literal_or_variable!(args.next());
return Ok(SysCall::Math(sys_call::Math::Atan2(arg1, arg2))); Ok(SysCall::Math(sys_call::Math::Atan2(arg1, arg2)))
} }
"abs" => { "abs" => {
check_length(&self, &invocation.arguments, 1)?; check_length(self, &invocation.arguments, 1)?;
let arg = literal_or_variable!(invocation.arguments.first()); let arg = literal_or_variable!(invocation.arguments.first());
return Ok(SysCall::Math(sys_call::Math::Abs(arg))); Ok(SysCall::Math(sys_call::Math::Abs(arg)))
} }
"ceil" => { "ceil" => {
check_length(&self, &invocation.arguments, 1)?; check_length(self, &invocation.arguments, 1)?;
let arg = literal_or_variable!(invocation.arguments.first()); let arg = literal_or_variable!(invocation.arguments.first());
return Ok(SysCall::Math(sys_call::Math::Ceil(arg))); Ok(SysCall::Math(sys_call::Math::Ceil(arg)))
} }
"cos" => { "cos" => {
check_length(&self, &invocation.arguments, 1)?; check_length(self, &invocation.arguments, 1)?;
let arg = literal_or_variable!(invocation.arguments.first()); let arg = literal_or_variable!(invocation.arguments.first());
return Ok(SysCall::Math(sys_call::Math::Cos(arg))); Ok(SysCall::Math(sys_call::Math::Cos(arg)))
} }
"floor" => { "floor" => {
check_length(&self, &invocation.arguments, 1)?; check_length(self, &invocation.arguments, 1)?;
let arg = literal_or_variable!(invocation.arguments.first()); let arg = literal_or_variable!(invocation.arguments.first());
return Ok(SysCall::Math(sys_call::Math::Floor(arg))); Ok(SysCall::Math(sys_call::Math::Floor(arg)))
} }
"log" => { "log" => {
check_length(&self, &invocation.arguments, 1)?; check_length(self, &invocation.arguments, 1)?;
let arg = literal_or_variable!(invocation.arguments.first()); let arg = literal_or_variable!(invocation.arguments.first());
return Ok(SysCall::Math(sys_call::Math::Log(arg))); Ok(SysCall::Math(sys_call::Math::Log(arg)))
} }
"max" => { "max" => {
check_length(&self, &invocation.arguments, 2)?; check_length(self, &invocation.arguments, 2)?;
let mut args = invocation.arguments.iter(); let mut args = invocation.arguments.iter();
let arg1 = literal_or_variable!(args.next()); let arg1 = literal_or_variable!(args.next());
let arg2 = literal_or_variable!(args.next()); let arg2 = literal_or_variable!(args.next());
return Ok(SysCall::Math(sys_call::Math::Max(arg1, arg2))); Ok(SysCall::Math(sys_call::Math::Max(arg1, arg2)))
} }
"min" => { "min" => {
check_length(&self, &invocation.arguments, 2)?; check_length(self, &invocation.arguments, 2)?;
let mut args = invocation.arguments.iter(); let mut args = invocation.arguments.iter();
let arg1 = literal_or_variable!(args.next()); let arg1 = literal_or_variable!(args.next());
let arg2 = literal_or_variable!(args.next()); let arg2 = literal_or_variable!(args.next());
return Ok(SysCall::Math(sys_call::Math::Min(arg1, arg2))); Ok(SysCall::Math(sys_call::Math::Min(arg1, arg2)))
} }
"rand" => { "rand" => {
check_length(&self, &invocation.arguments, 0)?; check_length(self, &invocation.arguments, 0)?;
return Ok(SysCall::Math(sys_call::Math::Rand)); Ok(SysCall::Math(sys_call::Math::Rand))
} }
"sin" => { "sin" => {
check_length(&self, &invocation.arguments, 1)?; check_length(self, &invocation.arguments, 1)?;
let arg = literal_or_variable!(invocation.arguments.first()); let arg = literal_or_variable!(invocation.arguments.first());
return Ok(SysCall::Math(sys_call::Math::Sin(arg))); Ok(SysCall::Math(sys_call::Math::Sin(arg)))
} }
"sqrt" => { "sqrt" => {
check_length(&self, &invocation.arguments, 1)?; check_length(self, &invocation.arguments, 1)?;
let arg = literal_or_variable!(invocation.arguments.first()); let arg = literal_or_variable!(invocation.arguments.first());
return Ok(SysCall::Math(sys_call::Math::Sqrt(arg))); Ok(SysCall::Math(sys_call::Math::Sqrt(arg)))
} }
"tan" => { "tan" => {
check_length(&self, &invocation.arguments, 1)?; check_length(self, &invocation.arguments, 1)?;
let arg = literal_or_variable!(invocation.arguments.first()); let arg = literal_or_variable!(invocation.arguments.first());
return Ok(SysCall::Math(sys_call::Math::Tan(arg))); Ok(SysCall::Math(sys_call::Math::Tan(arg)))
} }
"trunc" => { "trunc" => {
check_length(&self, &invocation.arguments, 1)?; check_length(self, &invocation.arguments, 1)?;
let arg = literal_or_variable!(invocation.arguments.first()); let arg = literal_or_variable!(invocation.arguments.first());
return Ok(SysCall::Math(sys_call::Math::Trunc(arg))); Ok(SysCall::Math(sys_call::Math::Trunc(arg)))
} }
_ => todo!(), _ => todo!(),
} }