loadFromDevice working

This commit is contained in:
2025-11-25 18:35:00 -07:00
parent 96645cbff3
commit 40c6b0f3e7
2 changed files with 72 additions and 22 deletions

View File

@@ -81,3 +81,29 @@ fn test_set_on_device() -> anyhow::Result<()> {
Ok(()) Ok(())
} }
#[test]
fn test_load_from_device() -> anyhow::Result<()> {
let compiled = compile! {
debug
r#"
device airCon = "d0";
let setting = loadFromDevice(airCon, "On");
"#
};
assert_eq!(
compiled,
indoc! {
"
j main
main:
l r15 d0 On
move r8 r15 #setting
"
}
);
Ok(())
}

View File

@@ -154,11 +154,7 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
Ok(None) Ok(None)
} }
Expression::Syscall(SysCall::System(system_syscall)) => { Expression::Syscall(SysCall::System(system_syscall)) => {
let res = self.expression_syscall_system(system_syscall, scope)?; self.expression_syscall_system(system_syscall, scope)
Ok(res.map(|l| CompilationResult {
location: l,
temp_name: None,
}))
} }
Expression::While(expr_while) => { Expression::While(expr_while) => {
self.expression_while(expr_while, scope)?; self.expression_while(expr_while, scope)?;
@@ -177,11 +173,7 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
Ok(None) Ok(None)
} }
Expression::Declaration(var_name, expr) => { Expression::Declaration(var_name, expr) => {
let loc = self.expression_declaration(var_name, *expr, scope)?; self.expression_declaration(var_name, *expr, scope)
Ok(loc.map(|l| CompilationResult {
location: l,
temp_name: None,
}))
} }
Expression::Assignment(assign_expr) => { Expression::Assignment(assign_expr) => {
self.expression_assignment(assign_expr, scope)?; self.expression_assignment(assign_expr, scope)?;
@@ -292,23 +284,26 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
var_name: String, var_name: String,
expr: Expression, expr: Expression,
scope: &mut VariableScope<'v>, scope: &mut VariableScope<'v>,
) -> Result<Option<VariableLocation>, Error> { ) -> Result<Option<CompilationResult>, Error> {
// optimization. Check for a negated numeric literal // optimization. Check for a negated numeric literal
if let Expression::Negation(box_expr) = &expr if let Expression::Negation(box_expr) = &expr
&& let Expression::Literal(Literal::Number(neg_num)) = &**box_expr && let Expression::Literal(Literal::Number(neg_num)) = &**box_expr
{ {
let loc = scope.add_variable(&var_name, LocationRequest::Persist)?; let loc = scope.add_variable(&var_name, LocationRequest::Persist)?;
self.emit_variable_assignment(&var_name, &loc, format!("-{neg_num}"))?; self.emit_variable_assignment(&var_name, &loc, format!("-{neg_num}"))?;
return Ok(Some(loc)); return Ok(Some(CompilationResult {
location: loc,
temp_name: None,
}));
} }
let loc = match expr { let (loc, temp_name) = match expr {
Expression::Literal(Literal::Number(num)) => { Expression::Literal(Literal::Number(num)) => {
let var_location = let var_location =
scope.add_variable(var_name.clone(), LocationRequest::Persist)?; scope.add_variable(var_name.clone(), LocationRequest::Persist)?;
self.emit_variable_assignment(&var_name, &var_location, num)?; self.emit_variable_assignment(&var_name, &var_location, num)?;
var_location (var_location, None)
} }
Expression::Literal(Literal::Boolean(b)) => { Expression::Literal(Literal::Boolean(b)) => {
let val = if b { "1" } else { "0" }; let val = if b { "1" } else { "0" };
@@ -316,7 +311,7 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
scope.add_variable(var_name.clone(), LocationRequest::Persist)?; scope.add_variable(var_name.clone(), LocationRequest::Persist)?;
self.emit_variable_assignment(&var_name, &var_location, val)?; self.emit_variable_assignment(&var_name, &var_location, val)?;
var_location (var_location, None)
} }
Expression::Invocation(invoke_expr) => { Expression::Invocation(invoke_expr) => {
self.expression_function_invocation(invoke_expr, scope)?; self.expression_function_invocation(invoke_expr, scope)?;
@@ -327,7 +322,21 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
&loc, &loc,
format!("r{}", VariableScope::RETURN_REGISTER), format!("r{}", VariableScope::RETURN_REGISTER),
)?; )?;
loc (loc, None)
}
Expression::Syscall(SysCall::System(call)) => {
if self.expression_syscall_system(call, scope)?.is_none() {
return Err(Error::Unknown("SysCall did not return a value".into()));
};
let loc = scope.add_variable(&var_name, LocationRequest::Persist)?;
self.emit_variable_assignment(
&var_name,
&loc,
format!("r{}", VariableScope::RETURN_REGISTER),
)?;
(loc, None)
} }
// Support assigning binary expressions to variables directly // Support assigning binary expressions to variables directly
Expression::Binary(bin_expr) => { Expression::Binary(bin_expr) => {
@@ -342,7 +351,7 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
if let Some(name) = result.temp_name { if let Some(name) = result.temp_name {
scope.free_temp(name)?; scope.free_temp(name)?;
} }
var_loc (var_loc, None)
} }
Expression::Logical(log_expr) => { Expression::Logical(log_expr) => {
let result = self.expression_logical(log_expr, scope)?; let result = self.expression_logical(log_expr, scope)?;
@@ -356,7 +365,7 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
if let Some(name) = result.temp_name { if let Some(name) = result.temp_name {
scope.free_temp(name)?; scope.free_temp(name)?;
} }
var_loc (var_loc, None)
} }
Expression::Variable(name) => { Expression::Variable(name) => {
let src_loc = scope.get_location_of(&name)?; let src_loc = scope.get_location_of(&name)?;
@@ -380,7 +389,7 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
} }
}; };
self.emit_variable_assignment(&var_name, &var_loc, src_str)?; self.emit_variable_assignment(&var_name, &var_loc, src_str)?;
var_loc (var_loc, None)
} }
Expression::Priority(inner) => { Expression::Priority(inner) => {
return self.expression_declaration(var_name, *inner, scope); return self.expression_declaration(var_name, *inner, scope);
@@ -392,7 +401,10 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
} }
}; };
Ok(Some(loc)) Ok(Some(CompilationResult {
location: loc,
temp_name,
}))
} }
fn expression_assignment<'v>( fn expression_assignment<'v>(
@@ -998,11 +1010,13 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
Ok(VariableLocation::Persistant(VariableScope::RETURN_REGISTER)) Ok(VariableLocation::Persistant(VariableScope::RETURN_REGISTER))
} }
// syscalls that return values will be stored in the VariableScope::RETURN_REGISTER
// register
fn expression_syscall_system<'v>( fn expression_syscall_system<'v>(
&mut self, &mut self,
expr: System, expr: System,
scope: &mut VariableScope<'v>, scope: &mut VariableScope<'v>,
) -> Result<Option<VariableLocation>, Error> { ) -> Result<Option<CompilationResult>, Error> {
match expr { match expr {
System::Yield => { System::Yield => {
self.write_output("yield")?; self.write_output("yield")?;
@@ -1061,7 +1075,17 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
)); ));
}; };
todo!() self.write_output(format!(
"l r{} {} {}",
VariableScope::RETURN_REGISTER,
device,
logic_type
))?;
Ok(Some(CompilationResult {
location: VariableLocation::Temporary(VariableScope::RETURN_REGISTER),
temp_name: None,
}))
} }
_ => { _ => {