Found bug, unable to do an assignment expression with a syscall

This commit is contained in:
2025-12-09 23:45:10 -07:00
parent f19801d4e6
commit b21d6cc73e
8 changed files with 270 additions and 51 deletions

View File

@@ -243,6 +243,22 @@ fn test_max() -> Result<()> {
Ok(())
}
// #[test]
fn test_max_from_game() -> Result<()> {
let compiled = compile! {
result
r#"
let item = 0;
item = max(1, 2);
"#
};
println!("{compiled:?}");
assert!(compiled.is_empty());
Ok(())
}
#[test]
fn test_min() -> Result<()> {
let compiled = compile! {

View File

@@ -157,3 +157,54 @@ fn test_load_from_device() -> anyhow::Result<()> {
Ok(())
}
#[test]
fn test_load_from_slot() -> anyhow::Result<()> {
let compiled = compile! {
debug
r#"
device airCon = "d0";
let setting = ls(airCon, 0, "Occupied");
"#
};
assert_eq!(
compiled,
indoc! {
"
j main
main:
ls r15 d0 0 Occupied
move r8 r15 #setting
"
}
);
Ok(())
}
#[test]
fn test_set_slot() -> anyhow::Result<()> {
let compiled = compile! {
debug
r#"
device airCon = "d0";
ss(airCon, 0, "Occupied", true);
"#
};
assert_eq!(
compiled,
indoc! {
"
j main
main:
ss d0 0 Occupied 1
"
}
);
Ok(())
}

View File

@@ -865,6 +865,7 @@ impl<'a, 'w, W: std::io::Write> Compiler<'a, 'w, W> {
scope.free_temp(c, None)?;
}
}
_ => {
return Err(Error::Unknown(
"Invalid assignment target. Only variables and member access are supported."
@@ -1952,6 +1953,55 @@ impl<'a, 'w, W: std::io::Write> Compiler<'a, 'w, W> {
temp_name: None,
}))
}
System::LoadSlot(dev_name, slot_index, logic_type) => {
let (dev_hash, hash_cleanup) =
self.compile_literal_or_variable(dev_name.node, scope)?;
let (slot_index, slot_cleanup) = self.compile_literal_or_variable(
LiteralOrVariable::Literal(slot_index.node),
scope,
)?;
let (logic_type, logic_cleanup) = self.compile_literal_or_variable(
LiteralOrVariable::Literal(logic_type.node),
scope,
)?;
self.write_output(format!(
"ls r{} {} {} {}",
VariableScope::RETURN_REGISTER,
dev_hash,
slot_index,
logic_type
))?;
cleanup!(hash_cleanup, slot_cleanup, logic_cleanup);
Ok(Some(CompilationResult {
location: VariableLocation::Persistant(VariableScope::RETURN_REGISTER),
temp_name: None,
}))
}
System::SetSlot(dev_name, slot_index, logic_type, var) => {
let (dev_name, name_cleanup) =
self.compile_literal_or_variable(dev_name.node, scope)?;
let (slot_index, index_cleanup) = self.compile_literal_or_variable(
LiteralOrVariable::Literal(slot_index.node),
scope,
)?;
let (logic_type, type_cleanup) = self.compile_literal_or_variable(
LiteralOrVariable::Literal(logic_type.node),
scope,
)?;
let (var, var_cleanup) = self.compile_operand(*var, scope)?;
self.write_output(format!(
"ss {} {} {} {}",
dev_name, slot_index, logic_type, var
))?;
cleanup!(name_cleanup, index_cleanup, type_cleanup, var_cleanup);
Ok(None)
}
}
}

View File

@@ -52,7 +52,7 @@ pub enum LocationRequest {
Stack,
}
#[derive(Clone)]
#[derive(Clone, Debug)]
pub enum VariableLocation<'a> {
/// Represents a temporary register (r1 - r7)
Temporary(u8),
@@ -66,7 +66,6 @@ pub enum VariableLocation<'a> {
Device(Cow<'a, str>),
}
// FIX: Added 'b lifetime for the parent reference
pub struct VariableScope<'a, 'b> {
temporary_vars: VecDeque<u8>,
persistant_vars: VecDeque<u8>,
@@ -75,7 +74,6 @@ pub struct VariableScope<'a, 'b> {
parent: Option<&'b VariableScope<'a, 'b>>,
}
// FIX: Updated Default impl to include 'b
impl<'a, 'b> Default for VariableScope<'a, 'b> {
fn default() -> Self {
Self {
@@ -88,7 +86,6 @@ impl<'a, 'b> Default for VariableScope<'a, 'b> {
}
}
// FIX: Updated impl block to include 'b
impl<'a, 'b> VariableScope<'a, 'b> {
#[allow(dead_code)]
pub const TEMP_REGISTER_COUNT: u8 = 7;
@@ -112,7 +109,6 @@ impl<'a, 'b> VariableScope<'a, 'b> {
})
}
// FIX: parent is now &'b VariableScope<'a, 'b>
pub fn scoped(parent: &'b VariableScope<'a, 'b>) -> Self {
Self {
parent: Option::Some(parent),