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