#[macro_use]
use crate::stdlib::*;
#[derive(Debug)]
struct TupleAccessElement {
out: Value,
}
impl MechFunctionImpl for TupleAccessElement {
fn solve(&self) {
()
}
fn out(&self) -> Value { self.out.clone() }
fn to_string(&self) -> String { format!("{:#?}", self) }
}
#[cfg(feature = "compiler")]
impl MechFunctionCompiler for TupleAccessElement {
fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
let mut registers = [0];
registers[0] = compile_register!(self.out, ctx);
ctx.features.insert(FeatureFlag::Builtin(FeatureKind::Tuple));
ctx.features.insert(FeatureFlag::Builtin(FeatureKind::Access));
ctx.emit_nullop(
hash_str(stringify!("TupleAccessElement")),
registers[0],
);
return Ok(registers[0]);
}
}
pub struct TupleAccess {}
impl NativeFunctionCompiler for TupleAccess{
fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
if arguments.len() < 2 {
return Err(MechError::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
}
let ix1 = &arguments[1];
let src = &arguments[0];
match (src.clone(),ix1.clone()) {
(Value::Tuple(tpl), Value::Index(ix)) => {
let tpl_brrw = tpl.borrow();
let ix_brrw = ix.borrow();
if *ix_brrw > tpl_brrw.elements.len() || *ix_brrw < 1 {
return Err(MechError::new(
TupleIndexOutOfBoundsError { ix: *ix_brrw, len: tpl_brrw.elements.len() },
None
).with_compiler_loc());
}
let element = tpl_brrw.elements[*ix_brrw - 1].clone();
let new_fxn = TupleAccessElement{ out: *element };
Ok(Box::new(new_fxn))
},
(Value::MutableReference(tpl), Value::Index(ix)) => {
match &*tpl.borrow() {
Value::Tuple(tpl) => {
let ix_brrw = ix.borrow();
let tpl_brrw = tpl.borrow();
if *ix_brrw > tpl_brrw.elements.len() || *ix_brrw < 1 {
return Err(MechError::new(
TupleIndexOutOfBoundsError { ix: *ix_brrw, len: tpl_brrw.elements.len() },
None
).with_compiler_loc());
}
let element = tpl_brrw.elements[*ix_brrw - 1].clone();
let new_fxn = TupleAccessElement{ out: *element };
Ok(Box::new(new_fxn))
},
_ => Err(MechError::new(
UnhandledFunctionArgumentKind2 { arg: (src.kind(), ix1.kind()), fxn_name: "access/tuple-element".to_string() },
None
).with_compiler_loc()
),
}
},
_ => todo!(),
}
}
}