mech_interpreter/stdlib/access/
mod.rs1#[cfg(feature = "matrix")]
6pub mod matrix;
7#[cfg(feature = "record")]
8pub mod record;
9#[cfg(feature = "table")]
10pub mod table;
11#[cfg(feature = "tuple")]
12pub mod tuple;
13#[cfg(feature = "map")]
14pub mod map;
15
16#[cfg(feature = "matrix")]
17pub use self::matrix::*;
18#[cfg(feature = "record")]
19pub use self::record::*;
20#[cfg(feature = "table")]
21pub use self::table::*;
22#[cfg(feature = "tuple")]
23pub use self::tuple::*;
24#[cfg(feature = "map")]
25pub use self::map::*;
26
27#[macro_use]
28use crate::stdlib::*;
29
30pub struct AccessScalar {}
31impl NativeFunctionCompiler for AccessScalar {
32 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
33 if arguments.len() != 2 {
34 return Err(MechError2::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
35 }
36 let src = &arguments[0];
37 let index = &arguments[1];
38 match src.kind().deref_kind() {
39 #[cfg(feature = "matrix")]
40 ValueKind::Matrix(mat,_) => MatrixAccessScalar{}.compile(&arguments),
41 #[cfg(feature = "table")]
42 ValueKind::Table(tble,_) => TableAccessScalar{}.compile(&arguments),
43 #[cfg(feature = "map")]
44 ValueKind::Map(..) => MapAccess{}.compile(&arguments),
45 _ => Err(MechError2::new(UnhandledFunctionArgumentKind2 { arg: (src.kind(), index.kind()), fxn_name: "access/scalar".to_string() }, None).with_compiler_loc()),
46 }
47 }
48}
49
50pub struct AccessRange {}
51impl NativeFunctionCompiler for AccessRange {
52 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
53 if arguments.len() != 2 {
54 return Err(MechError2::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
55 }
56 let src = &arguments[0];
57 let index = &arguments[1];
58 match src.kind().deref_kind() {
59 #[cfg(feature = "matrix")]
60 ValueKind::Matrix(mat,_) => MatrixAccessRange{}.compile(&arguments),
61 #[cfg(feature = "table")]
62 ValueKind::Table(tble,_) => TableAccessRange{}.compile(&arguments),
63 _ => Err(MechError2::new(UnhandledFunctionArgumentKind2 { arg: (src.kind(), index.kind()), fxn_name: "access/range".to_string() }, None).with_compiler_loc()),
64 }
65 }
66}
67
68pub struct AccessSwizzle {}
69impl NativeFunctionCompiler for AccessSwizzle {
70 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
71 if arguments.len() < 3 {
72 return Err(MechError2::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
73 }
74 let keys = &arguments.clone().split_off(1);
75 let src = &arguments[0];
76 match src {
77 #[cfg(feature = "record")]
78 Value::Record(rcrd) => {
79 let mut values = vec![];
80 for key in keys {
81 let k = key.as_u64().unwrap().borrow().clone();
82 match rcrd.borrow().get(&k) {
83 Some(value) => values.push(value.clone()),
84 None => {
85 return Err(MechError2::new(
86 UndefinedRecordFieldError { id: k.clone() },
87 None
88 ).with_compiler_loc());
89 }
90 }
91 }
92 Ok(Box::new(RecordAccessSwizzle{source: Value::Tuple(Ref::new(MechTuple::from_vec(values)))}))
93 }
94 #[cfg(feature = "table")]
95 Value::Table(tbl) => {
96 let mut elements = vec![];
97 for k in keys {
98 match k {
99 Value::Id(k) => {
100 match tbl.borrow().get(&k) {
101 Some((kind, mat_values)) => {
102 elements.push(Box::new(mat_values.to_value()));
103 }
104 None => { return Err(MechError2::new(
105 UndefinedRecordFieldError { id: k.clone() },
106 None
107 ).with_compiler_loc()); }
108 }
109 }
110 _ => return Err(MechError2::new(UnhandledFunctionArgumentIxesMono { arg: (src.kind(), keys.iter().map(|x| x.kind()).collect()), fxn_name: "access/swizzle".to_string() }, None).with_compiler_loc()),
111 }
112 }
113 todo!("Table swizzle needs to be fixed.");
114 let tuple = Value::Tuple(Ref::new(MechTuple{elements}));
115 Ok(Box::new(TableAccessSwizzle{out: tuple}))
116 }
117 Value::MutableReference(r) => match &*r.borrow() {
118 #[cfg(feature = "record")]
119 Value::Record(rcrd) => {
120 let mut values = vec![];
121 for key in keys {
122 let k = key.as_u64().unwrap().borrow().clone();
123 match rcrd.borrow().get(&k) {
124 Some(value) => values.push(value.clone()),
125 None => { return Err(MechError2::new(
126 UndefinedRecordFieldError { id: k.clone() },
127 None
128 ).with_compiler_loc());
129 }
130 }
131 }
132 Ok(Box::new(RecordAccessSwizzle{source: Value::Tuple(Ref::new(MechTuple::from_vec(values)))}))
133 }
134 #[cfg(feature = "table")]
135 Value::Table(tbl) => {
136 let mut elements = vec![];
137 for key in keys {
138 let k = key.as_u64().unwrap().borrow().clone();
139 match tbl.borrow().get(&k) {
140 Some((kind, mat_values)) => {
141 elements.push(Box::new(mat_values.to_value()));
142 }
143 None => { return Err(MechError2::new(
144 UndefinedTableColumnError { id: k.clone() },
145 None
146 ).with_compiler_loc());
147 }
148 }
149 }
150 let tuple = Value::Tuple(Ref::new(MechTuple{elements}));
151 Ok(Box::new(TableAccessSwizzle{out: tuple}))
152 }
153 _ => todo!(),
154 }
155 _ => todo!(),
156 }
157 }
158}
159
160pub fn impl_access_column_fxn(source: Value, key: Value) -> MResult<Box<dyn MechFunction>> {
165 match source.kind().deref_kind() {
166 #[cfg(feature = "record")]
167 ValueKind::Record(_) => RecordAccess{}.compile(&vec![source,key]),
168 #[cfg(feature = "map")]
169 ValueKind::Map(..) => MapAccess{}.compile(&vec![source,key]),
170 #[cfg(feature = "table")]
171 ValueKind::Table(_,_) => TableAccessColumn{}.compile(&vec![source,key]),
172 _ => Err(MechError2::new(
173 UnhandledFunctionArgumentKind2 { arg: (source.kind(), key.kind()), fxn_name: "access/column".to_string() },
174 None
175 ).with_compiler_loc()
176 ),
177 }
178}
179
180pub struct AccessColumn {}
181impl NativeFunctionCompiler for AccessColumn {
182 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
183 if arguments.len() != 2 {
184 return Err(MechError2::new(IncorrectNumberOfArguments { expected: 1, found: arguments.len() }, None).with_compiler_loc());
185 }
186 let src = arguments[0].clone();
187 let key = arguments[1].clone();
188 match impl_access_column_fxn(src.clone(), key.clone()) {
189 Ok(fxn) => Ok(fxn),
190 Err(_) => {
191 match (src.clone(),&key.clone()) {
192 (Value::MutableReference(src),_) => { impl_access_column_fxn(src.borrow().clone(), key.clone()) }
193 _ => Err(MechError2::new(
194 UnhandledFunctionArgumentKind2 { arg: (src.kind(), key.kind()), fxn_name: "access/column".to_string() },
195 None
196 ).with_compiler_loc()
197 ),
198 }
199 }
200 }
201 }
202}