mech_interpreter/stdlib/access/
record.rs

1#[macro_use]
2use crate::stdlib::*;
3
4// Record Access --------------------------------------------------------------
5
6#[derive(Debug)]
7pub struct RecordAccessField {
8  pub source: Value,
9}
10impl MechFunctionImpl for RecordAccessField {
11  fn solve(&self) {
12    ()
13  }
14  fn out(&self) -> Value { self.source.clone() }
15  fn to_string(&self) -> String { format!("{:#?}", self) }
16}
17#[cfg(feature = "compiler")]
18impl MechFunctionCompiler for RecordAccessField {
19  fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
20    let mut registers = [0];
21
22    registers[0] = compile_register!(self.source, ctx);
23
24    ctx.features.insert(FeatureFlag::Builtin(FeatureKind::Access));
25
26    ctx.emit_nullop(
27      hash_str("RecordAccessField"),
28      registers[0],
29    );
30
31    return Ok(registers[0]);
32  }
33}
34
35pub fn impl_access_record_fxn(source: Value, key: Value) -> MResult<Box<dyn MechFunction>> {
36  match (source,key) {
37    (Value::Record(rcd), Value::Id(id)) => {
38      let k = id;
39      match rcd.borrow().get(&k) {
40        Some(value) => Ok(Box::new(RecordAccessField{source: value.clone()})),
41        None => Err(MechError2::new(
42            UndefinedRecordFieldError { id: k.clone() },
43            None
44          ).with_compiler_loc()),
45      }
46    }
47    (source,key) => return Err(MechError2::new(
48        UnhandledFunctionArgumentKind2 { arg: (source.kind(), key.kind()), fxn_name: "RecordAccess".to_string() },
49        None
50      ).with_compiler_loc()
51    ),
52  }
53}
54
55pub struct RecordAccess {}
56impl NativeFunctionCompiler for RecordAccess {
57  fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
58    if arguments.len() != 2 {
59      return Err(MechError2::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
60    }
61    let key = &arguments[1];
62    let src = &arguments[0];
63    match impl_access_record_fxn(src.clone(), key.clone()) {
64      Ok(fxn) => Ok(fxn),
65      Err(_) => {
66        match src {
67          Value::MutableReference(rcrd) => { impl_access_record_fxn(rcrd.borrow().clone(), key.clone()) },
68          x => Err(MechError2::new(
69              UnhandledFunctionArgumentKind2 { arg: (src.kind(), key.kind()), fxn_name: "RecordAccess".to_string() },
70              None
71            ).with_compiler_loc()
72          ),
73        }
74      }
75    }
76  }
77}
78
79
80#[derive(Debug)]
81pub struct RecordAccessSwizzle {
82  pub source: Value,
83}
84
85impl MechFunctionImpl for RecordAccessSwizzle {
86  fn solve(&self) {
87    ()
88  }
89  fn out(&self) -> Value { self.source.clone() }
90  fn to_string(&self) -> String { format!("{:#?}", self) }
91}
92#[cfg(feature = "compiler")]
93impl MechFunctionCompiler for RecordAccessSwizzle {
94  fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
95    let mut registers = [0];
96
97    registers[0] = compile_register!(self.source, ctx);
98
99    ctx.features.insert(FeatureFlag::Builtin(FeatureKind::Swizzle));
100
101    ctx.emit_nullop(
102      hash_str("RecordAccessSwizzle"),
103      registers[0],
104    );
105
106    return Ok(registers[0]);
107  }
108}