1mod builtins;
2pub mod types;
3
4use types::*;
5
6fn resolve_funcmap(funcs: &mut FuncMap) {
8 for function in &mut funcs.functions {
9 if let Function::Clac(f) = function {
10 for token in f {
11 if let Token::FunctionCall(FunctionRef::Unresolved(name)) = token
12 && let Some(resolved) = funcs.map.get(name)
13 {
14 *token = Token::FunctionCall(FunctionRef::Resolved(*resolved));
15 }
16 }
17 }
18 }
19}
20
21fn parse(token: &str) -> Token {
22 use Token::*;
23
24 match token {
25 "print" => Print,
26 "quit" => Quit,
27
28 "drop" => Drop,
29 "swap" => Swap,
30 "rot" => Rot,
31 "pick" => Pick,
32
33 "if" => If,
34 "skip" => Skip,
35
36 ":" => Colon,
37 ";" => Semicolon,
38
39 id => match id.parse() {
41 Ok(num) => Literal(num),
42 Err(_) => FunctionCall(FunctionRef::Unresolved(id.to_string())),
43 },
44 }
45}
46
47impl ClacState {
48 fn execute<'cs>(
49 functions: &'cs FuncMap,
50 stack: &mut ClacStack,
51 token: &Token,
52 ) -> Result<ExecRes<'cs>, ExecError> {
53 match (stack.as_mut_slice(), token) {
54 (_, Token::Literal(n)) => {
55 stack.push(*n);
56 Ok(ExecRes::Executed)
57 }
58 (_, Token::Quit) => Err(ExecError::Quit),
59 (_, Token::FunctionCall(state)) => {
60 let f = match state {
61 FunctionRef::Resolved(x) => &functions.functions[*x],
62 FunctionRef::Unresolved(name) => match functions.map.get(name) {
63 Some(x) => &functions.functions[*x], None => return Err(ExecError::UnknownFunction(name.to_string())),
65 },
66 };
67
68 match f {
69 Function::Clac(f) => Ok(ExecRes::RecursiveCall(f)),
70 Function::Native(f) => {
71 f(stack);
72 Ok(ExecRes::Executed)
73 }
74 Function::ClacOp(f) => {
75 let y = stack.pop().ok_or(ExecError::MissingArguments)?;
76 let x = stack.pop().ok_or(ExecError::MissingArguments)?;
77
78 stack.push(f(x, y));
79 Ok(ExecRes::Executed)
80 }
81 }
82 }
83
84 ([.., x], Token::Print) => {
85 println!("{x}");
86 stack.pop();
87 Ok(ExecRes::Executed)
88 }
89 ([.., _], Token::Drop) => {
90 stack.pop().expect("unreachable");
91 Ok(ExecRes::Executed)
92 }
93 ([.., x, y], Token::Swap) => {
94 std::mem::swap(x, y);
95 Ok(ExecRes::Executed)
96 }
97 ([.., x, y, z], Token::Rot) => {
98 (*x, *y, *z) = (*y, *z, *x);
99 Ok(ExecRes::Executed)
100 }
101 ([.., 0], Token::If) => {
102 stack.pop().unwrap();
103
104 Ok(ExecRes::Skip(3))
105 }
106 ([.., _], Token::If) => {
107 stack.pop().unwrap();
108
109 Ok(ExecRes::Executed)
110 }
111 ([.., n], Token::Skip) => {
112 let n = *n;
113 stack.pop();
114 Ok(ExecRes::Skip(
115 n.try_into().map_err(|_| ExecError::InvalidSkip)?,
116 ))
117 }
118 ([.., n], Token::Pick) if (*n > 0) => {
119 let conv: usize = (*n).try_into().unwrap();
120 stack.pop();
121 let got = stack
122 .get::<usize>(stack.len() - conv)
123 .ok_or(ExecError::InvalidPick)?;
124
125 stack.push(*got);
126
127 Ok(ExecRes::Executed)
128 }
129 (
130 _,
131 Token::Swap
132 | Token::Print
133 | Token::Drop
134 | Token::Rot
135 | Token::If
136 | Token::Pick
137 | Token::Skip,
138 ) => Err(ExecError::MissingArguments),
139 (_, Token::Semicolon) => unreachable!(),
140 (_, Token::Colon) => unreachable!(),
141 }
142 }
143
144 fn execute_line_nontop<'cs>(
146 funcs: &'cs FuncMap,
147 stack: &mut ClacStack,
148 mut callstack: CallStack<'cs>,
149 ) -> Result<(), ExecError> {
150 while let Some(line) = callstack.pop() {
151 let Some((token, xs)) = line.split_first() else {
153 continue;
154 };
155
156 let mut optimize_push = |vals: &[Token]| match vals {
157 [] => {}
158 [Token::Literal(n), Token::Skip, rest @ ..]
159 if (*n >= 0 && ((*n as usize) == rest.len())) => {}
160 _ => {
161 callstack.push(xs);
162 }
163 };
164
165 match Self::execute(funcs, stack, token)? {
166 ExecRes::Executed => {
167 if !xs.is_empty() {
168 callstack.push(xs);
169 }
170 }
171 ExecRes::Skip(n) => match xs.split_at_checked(n) {
172 Some((_, remain)) => {
173 if !remain.is_empty() {
174 callstack.push(remain);
175 }
176 }
177 None => return Err(ExecError::InvalidSkip),
178 },
179 ExecRes::RecursiveCall(newfunc) => {
180 optimize_push(xs);
182
183 callstack.push(newfunc);
184 }
185 }
186 }
187
188 Ok(())
189 }
190
191 pub fn execute_tokens(&mut self, mut line: &[Token]) -> Result<(), ExecError> {
193 let mut cur_func: Option<(&String, Code)> = None;
194
195 let funcs = &mut self.funcmap;
196 let stack = &mut self.stack;
197
198 loop {
199 (line, cur_func) = match (line, cur_func) {
200 (
201 [
202 Token::Colon,
203 Token::FunctionCall(FunctionRef::Unresolved(name)),
204 rem @ ..,
205 ],
206 None,
207 ) => (rem, Some((name, Vec::new()))),
208 ([Token::Semicolon, rem @ ..], Some((name, f))) => {
209 let len = funcs.functions.len();
210
211 match funcs.map.get(name) {
213 Some(idx) => {
214 funcs.functions[*idx] = Function::Clac(f);
215 }
216 None => {
217 funcs.functions.push(Function::Clac(f));
218 funcs.map.insert(name.to_string(), len);
219 }
220 };
221
222 resolve_funcmap(funcs);
224
225 (rem, None)
226 }
227 ([Token::Colon | Token::Semicolon, ..], _) => {
228 return Err(ExecError::BadFunctionDefinition);
229 }
230 ([tok, rem @ ..], Some((nm, mut f))) => {
231 f.push(tok.clone());
232 (rem, Some((nm, f)))
233 }
234 ([tok, rem @ ..], None) => match Self::execute(funcs, stack, tok)? {
235 ExecRes::Executed => (rem, None),
236 ExecRes::Skip(n) => match rem.split_at_checked(n) {
237 Some((_, rem2)) => (rem2, None),
238 None => return Err(ExecError::InvalidSkip),
239 },
240 ExecRes::RecursiveCall(f) => {
241 Self::execute_line_nontop(funcs, stack, vec![f])?;
242 (rem, None)
243 }
244 },
245 ([], Some(_)) => return Err(ExecError::BadFunctionDefinition),
246 ([], None) => return Ok(()),
247 };
248 }
249 }
250
251 pub fn execute_str(&mut self, line: &str) -> Result<(), ExecError> {
253 let parsed: Vec<Token> = line.split_whitespace().map(parse).collect();
254
255 self.execute_tokens(&parsed)
256 }
257}
258
259fn name_func_pair_to_funcmap<const N: usize>(xs: [(&str, Function); N]) -> FuncMap {
260 FuncMap {
261 map: ahash::AHashMap::from_iter(
262 xs.iter()
263 .enumerate()
264 .map(|(i, (name, _))| (name.to_string(), i)),
265 ),
266 functions: Vec::from_iter(xs.into_iter().map(|(_, func)| func)),
267 }
268}
269
270impl Default for ClacState {
271 fn default() -> Self {
272 ClacState {
273 stack: Vec::new(),
274 funcmap: name_func_pair_to_funcmap(builtins::FUNCTIONS),
275 }
276 }
277}