loadFromDevice working
This commit is contained in:
@@ -81,3 +81,29 @@ fn test_set_on_device() -> anyhow::Result<()> {
|
||||
|
||||
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(())
|
||||
}
|
||||
|
||||
@@ -154,11 +154,7 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
|
||||
Ok(None)
|
||||
}
|
||||
Expression::Syscall(SysCall::System(system_syscall)) => {
|
||||
let res = self.expression_syscall_system(system_syscall, scope)?;
|
||||
Ok(res.map(|l| CompilationResult {
|
||||
location: l,
|
||||
temp_name: None,
|
||||
}))
|
||||
self.expression_syscall_system(system_syscall, scope)
|
||||
}
|
||||
Expression::While(expr_while) => {
|
||||
self.expression_while(expr_while, scope)?;
|
||||
@@ -177,11 +173,7 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
|
||||
Ok(None)
|
||||
}
|
||||
Expression::Declaration(var_name, expr) => {
|
||||
let loc = self.expression_declaration(var_name, *expr, scope)?;
|
||||
Ok(loc.map(|l| CompilationResult {
|
||||
location: l,
|
||||
temp_name: None,
|
||||
}))
|
||||
self.expression_declaration(var_name, *expr, scope)
|
||||
}
|
||||
Expression::Assignment(assign_expr) => {
|
||||
self.expression_assignment(assign_expr, scope)?;
|
||||
@@ -292,23 +284,26 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
|
||||
var_name: String,
|
||||
expr: Expression,
|
||||
scope: &mut VariableScope<'v>,
|
||||
) -> Result<Option<VariableLocation>, Error> {
|
||||
) -> Result<Option<CompilationResult>, Error> {
|
||||
// optimization. Check for a negated numeric literal
|
||||
if let Expression::Negation(box_expr) = &expr
|
||||
&& let Expression::Literal(Literal::Number(neg_num)) = &**box_expr
|
||||
{
|
||||
let loc = scope.add_variable(&var_name, LocationRequest::Persist)?;
|
||||
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)) => {
|
||||
let var_location =
|
||||
scope.add_variable(var_name.clone(), LocationRequest::Persist)?;
|
||||
|
||||
self.emit_variable_assignment(&var_name, &var_location, num)?;
|
||||
var_location
|
||||
(var_location, None)
|
||||
}
|
||||
Expression::Literal(Literal::Boolean(b)) => {
|
||||
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)?;
|
||||
|
||||
self.emit_variable_assignment(&var_name, &var_location, val)?;
|
||||
var_location
|
||||
(var_location, None)
|
||||
}
|
||||
Expression::Invocation(invoke_expr) => {
|
||||
self.expression_function_invocation(invoke_expr, scope)?;
|
||||
@@ -327,7 +322,21 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
|
||||
&loc,
|
||||
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
|
||||
Expression::Binary(bin_expr) => {
|
||||
@@ -342,7 +351,7 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
|
||||
if let Some(name) = result.temp_name {
|
||||
scope.free_temp(name)?;
|
||||
}
|
||||
var_loc
|
||||
(var_loc, None)
|
||||
}
|
||||
Expression::Logical(log_expr) => {
|
||||
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 {
|
||||
scope.free_temp(name)?;
|
||||
}
|
||||
var_loc
|
||||
(var_loc, None)
|
||||
}
|
||||
Expression::Variable(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)?;
|
||||
var_loc
|
||||
(var_loc, None)
|
||||
}
|
||||
Expression::Priority(inner) => {
|
||||
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>(
|
||||
@@ -998,11 +1010,13 @@ impl<'a, W: std::io::Write> Compiler<'a, W> {
|
||||
Ok(VariableLocation::Persistant(VariableScope::RETURN_REGISTER))
|
||||
}
|
||||
|
||||
// syscalls that return values will be stored in the VariableScope::RETURN_REGISTER
|
||||
// register
|
||||
fn expression_syscall_system<'v>(
|
||||
&mut self,
|
||||
expr: System,
|
||||
scope: &mut VariableScope<'v>,
|
||||
) -> Result<Option<VariableLocation>, Error> {
|
||||
) -> Result<Option<CompilationResult>, Error> {
|
||||
match expr {
|
||||
System::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,
|
||||
}))
|
||||
}
|
||||
|
||||
_ => {
|
||||
|
||||
Reference in New Issue
Block a user