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(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
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(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind}),
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(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
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(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind}),
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(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
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 => { return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::UndefinedField(k)});}
79 }
80 }
81 Ok(Box::new(RecordAccessSwizzle{source: Value::Tuple(MechTuple::from_vec(values))}))
82 }
83 #[cfg(feature = "table")]
84 Value::Table(tbl) => {
85 let mut elements = vec![];
86 for k in keys {
87 match k {
88 Value::Id(k) => {
89 match tbl.borrow().get(&k) {
90 Some((kind, mat_values)) => {
91 elements.push(Box::new(mat_values.to_value()));
92 }
93 None => { return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::UndefinedField(*k)});}
94 }
95 }
96 _ => return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind}),
97 }
98 }
99 todo!("Table swizzle needs to be fixed.");
100 let tuple = Value::Tuple(MechTuple{elements});
101 Ok(Box::new(TableAccessSwizzle{out: tuple}))
102 }
103 Value::MutableReference(r) => match &*r.borrow() {
104 #[cfg(feature = "record")]
105 Value::Record(rcrd) => {
106 let mut values = vec![];
107 for key in keys {
108 let k = key.as_u64().unwrap().borrow().clone();
109 match rcrd.borrow().get(&k) {
110 Some(value) => values.push(value.clone()),
111 None => { return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::UndefinedField(k)});}
112 }
113 }
114 Ok(Box::new(RecordAccessSwizzle{source: Value::Tuple(MechTuple::from_vec(values))}))
115 }
116 #[cfg(feature = "table")]
117 Value::Table(tbl) => {
118 let mut elements = vec![];
119 for key in keys {
120 let k = key.as_u64().unwrap().borrow().clone();
121 match tbl.borrow().get(&k) {
122 Some((kind, mat_values)) => {
123 elements.push(Box::new(mat_values.to_value()));
124 }
125 None => { return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::UndefinedField(k)});}
126 }
127 }
128 let tuple = Value::Tuple(MechTuple{elements});
129 Ok(Box::new(TableAccessSwizzle{out: tuple}))
130 }
131 _ => todo!(),
132 }
133 _ => todo!(),
134 }
135 }
136}
137
138pub fn impl_access_column_fxn(source: Value, key: Value) -> MResult<Box<dyn MechFunction>> {
143 match source.kind().deref_kind() {
144 #[cfg(feature = "record")]
145 ValueKind::Record(_) => RecordAccess{}.compile(&vec![source,key]),
146 #[cfg(feature = "table")]
147 ValueKind::Table(_,_) => TableAccessColumn{}.compile(&vec![source,key]),
148 _ => Err(MechError{file: file!().to_string(),tokens: vec![],msg: format!("Unhandled args {:?}, {:?}", source, key),id: line!(),kind: MechErrorKind::UnhandledFunctionArgumentKind,}),
149 }
150}
151
152pub struct AccessColumn {}
153impl NativeFunctionCompiler for AccessColumn {
154 fn compile(&self, arguments: &Vec<Value>) -> MResult<Box<dyn MechFunction>> {
155 if arguments.len() != 2 {
156 return Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::IncorrectNumberOfArguments});
157 }
158 let src = arguments[0].clone();
159 let key = arguments[1].clone();
160 match impl_access_column_fxn(src.clone(), key.clone()) {
161 Ok(fxn) => Ok(fxn),
162 Err(_) => {
163 match (src,&key) {
164 (Value::MutableReference(src),_) => { impl_access_column_fxn(src.borrow().clone(), key.clone()) }
165 _ => Err(MechError{file: file!().to_string(), tokens: vec![], msg: "".to_string(), id: line!(), kind: MechErrorKind::UnhandledFunctionArgumentKind }),
166 }
167 }
168 }
169 }
170}