mech_interpreter/stdlib/access/
tuple.rs1#[macro_use]
2use crate::stdlib::*;
3
4#[derive(Debug)]
7struct TupleAccessElement {
8 out: Value,
9}
10
11impl MechFunctionImpl for TupleAccessElement {
12 fn solve(&self) {
13 ()
14 }
15 fn out(&self) -> Value { self.out.clone() }
16 fn to_string(&self) -> String { format!("{:#?}", self) }
17}
18#[cfg(feature = "compiler")]
19impl MechFunctionCompiler for TupleAccessElement {
20 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
21 let mut registers = [0];
22 registers[0] = compile_register!(self.out, ctx);
23 ctx.features.insert(FeatureFlag::Builtin(FeatureKind::Tuple));
24 ctx.features.insert(FeatureFlag::Builtin(FeatureKind::Access));
25 ctx.emit_nullop(
26 hash_str(stringify!("TupleAccessElement")),
27 registers[0],
28 );
29 return Ok(registers[0]);
30 }
31}
32
33pub struct TupleAccess {}
34impl NativeFunctionCompiler for TupleAccess{
35 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
36 if arguments.len() < 2 {
37 return Err(MechError2::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
38 }
39 let ix1 = &arguments[1];
40 let src = &arguments[0];
41 match (src.clone(),ix1.clone()) {
42 (Value::Tuple(tpl), Value::Index(ix)) => {
43 let tpl_brrw = tpl.borrow();
44 let ix_brrw = ix.borrow();
45 if *ix_brrw > tpl_brrw.elements.len() || *ix_brrw < 1 {
46 return Err(MechError2::new(
47 TupleIndexOutOfBoundsError { ix: *ix_brrw, len: tpl_brrw.elements.len() },
48 None
49 ).with_compiler_loc());
50 }
51 let element = tpl_brrw.elements[*ix_brrw - 1].clone();
52 let new_fxn = TupleAccessElement{ out: *element };
53 Ok(Box::new(new_fxn))
54 },
55 (Value::MutableReference(tpl), Value::Index(ix)) => {
56 match &*tpl.borrow() {
57 Value::Tuple(ref tpl) => {
58 let ix_brrw = ix.borrow();
59 let tpl_brrw = tpl.borrow();
60 if *ix_brrw > tpl_brrw.elements.len() || *ix_brrw < 1 {
61 return Err(MechError2::new(
62 TupleIndexOutOfBoundsError { ix: *ix_brrw, len: tpl_brrw.elements.len() },
63 None
64 ).with_compiler_loc());
65 }
66 let element = tpl_brrw.elements[*ix_brrw - 1].clone();
67 let new_fxn = TupleAccessElement{ out: *element };
68 Ok(Box::new(new_fxn))
69 },
70 _ => Err(MechError2::new(
71 UnhandledFunctionArgumentKind2 { arg: (src.kind(), ix1.kind()), fxn_name: "access/tuple-element".to_string() },
72 None
73 ).with_compiler_loc()
74 ),
75 }
76 },
77 _ => todo!(),
78 }
79 }
80}