untested compiled Math syscalls

This commit is contained in:
2025-12-06 22:28:39 -07:00
parent ab7b36ac22
commit 19d6679229
3 changed files with 208 additions and 1 deletions

View File

@@ -0,0 +1,8 @@
use crate::compile;
use anyhow::Result;
use indoc::indoc;
use pretty_assertions::assert_eq;
fn test_acos() -> Result<()> {
todo!()
}

View File

@@ -47,4 +47,5 @@ mod declaration_literal;
mod function_declaration; mod function_declaration;
mod logic_expression; mod logic_expression;
mod loops; mod loops;
mod math_syscall;
mod syscall; mod syscall;

View File

@@ -3,7 +3,7 @@ use crate::variable_manager::{self, LocationRequest, VariableLocation, VariableS
use helpers::prelude::*; use helpers::prelude::*;
use parser::{ use parser::{
Parser as ASTParser, Parser as ASTParser,
sys_call::{SysCall, System}, sys_call::{Math, SysCall, System},
tree_node::{ tree_node::{
AssignmentExpression, BinaryExpression, BlockExpression, ConstDeclarationExpression, AssignmentExpression, BinaryExpression, BlockExpression, ConstDeclarationExpression,
DeviceDeclarationExpression, Expression, FunctionExpression, IfExpression, DeviceDeclarationExpression, Expression, FunctionExpression, IfExpression,
@@ -266,6 +266,10 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
node: SysCall::System(system), node: SysCall::System(system),
span, span,
}) => self.expression_syscall_system(system, span, scope), }) => self.expression_syscall_system(system, span, scope),
Expression::Syscall(Spanned {
node: SysCall::Math(math),
..
}) => self.expression_syscall_math(math, scope),
Expression::While(expr_while) => { Expression::While(expr_while) => {
self.expression_while(expr_while.node, scope)?; self.expression_while(expr_while.node, scope)?;
Ok(None) Ok(None)
@@ -1893,6 +1897,200 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
} }
} }
fn expression_syscall_math<'v>(
&mut self,
expr: Math,
scope: &mut VariableScope<'v>,
) -> Result<Option<CompilationResult>, Error> {
macro_rules! cleanup {
($($to_clean:expr),*) => {
$(
if let Some(to_clean) = $to_clean {
scope.free_temp(to_clean, None)?;
}
)*
};
}
match expr {
Math::Acos(expr) => {
let (var, cleanup) = self.compile_operand(*expr, scope)?;
self.write_output(format!("acos r{} {}", VariableScope::RETURN_REGISTER, var))?;
cleanup!(cleanup);
Ok(Some(CompilationResult {
location: VariableLocation::Persistant(VariableScope::RETURN_REGISTER),
temp_name: None,
}))
}
Math::Asin(expr) => {
let (var, cleanup) = self.compile_operand(*expr, scope)?;
self.write_output(format!("asin r{} {}", VariableScope::RETURN_REGISTER, var))?;
cleanup!(cleanup);
Ok(Some(CompilationResult {
location: VariableLocation::Persistant(VariableScope::RETURN_REGISTER),
temp_name: None,
}))
}
Math::Atan(expr) => {
let (var, cleanup) = self.compile_operand(*expr, scope)?;
self.write_output(format!("atan r{} {}", VariableScope::RETURN_REGISTER, var))?;
cleanup!(cleanup);
Ok(Some(CompilationResult {
location: VariableLocation::Persistant(VariableScope::RETURN_REGISTER),
temp_name: None,
}))
}
Math::Atan2(expr1, expr2) => {
let (var1, var1_cleanup) = self.compile_operand(*expr1, scope)?;
let (var2, var2_cleanup) = self.compile_operand(*expr2, scope)?;
self.write_output(format!(
"atan2 r{} {} {}",
VariableScope::RETURN_REGISTER,
var1,
var2
))?;
cleanup!(var1_cleanup, var2_cleanup);
Ok(Some(CompilationResult {
location: VariableLocation::Persistant(VariableScope::RETURN_REGISTER),
temp_name: None,
}))
}
Math::Abs(expr) => {
let (var, cleanup) = self.compile_operand(*expr, scope)?;
self.write_output(format!("abs r{} {}", VariableScope::RETURN_REGISTER, var))?;
cleanup!(cleanup);
Ok(Some(CompilationResult {
location: VariableLocation::Persistant(VariableScope::RETURN_REGISTER),
temp_name: None,
}))
}
Math::Ceil(expr) => {
let (var, cleanup) = self.compile_operand(*expr, scope)?;
self.write_output(format!("ceil r{} {}", VariableScope::RETURN_REGISTER, var))?;
cleanup!(cleanup);
Ok(Some(CompilationResult {
location: VariableLocation::Persistant(VariableScope::RETURN_REGISTER),
temp_name: None,
}))
}
Math::Cos(expr) => {
let (var, cleanup) = self.compile_operand(*expr, scope)?;
self.write_output(format!("cos r{} {}", VariableScope::RETURN_REGISTER, var))?;
cleanup!(cleanup);
Ok(Some(CompilationResult {
location: VariableLocation::Persistant(VariableScope::RETURN_REGISTER),
temp_name: None,
}))
}
Math::Floor(expr) => {
let (var, cleanup) = self.compile_operand(*expr, scope)?;
self.write_output(format!("floor r{} {}", VariableScope::RETURN_REGISTER, var))?;
cleanup!(cleanup);
Ok(Some(CompilationResult {
location: VariableLocation::Persistant(VariableScope::RETURN_REGISTER),
temp_name: None,
}))
}
Math::Log(expr) => {
let (var, cleanup) = self.compile_operand(*expr, scope)?;
self.write_output(format!("log r{} {}", VariableScope::RETURN_REGISTER, var))?;
cleanup!(cleanup);
Ok(Some(CompilationResult {
location: VariableLocation::Persistant(VariableScope::RETURN_REGISTER),
temp_name: None,
}))
}
Math::Max(expr1, expr2) => {
let (var1, clean1) = self.compile_operand(*expr1, scope)?;
let (var2, clean2) = self.compile_operand(*expr2, scope)?;
self.write_output(format!(
"max r{} {} {}",
VariableScope::RETURN_REGISTER,
var1,
var2
))?;
cleanup!(clean1, clean2);
Ok(Some(CompilationResult {
location: VariableLocation::Persistant(VariableScope::RETURN_REGISTER),
temp_name: None,
}))
}
Math::Min(expr1, expr2) => {
let (var1, clean1) = self.compile_operand(*expr1, scope)?;
let (var2, clean2) = self.compile_operand(*expr2, scope)?;
self.write_output(format!(
"min r{} {} {}",
VariableScope::RETURN_REGISTER,
var1,
var2
))?;
cleanup!(clean1, clean2);
Ok(Some(CompilationResult {
location: VariableLocation::Persistant(VariableScope::RETURN_REGISTER),
temp_name: None,
}))
}
Math::Rand => {
self.write_output(format!("rand r{}", VariableScope::RETURN_REGISTER))?;
Ok(Some(CompilationResult {
location: VariableLocation::Persistant(VariableScope::RETURN_REGISTER),
temp_name: None,
}))
}
Math::Sin(expr) => {
let (var, clean) = self.compile_operand(*expr, scope)?;
self.write_output(format!("sin r{} {}", VariableScope::RETURN_REGISTER, var))?;
cleanup!(clean);
Ok(Some(CompilationResult {
location: VariableLocation::Persistant(VariableScope::RETURN_REGISTER),
temp_name: None,
}))
}
Math::Sqrt(expr) => {
let (var, clean) = self.compile_operand(*expr, scope)?;
self.write_output(format!("sqrt r{} {}", VariableScope::RETURN_REGISTER, var))?;
cleanup!(clean);
Ok(Some(CompilationResult {
location: VariableLocation::Persistant(VariableScope::RETURN_REGISTER),
temp_name: None,
}))
}
Math::Tan(expr) => {
let (var, clean) = self.compile_operand(*expr, scope)?;
self.write_output(format!("tan r{} {}", VariableScope::RETURN_REGISTER, var))?;
cleanup!(clean);
Ok(Some(CompilationResult {
location: VariableLocation::Persistant(VariableScope::RETURN_REGISTER),
temp_name: None,
}))
}
Math::Trunc(expr) => {
let (var, clean) = self.compile_operand(*expr, scope)?;
self.write_output(format!("trunc r{} {}", VariableScope::RETURN_REGISTER, var))?;
cleanup!(clean);
Ok(Some(CompilationResult {
location: VariableLocation::Persistant(VariableScope::RETURN_REGISTER),
temp_name: None,
}))
}
}
}
/// Compile a function declaration. /// Compile a function declaration.
/// Calees are responsible for backing up any registers they wish to use. /// Calees are responsible for backing up any registers they wish to use.
fn expression_function<'v>( fn expression_function<'v>(