mech_interpreter/stdlib/access/
map.rs1#[macro_use]
2use crate::stdlib::*;
3
4#[derive(Debug)]
5pub struct MapAccessField {
6 pub out: Value,
7 pub source: Ref<MechMap>,
8}
9
10impl MechFunctionImpl for MapAccessField {
11 fn solve(&self) {
12 ()
13 }
14 fn out(&self) -> Value {self.out.clone()}
15 fn to_string(&self) -> String {format!("{:#?}", self)}
16}
17#[cfg(feature = "compiler")]
18impl MechFunctionCompiler for MapAccessField {
19 fn compile(&self, ctx: &mut CompileCtx) -> MResult<Register> {
20 let mut registers = [0, 0];
21 registers[0] = compile_register!(self.out, ctx);
22 registers[1] = compile_register_brrw!(self.source, ctx);
23 ctx.features.insert(FeatureFlag::Builtin(FeatureKind::Access));
24 ctx.emit_unop(
25 hash_str("MapAccessField"),
26 registers[0],
27 registers[1],
28 );
29 return Ok(registers[0]);
30 }
31 }
32
33pub fn impl_access_map_fxn(source: Value, key: Value) -> MResult<Box<dyn MechFunction>> {
34 match (source, key) {
35
36 (Value::Map(map), key) => {
37 let map_ref = map.borrow();
38
39 match map_ref.map.get(&key) {
40 Some(value) => Ok(Box::new(MapAccessField {
41 out: value.clone(),
42 source: map.clone(),
43 })),
44 None => Err(MechError2::new(
45 UndefinedMapKeyError { key: key.to_string() },
46 None,
47 ).with_compiler_loc()),
48 }
49 }
50
51 (source, key) => Err(MechError2::new(
52 UnhandledFunctionArgumentKind2 {
53 arg: (source.kind(), key.kind()),
54 fxn_name: "MapAccess".to_string(),
55 },
56 None,
57 ).with_compiler_loc()),
58 }
59}
60
61pub struct MapAccess {}
62
63impl NativeFunctionCompiler for MapAccess {
64 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
65 if arguments.len() != 2 {
66 return Err(MechError2::new(
67 IncorrectNumberOfArguments {
68 expected: 2,
69 found: arguments.len(),
70 },
71 None,
72 ).with_compiler_loc());
73 }
74
75 let src = &arguments[0];
76 let key = &arguments[1];
77
78 match src.kind().deref_kind() {
80 #[cfg(feature = "map")]
81 ValueKind::Map(key_kind, _) => {
82 if key.kind() != *key_kind {
83 return Err(MechError2::new(
84 UnhandledFunctionArgumentKind2 { arg: (src.kind(), key.kind()), fxn_name: "MapAccess".to_string() },
85 None,
86 ).with_compiler_loc());
87 }
88 }
89 _ => unreachable!(),
90 };
91
92 match impl_access_map_fxn(src.clone(), key.clone()) {
93 Ok(fxn) => Ok(fxn),
94 Err(_) => {
95 match src {
96 Value::MutableReference(map) => {
97 impl_access_map_fxn(map.borrow().clone(), key.clone())
98 }
99 _ => Err(MechError2::new(
100 UnhandledFunctionArgumentKind2 {
101 arg: (src.kind(), key.kind()),
102 fxn_name: "MapAccess".to_string(),
103 },
104 None,
105 ).with_compiler_loc()),
106 }
107 }
108 }
109 }
110}
111
112#[derive(Debug, Clone)]
113pub struct UndefinedMapKeyError {
114 pub key: String,
115}
116
117impl MechErrorKind2 for UndefinedMapKeyError {
118 fn name(&self) -> &str {
119 "UndefinedMapKey"
120 }
121 fn message(&self) -> String {
122 format!("Key id `{}` not found in key_index.", self.key)
123 }
124}