First pass getting loadReagent support into the compiler with optimizations
This commit is contained in:
2
rust_compiler/Cargo.lock
generated
2
rust_compiler/Cargo.lock
generated
@@ -930,7 +930,7 @@ checksum = "e3a9fe34e3e7a50316060351f37187a3f546bce95496156754b601a5fa71b76e"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "slang"
|
name = "slang"
|
||||||
version = "0.3.2"
|
version = "0.3.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"anyhow",
|
"anyhow",
|
||||||
"clap",
|
"clap",
|
||||||
|
|||||||
@@ -208,3 +208,29 @@ fn test_set_slot() -> anyhow::Result<()> {
|
|||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_load_reagent() -> anyhow::Result<()> {
|
||||||
|
let compiled = compile! {
|
||||||
|
debug
|
||||||
|
r#"
|
||||||
|
device thingy = "d0";
|
||||||
|
|
||||||
|
let something = lr(thingy, "Contents", hash("Iron"));
|
||||||
|
"#
|
||||||
|
};
|
||||||
|
|
||||||
|
assert_eq!(
|
||||||
|
compiled,
|
||||||
|
indoc! {
|
||||||
|
"
|
||||||
|
j main
|
||||||
|
main:
|
||||||
|
lr r15 d0 Contents -666742878
|
||||||
|
move r8 r15
|
||||||
|
"
|
||||||
|
}
|
||||||
|
);
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|||||||
@@ -2296,6 +2296,48 @@ impl<'a> Compiler<'a> {
|
|||||||
|
|
||||||
Ok(None)
|
Ok(None)
|
||||||
}
|
}
|
||||||
|
System::LoadReagent(device, reagent_mode, reagent_hash) => {
|
||||||
|
let Spanned {
|
||||||
|
node: LiteralOrVariable::Variable(device_spanned),
|
||||||
|
..
|
||||||
|
} = device
|
||||||
|
else {
|
||||||
|
return Err(Error::AgrumentMismatch(
|
||||||
|
"Arg1 expected to be a variable".into(),
|
||||||
|
span,
|
||||||
|
));
|
||||||
|
};
|
||||||
|
|
||||||
|
let (device, device_cleanup) = self.compile_literal_or_variable(
|
||||||
|
LiteralOrVariable::Variable(device_spanned),
|
||||||
|
scope,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let (reagent_mode, reagent_cleanup) = self.compile_literal_or_variable(
|
||||||
|
LiteralOrVariable::Literal(reagent_mode.node),
|
||||||
|
scope,
|
||||||
|
)?;
|
||||||
|
|
||||||
|
let (reagent_hash, reagent_hash_cleanup) =
|
||||||
|
self.compile_operand(*reagent_hash, scope)?;
|
||||||
|
|
||||||
|
self.write_instruction(
|
||||||
|
Instruction::LoadReagent(
|
||||||
|
Operand::Register(VariableScope::RETURN_REGISTER),
|
||||||
|
device,
|
||||||
|
reagent_mode,
|
||||||
|
reagent_hash,
|
||||||
|
),
|
||||||
|
Some(span),
|
||||||
|
)?;
|
||||||
|
|
||||||
|
cleanup!(reagent_cleanup, reagent_hash_cleanup, device_cleanup);
|
||||||
|
|
||||||
|
Ok(Some(CompileLocation {
|
||||||
|
location: VariableLocation::Persistant(VariableScope::RETURN_REGISTER),
|
||||||
|
temp_name: None,
|
||||||
|
}))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ macro_rules! with_syscalls {
|
|||||||
"loadBatched",
|
"loadBatched",
|
||||||
"loadBatchedNamed",
|
"loadBatchedNamed",
|
||||||
"loadSlot",
|
"loadSlot",
|
||||||
|
"loadReagent",
|
||||||
"set",
|
"set",
|
||||||
"setBatched",
|
"setBatched",
|
||||||
"setBatchedNamed",
|
"setBatchedNamed",
|
||||||
@@ -35,6 +36,7 @@ macro_rules! with_syscalls {
|
|||||||
"lb",
|
"lb",
|
||||||
"lbn",
|
"lbn",
|
||||||
"ls",
|
"ls",
|
||||||
|
"lr",
|
||||||
"s",
|
"s",
|
||||||
"sb",
|
"sb",
|
||||||
"sbn",
|
"sbn",
|
||||||
|
|||||||
@@ -191,6 +191,9 @@ pub enum Instruction<'a> {
|
|||||||
/// `sbn deviceHash nameHash type value` - Set Batch Named
|
/// `sbn deviceHash nameHash type value` - Set Batch Named
|
||||||
StoreBatchNamed(Operand<'a>, Operand<'a>, Operand<'a>, Operand<'a>),
|
StoreBatchNamed(Operand<'a>, Operand<'a>, Operand<'a>, Operand<'a>),
|
||||||
|
|
||||||
|
/// `lr register device reagentMode int`
|
||||||
|
LoadReagent(Operand<'a>, Operand<'a>, Operand<'a>, Operand<'a>),
|
||||||
|
|
||||||
/// `j label` - Unconditional Jump
|
/// `j label` - Unconditional Jump
|
||||||
Jump(Operand<'a>),
|
Jump(Operand<'a>),
|
||||||
/// `jal label` - Jump and Link (Function Call)
|
/// `jal label` - Jump and Link (Function Call)
|
||||||
@@ -311,6 +314,9 @@ impl<'a> fmt::Display for Instruction<'a> {
|
|||||||
Instruction::StoreBatchNamed(d_hash, n_hash, typ, val) => {
|
Instruction::StoreBatchNamed(d_hash, n_hash, typ, val) => {
|
||||||
write!(f, "sbn {} {} {} {}", d_hash, n_hash, typ, val)
|
write!(f, "sbn {} {} {} {}", d_hash, n_hash, typ, val)
|
||||||
}
|
}
|
||||||
|
Instruction::LoadReagent(reg, device, reagent_mode, reagent_hash) => {
|
||||||
|
write!(f, "lr {} {} {} {}", reg, device, reagent_mode, reagent_hash)
|
||||||
|
}
|
||||||
Instruction::Jump(lbl) => write!(f, "j {}", lbl),
|
Instruction::Jump(lbl) => write!(f, "j {}", lbl),
|
||||||
Instruction::JumpAndLink(lbl) => write!(f, "jal {}", lbl),
|
Instruction::JumpAndLink(lbl) => write!(f, "jal {}", lbl),
|
||||||
Instruction::JumpRelative(off) => write!(f, "jr {}", off),
|
Instruction::JumpRelative(off) => write!(f, "jr {}", off),
|
||||||
|
|||||||
@@ -565,6 +565,7 @@ fn get_destination_reg(instr: &Instruction) -> Option<u8> {
|
|||||||
| Instruction::Sqrt(Operand::Register(r), _)
|
| Instruction::Sqrt(Operand::Register(r), _)
|
||||||
| Instruction::Tan(Operand::Register(r), _)
|
| Instruction::Tan(Operand::Register(r), _)
|
||||||
| Instruction::Trunc(Operand::Register(r), _)
|
| Instruction::Trunc(Operand::Register(r), _)
|
||||||
|
| Instruction::LoadReagent(Operand::Register(r), _, _, _)
|
||||||
| Instruction::Pop(Operand::Register(r)) => Some(*r),
|
| Instruction::Pop(Operand::Register(r)) => Some(*r),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
@@ -595,6 +596,9 @@ fn set_destination_reg<'a>(instr: &Instruction<'a>, new_reg: u8) -> Option<Instr
|
|||||||
c.clone(),
|
c.clone(),
|
||||||
d.clone(),
|
d.clone(),
|
||||||
)),
|
)),
|
||||||
|
Instruction::LoadReagent(_, b, c, d) => {
|
||||||
|
Some(Instruction::LoadReagent(r, b.clone(), c.clone(), d.clone()))
|
||||||
|
}
|
||||||
Instruction::SetEq(_, a, b) => Some(Instruction::SetEq(r, a.clone(), b.clone())),
|
Instruction::SetEq(_, a, b) => Some(Instruction::SetEq(r, a.clone(), b.clone())),
|
||||||
Instruction::SetNe(_, a, b) => Some(Instruction::SetNe(r, a.clone(), b.clone())),
|
Instruction::SetNe(_, a, b) => Some(Instruction::SetNe(r, a.clone(), b.clone())),
|
||||||
Instruction::SetGt(_, a, b) => Some(Instruction::SetGt(r, a.clone(), b.clone())),
|
Instruction::SetGt(_, a, b) => Some(Instruction::SetGt(r, a.clone(), b.clone())),
|
||||||
|
|||||||
@@ -1909,6 +1909,20 @@ impl<'a> Parser<'a> {
|
|||||||
Box::new(expr),
|
Box::new(expr),
|
||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
|
"loadReagent" | "lr" => {
|
||||||
|
let mut args = args!(3);
|
||||||
|
let next = args.next();
|
||||||
|
let device = literal_or_variable!(next);
|
||||||
|
let next = args.next();
|
||||||
|
let reagent_mode = get_arg!(Literal, literal_or_variable!(next));
|
||||||
|
let reagent_hash = args.next().ok_or(Error::UnexpectedEOF)?;
|
||||||
|
|
||||||
|
Ok(SysCall::System(System::LoadReagent(
|
||||||
|
device,
|
||||||
|
reagent_mode,
|
||||||
|
Box::new(reagent_hash),
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
|
||||||
// Math SysCalls
|
// Math SysCalls
|
||||||
"acos" => {
|
"acos" => {
|
||||||
|
|||||||
@@ -237,6 +237,18 @@ documented! {
|
|||||||
Spanned<Literal<'a>>,
|
Spanned<Literal<'a>>,
|
||||||
Spanned<Literal<'a>>,
|
Spanned<Literal<'a>>,
|
||||||
Box<Spanned<Expression<'a>>>
|
Box<Spanned<Expression<'a>>>
|
||||||
|
),
|
||||||
|
/// Loads reagent of device's ReagentMode where a hash of the reagent type to check for
|
||||||
|
///
|
||||||
|
/// ## IC10
|
||||||
|
/// `lr r? device(d?|r?|id) reagentMode int`
|
||||||
|
/// ## Slang
|
||||||
|
/// `let result = loadReagent(deviceHash, "ReagentMode", reagentHash);`
|
||||||
|
/// `let result = lr(deviceHash, "ReagentMode", reagentHash);`
|
||||||
|
LoadReagent(
|
||||||
|
Spanned<LiteralOrVariable<'a>>,
|
||||||
|
Spanned<Literal<'a>>,
|
||||||
|
Box<Spanned<Expression<'a>>>
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -261,6 +273,7 @@ impl<'a> std::fmt::Display for System<'a> {
|
|||||||
}
|
}
|
||||||
System::LoadSlot(a, b, c) => write!(f, "loadSlot({}, {}, {})", a, b, c),
|
System::LoadSlot(a, b, c) => write!(f, "loadSlot({}, {}, {})", a, b, c),
|
||||||
System::SetSlot(a, b, c, d) => write!(f, "setSlot({}, {}, {}, {})", a, b, c, d),
|
System::SetSlot(a, b, c, d) => write!(f, "setSlot({}, {}, {}, {})", a, b, c, d),
|
||||||
|
System::LoadReagent(a, b, c) => write!(f, "loadReagent({}, {}, {})", a, b, c),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user