1use crate::constructor::Constructor;
9
10use super::*;
11use cl_ast::{ast_visitor::Visit, *};
12use std::borrow::Borrow;
13
14macro trace($($t:tt)*) {{
15 #[cfg(debug_assertions)]
16 if std::env::var("CONLANG_TRACE").is_ok() {
17 eprintln!($($t)*)
18 }
19}}
20
21pub trait Interpret {
23 fn interpret(&self, env: &mut Environment) -> IResult<ConValue>;
27}
28
29impl Interpret for File {
30 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
31 trace!("// Running {}", self.name);
32 #[derive(Debug, Default)]
34 struct ItemSorter<'ast>(pub [Vec<&'ast Item>; 8]);
35 impl<'ast> Visit<'ast> for ItemSorter<'ast> {
36 fn visit_item(&mut self, i: &'ast Item) {
37 for stage in match &i.kind {
38 ItemKind::Module(_) => [0].as_slice(),
39 ItemKind::Use(_) => &[1, 6],
40 ItemKind::Enum(_) | ItemKind::Struct(_) | ItemKind::Alias(_) => &[2],
41 ItemKind::Function(_) => &[3, 7],
42 ItemKind::Impl(_) => &[4],
43 ItemKind::Const(_) | ItemKind::Static(_) => &[5],
44 } {
45 self.0[*stage].push(i)
46 }
47 }
48 }
49
50 let mut items = ItemSorter::default();
51 items.visit_file(self);
52 for item in items.0.into_iter().flatten() {
53 item.interpret(env)?;
54 }
55
56 Ok(ConValue::Empty)
57 }
58}
59
60impl Interpret for Item {
61 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
62 match &self.kind {
63 ItemKind::Alias(item) => item.interpret(env),
64 ItemKind::Const(item) => item.interpret(env),
65 ItemKind::Static(item) => item.interpret(env),
66 ItemKind::Module(item) => item.interpret(env),
67 ItemKind::Function(item) => item.interpret(env),
68 ItemKind::Struct(item) => item.interpret(env),
69 ItemKind::Enum(item) => item.interpret(env),
70 ItemKind::Impl(item) => item.interpret(env),
71 ItemKind::Use(item) => item.interpret(env),
72 }
73 }
74}
75
76impl Interpret for Alias {
77 fn interpret(&self, _env: &mut Environment) -> IResult<ConValue> {
78 trace!("// TODO: {self}");
79 Ok(ConValue::Empty)
80 }
81}
82
83impl Interpret for Const {
84 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
85 let Const { name, ty: _, init } = self;
86 trace!("// Defining const {name}");
87
88 let init = init.as_ref().interpret(env)?;
89 env.insert(*name, init);
90 Ok(ConValue::Empty)
91 }
92}
93
94impl Interpret for Static {
95 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
96 let Static { mutable: _, name, ty: _, init } = self;
97 trace!("// Defining static {name}");
98
99 let init = init.as_ref().interpret(env)?;
100 env.insert(*name, init);
101 Ok(ConValue::Empty)
102 }
103}
104
105impl Interpret for Module {
106 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
108 let Self { name, file } = self;
109 trace!("// Defining module {name}");
110
111 let mut scope = env.frame(name.to_ref());
112
113 let out = match file {
114 Some(file) => file.interpret(&mut scope),
115 None => {
116 eprintln!("Module {name} specified, but not imported.");
117 Ok(ConValue::Empty)
118 }
119 };
120
121 let frame = scope
122 .pop_values()
123 .expect("Environment frames must be balanced");
124 env.insert(*name, ConValue::Module(frame.into()));
125
126 out
127 }
128}
129
130impl Interpret for Function {
131 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
132 trace!("// Defining fn {}", self.name);
133
134 env.insert_fn(self);
136 Ok(ConValue::Empty)
137 }
138}
139
140impl Interpret for Struct {
141 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
142 let Self { name, gens: _, kind } = self;
143 trace!("// Defining struct {name}");
144
145 let mut frame = env.frame(name.to_ref());
146
147 match kind {
148 StructKind::Empty => {
149 let cs = Constructor { arity: 0, name: *name };
150 frame.insert("call".into(), ConValue::TupleConstructor(cs));
151 frame.insert("__nmemb".into(), ConValue::Int(0));
152 }
153 StructKind::Tuple(args) => {
154 let cs = Constructor { arity: args.len() as _, name: *name };
155 frame.insert("call".into(), ConValue::TupleConstructor(cs));
156 frame.insert("__nmemb".into(), ConValue::Int(args.len() as _));
157 }
158 StructKind::Struct(members) => {
159 for (idx, StructMember { vis: _, name: nm, ty: _ }) in members.iter().enumerate() {
161 trace!("// Defining {name}::{nm}");
162 frame.insert(*nm, ConValue::Int(idx as _));
163 }
164 frame.insert("__nmemb".into(), ConValue::Int(members.len() as _));
165 }
166 }
167
168 let frame = frame
169 .pop_values()
170 .expect("Environment frames must be balanced");
171
172 env.insert(*name, ConValue::Module(Box::new(frame)));
173 Ok(ConValue::Empty)
174 }
175}
176
177impl Interpret for Enum {
178 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
179 let Self { name, gens: _, variants } = self;
180 trace!("// Defining enum {name}");
181
182 let mut scope = env.frame(name.to_ref());
183 for (idx, Variant { name, kind, body }) in variants.iter().enumerate() {
184 match (kind, body) {
185 (StructKind::Empty, None) => scope.insert(*name, ConValue::Int(idx as _)),
186 (StructKind::Empty, Some(idx)) => {
187 let idx = idx.interpret(&mut scope)?;
188 scope.insert(*name, idx)
189 }
190 (StructKind::Tuple(args), None) => {
191 let cs = Constructor { arity: args.len() as _, name: *name };
192 let mut variant = scope.frame(name.to_ref());
193 variant.insert("call".into(), ConValue::TupleConstructor(cs));
194 variant.insert("__nmemb".into(), ConValue::Int(args.len() as _));
195 let frame = variant
196 .pop_values()
197 .expect("Frame stack should remain balanced.");
198 scope.insert(*name, ConValue::Module(Box::new(frame)));
199 }
200 (StructKind::Struct(_), None) => {}
201 _ => eprintln!("Well-formedness error in {self}"),
202 }
203 }
204 let frame = scope
205 .pop_values()
206 .expect("Frame stack should remain balanced.");
207 env.insert(*name, ConValue::Module(Box::new(frame)));
208 Ok(ConValue::Empty)
209 }
210}
211
212impl Interpret for Impl {
213 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
214 let Self {
215 gens: _,
216 target: ImplKind::Type(Ty { span, kind: TyKind::Path(name), .. }),
217 body,
218 } = self
219 else {
220 trace!("TODO: impl X for Ty");
221 return Ok(ConValue::Empty);
222 };
223 let mut frame = env.frame("impl");
224 body.interpret(&mut frame)?;
225
226 let frame = frame
227 .pop_values()
228 .expect("Environment frames must be balanced");
229 match assignment::addrof_path(env, name.parts.as_slice())
230 .map_err(|err| err.with_span(*span))?
231 {
232 ConValue::Module(m) => m.extend(frame),
233 other => eprintln!("TODO: impl for {other}"),
234 }
235 Ok(ConValue::Empty)
236 }
237}
238
239impl Interpret for Use {
240 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
241 let Self { absolute: _, tree } = self;
242 tree.interpret(env)
243 }
244}
245
246impl Interpret for UseTree {
247 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
248 type Bindings = HashMap<Sym, ConValue>;
250 use std::collections::HashMap;
251
252 fn get_bindings(
253 tree: &UseTree,
254 env: &mut Environment,
255 bindings: &mut Bindings,
256 ) -> IResult<()> {
257 match tree {
258 UseTree::Tree(use_trees) => {
259 for tree in use_trees {
260 get_bindings(tree, env, bindings)?;
261 }
262 }
263 UseTree::Path(PathPart::Ident(name), tree) => {
264 let Ok(ConValue::Module(m)) = env.get(*name) else {
265 Err(Error::TypeError())?
266 };
267 let mut scope = env.with_frame(name.to_ref(), *m);
268 let out = get_bindings(tree, &mut scope, bindings);
269 return out;
270 }
271 UseTree::Alias(name, alias) => {
272 bindings.insert(*alias, env.get(*name)?);
273 }
274 UseTree::Name(name) => {
275 bindings.insert(*name, env.get(*name)?);
276 }
277 UseTree::Glob => {
278 trace!("TODO: Improve glob imports");
279 if let Some((frame, name)) = env.pop_frame() {
280 for (k, v) in &frame {
281 bindings.insert(*k, v.clone());
282 }
283 env.push_frame(name, frame);
284 }
285 }
286 other => {
287 eprintln!("ERROR: Cannot use {other}");
288 }
289 }
290 Ok(())
291 }
292
293 let mut bindings = Bindings::new();
294 get_bindings(self, env, &mut bindings)?;
295
296 for (name, value) in bindings {
297 env.insert(name, value);
298 }
299
300 Ok(ConValue::Empty)
301 }
302}
303
304impl Interpret for Stmt {
305 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
306 let Self { span, kind, semi } = self;
307 let out = match kind {
308 StmtKind::Empty => Ok(ConValue::Empty),
309 StmtKind::Item(stmt) => stmt.interpret(env),
310 StmtKind::Expr(stmt) => stmt.interpret(env),
311 }
312 .map_err(|err| err.with_span(*span))?;
313 Ok(match semi {
314 Semi::Terminated => ConValue::Empty,
315 Semi::Unterminated => out,
316 })
317 }
318}
319
320impl Interpret for Expr {
321 #[inline]
322 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
323 let Self { span, kind } = self;
324 kind.interpret(env).map_err(|err| err.with_span(*span))
325 }
326}
327
328impl Interpret for ExprKind {
329 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
330 match self {
331 ExprKind::Empty => Ok(ConValue::Empty),
332 ExprKind::Closure(v) => v.interpret(env),
333 ExprKind::Quote(q) => q.interpret(env),
334 ExprKind::Let(v) => v.interpret(env),
335 ExprKind::Match(v) => v.interpret(env),
336 ExprKind::Assign(v) => v.interpret(env),
337 ExprKind::Modify(v) => v.interpret(env),
338 ExprKind::Binary(v) => v.interpret(env),
339 ExprKind::Unary(v) => v.interpret(env),
340 ExprKind::Cast(v) => v.interpret(env),
341 ExprKind::Member(v) => v.interpret(env),
342 ExprKind::Index(v) => v.interpret(env),
343 ExprKind::Structor(v) => v.interpret(env),
344 ExprKind::Path(v) => v.interpret(env),
345 ExprKind::Literal(v) => v.interpret(env),
346 ExprKind::Array(v) => v.interpret(env),
347 ExprKind::ArrayRep(v) => v.interpret(env),
348 ExprKind::AddrOf(v) => v.interpret(env),
349 ExprKind::Block(v) => v.interpret(env),
350 ExprKind::Group(v) => v.interpret(env),
351 ExprKind::Tuple(v) => v.interpret(env),
352 ExprKind::While(v) => v.interpret(env),
353 ExprKind::If(v) => v.interpret(env),
354 ExprKind::For(v) => v.interpret(env),
355 ExprKind::Break(v) => v.interpret(env),
356 ExprKind::Return(v) => v.interpret(env),
357 ExprKind::Continue => Err(Error::Continue()),
358 }
359 }
360}
361
362impl Interpret for Closure {
363 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
364 Ok(ConValue::Closure(
365 crate::closure::Closure::new(env, self).into(),
366 ))
367 }
368}
369
370impl Interpret for Quote {
371 fn interpret(&self, _env: &mut Environment) -> IResult<ConValue> {
372 Ok(ConValue::Quote(self.quote.as_ref().clone().into()))
374 }
375}
376
377impl Interpret for Let {
378 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
379 let Let { mutable: _, name, ty: _, init } = self;
380 match init.as_ref().map(|i| i.interpret(env)).transpose()? {
381 Some(value) => {
382 match pattern::substitution(env, name, value) {
383 Ok(sub) => {
384 for (name, value) in sub {
385 env.insert(name, value);
386 }
387 return Ok(ConValue::Bool(true));
388 }
389 Err(_e) => trace!("{_e}"),
390 };
391 }
392 None => {
393 for name in pattern::variables(name) {
394 env.insert(*name, ConValue::Empty);
395 }
396 }
397 }
398 Ok(ConValue::Bool(false))
399 }
400}
401
402impl Interpret for Match {
403 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
404 let Self { scrutinee, arms } = self;
405 let scrutinee = scrutinee.interpret(env)?;
406 for MatchArm(pat, expr) in arms {
407 if let Ok(substitution) = pattern::substitution(env, pat, scrutinee.clone()) {
408 let mut env = env.frame("match");
409 for (name, value) in substitution {
410 env.insert(name, value);
411 }
412 return expr.interpret(&mut env);
413 }
414 }
415 Err(Error::MatchNonexhaustive())
416 }
417}
418
419pub(crate) mod assignment {
420 use super::*;
422 use std::collections::HashMap;
423 type Namespace = HashMap<Sym, ConValue>;
424
425 pub(super) fn pat_assign(env: &mut Environment, pat: &Pattern, value: ConValue) -> IResult<()> {
426 for (name, value) in pattern::substitution(env, pat, value)
427 .map_err(|_| Error::PatFailed(pat.clone().into()))?
428 {
429 match env.get_mut(name)? {
430 &mut ConValue::Ref(id) => {
431 *(env.get_id_mut(id).ok_or(Error::StackOverflow(id))?) = value;
432 }
433 other => *other = value,
434 }
435 }
436 Ok(())
437 }
438
439 pub(super) fn assign(env: &mut Environment, pat: &Expr, value: ConValue) -> IResult<()> {
440 if let Ok(pat) = Pattern::try_from(pat.clone()) {
441 return pat_assign(env, &pat, value);
442 }
443 match &pat.kind {
444 ExprKind::Member(member) => *addrof_member(env, member)? = value,
445 ExprKind::Index(index) => *addrof_index(env, index)? = value,
446 ExprKind::Path(path) => *addrof_path(env, &path.parts)? = value,
447 ExprKind::Unary(Unary { kind: UnaryKind::Deref, tail }) => match addrof(env, tail)? {
448 &mut ConValue::Ref(r) => *env.get_id_mut(r).ok_or(Error::StackOverflow(r))? = value,
449 _ => Err(Error::NotAssignable())?,
450 },
451 _ => Err(Error::NotAssignable())?,
452 }
453 Ok(())
454 }
455
456 pub(super) fn addrof<'e>(env: &'e mut Environment, pat: &Expr) -> IResult<&'e mut ConValue> {
457 match &pat.kind {
458 ExprKind::Path(path) => addrof_path(env, &path.parts),
459 ExprKind::Member(member) => addrof_member(env, member),
460 ExprKind::Index(index) => addrof_index(env, index),
461 ExprKind::Group(Group { expr }) => addrof(env, expr),
462 ExprKind::Unary(Unary { kind: UnaryKind::Deref, tail }) => match *addrof(env, tail)? {
463 ConValue::Ref(place) => env.get_id_mut(place).ok_or(Error::NotIndexable()),
464 _ => Err(Error::TypeError()),
465 },
466 _ => Err(Error::TypeError()),
467 }
468 }
469
470 pub fn addrof_path<'e>(
471 env: &'e mut Environment,
472 path: &[PathPart],
473 ) -> IResult<&'e mut ConValue> {
474 match path {
475 [PathPart::Ident(name)] => env.get_mut(*name),
476 [PathPart::Ident(name), rest @ ..] => match env.get_mut(*name)? {
477 ConValue::Module(env) => project_path_in_namespace(env, rest),
478 _ => Err(Error::NotIndexable()),
479 },
480 _ => Err(Error::NotAssignable()),
481 }
482 }
483
484 pub fn addrof_member<'e>(
485 env: &'e mut Environment,
486 member: &Member,
487 ) -> IResult<&'e mut ConValue> {
488 let Member { head, kind } = member;
489
490 let head = addrof(env, head)?;
491 project_memberkind(head, kind)
492 }
493
494 fn addrof_index<'e>(env: &'e mut Environment, index: &Index) -> IResult<&'e mut ConValue> {
495 let Index { head, indices } = index;
496 let indices = indices
497 .iter()
498 .map(|index| index.interpret(env))
499 .collect::<IResult<Vec<_>>>()?;
500
501 let mut head = addrof(env, head)?;
502 for index in indices {
508 head = project_index(head, &index)?;
509 }
510 Ok(head)
511 }
512
513 pub fn project_memberkind<'v>(
515 value: &'v mut ConValue,
516 kind: &MemberKind,
517 ) -> IResult<&'v mut ConValue> {
518 match (value, kind) {
519 (ConValue::Struct(_name, s), MemberKind::Struct(id)) => {
520 s.get_mut(id).ok_or(Error::NotDefined(*id))
521 }
522 (ConValue::TupleStruct(_name, s), MemberKind::Tuple(Literal::Int(id))) => {
523 let len = s.len();
524 s.get_mut(*id as usize)
525 .ok_or(Error::OobIndex(*id as _, len))
526 }
527 (ConValue::Tuple(t), MemberKind::Tuple(Literal::Int(id))) => {
528 let len = t.len();
529 t.get_mut(*id as usize)
530 .ok_or(Error::OobIndex(*id as _, len))
531 }
532 _ => Err(Error::TypeError()),
533 }
534 }
535
536 pub fn project_index<'v>(
538 _value: &'v mut ConValue,
539 _index: &ConValue,
540 ) -> IResult<&'v mut ConValue> {
541 Err(Error::NotIndexable())
542 }
543
544 pub fn project_path_in_namespace<'e>(
545 env: &'e mut Namespace,
546 path: &[PathPart],
547 ) -> IResult<&'e mut ConValue> {
548 match path {
549 [] => Err(Error::NotAssignable()),
550 [PathPart::Ident(name)] => env.get_mut(name).ok_or(Error::NotDefined(*name)),
551 [PathPart::Ident(name), rest @ ..] => {
552 match env.get_mut(name).ok_or(Error::NotDefined(*name))? {
553 ConValue::Module(env) => project_path_in_namespace(env, rest),
554 _ => Err(Error::NotIndexable()),
555 }
556 }
557 [PathPart::SelfTy, ..] => todo!("calc_address for `Self`"),
558 [PathPart::SuperKw, ..] => todo!("calc_address for `super`"),
559 }
560 }
561}
562
563impl Interpret for Assign {
564 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
565 let Assign { parts } = self;
566 let (head, tail) = parts.borrow();
567 let init = tail.interpret(env)?;
568 assignment::assign(env, head, init).map(|_| ConValue::Empty)
570 }
571}
572impl Interpret for Modify {
573 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
574 let Modify { kind: op, parts } = self;
575 let (head, tail) = parts.borrow();
576 let init = tail.interpret(env)?;
578 let target = assignment::addrof(env, head)?;
580
581 match op {
582 ModifyKind::Add => target.add_assign(init),
583 ModifyKind::Sub => target.sub_assign(init),
584 ModifyKind::Mul => target.mul_assign(init),
585 ModifyKind::Div => target.div_assign(init),
586 ModifyKind::Rem => target.rem_assign(init),
587 ModifyKind::And => target.bitand_assign(init),
588 ModifyKind::Or => target.bitor_assign(init),
589 ModifyKind::Xor => target.bitxor_assign(init),
590 ModifyKind::Shl => target.shl_assign(init),
591 ModifyKind::Shr => target.shr_assign(init),
592 }?;
593 Ok(ConValue::Empty)
594 }
595}
596impl Interpret for Binary {
597 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
598 let Binary { kind, parts } = self;
599 let (head, tail) = parts.borrow();
600
601 let head = head.interpret(env)?;
602 match kind {
603 BinaryKind::LogAnd => {
604 return if head.truthy()? {
605 tail.interpret(env)
606 } else {
607 Ok(head)
608 }; }
610 BinaryKind::LogOr => {
611 return if !head.truthy()? {
612 tail.interpret(env)
613 } else {
614 Ok(head)
615 }; }
617 BinaryKind::LogXor => {
618 return Ok(ConValue::Bool(
619 head.truthy()? ^ tail.interpret(env)?.truthy()?,
620 ));
621 }
622 _ => {}
623 }
624
625 let tail = tail.interpret(env)?;
626
627 #[allow(unused)]
628 let operator = match kind {
629 BinaryKind::Lt => "lt",
630 BinaryKind::LtEq => "lteq",
631 BinaryKind::Equal => "eq",
632 BinaryKind::NotEq => "neq",
633 BinaryKind::GtEq => "gteq",
634 BinaryKind::Gt => "gt",
635 BinaryKind::RangeExc => "range_exc",
636 BinaryKind::RangeInc => "range_inc",
637 BinaryKind::LogAnd => "log_and",
638 BinaryKind::LogOr => "log_or",
639 BinaryKind::LogXor => "log_xor",
640 BinaryKind::BitAnd => "bit_and",
641 BinaryKind::BitOr => "bit_or",
642 BinaryKind::BitXor => "bit_xor",
643 BinaryKind::Shl => "shl",
644 BinaryKind::Shr => "shr",
645 BinaryKind::Add => "add",
646 BinaryKind::Sub => "sub",
647 BinaryKind::Mul => "mul",
648 BinaryKind::Div => "div",
649 BinaryKind::Rem => "rem",
650 BinaryKind::Call => "call",
651 };
652
653 if let ConValue::Struct(name, _) | ConValue::TupleStruct(name, _) = head
654 && let Ok(ConValue::Module(m)) = env.get_mut(name)
655 && let Some(f) = m.get(&operator.into())
656 {
657 return f.clone().call(env, &[head, tail]);
658 }
659
660 if let Ok(ConValue::Module(m)) = env.get_mut(head.typename().into())
661 && let Some(f) = m.get(&operator.into())
662 {
663 return f.clone().call(env, &[head, tail]);
664 }
665
666 match kind {
667 BinaryKind::Lt => head.lt(&tail),
668 BinaryKind::LtEq => head.lt_eq(&tail),
669 BinaryKind::Equal => head.eq(&tail),
670 BinaryKind::NotEq => head.neq(&tail),
671 BinaryKind::GtEq => head.gt_eq(&tail),
672 BinaryKind::Gt => head.gt(&tail),
673 BinaryKind::RangeExc => env.call("RangeExc".into(), &[head, tail]),
674 BinaryKind::RangeInc => env.call("RangeInc".into(), &[head, tail]),
675 BinaryKind::BitAnd => head & tail,
676 BinaryKind::BitOr => head | tail,
677 BinaryKind::BitXor => head ^ tail,
678 BinaryKind::Shl => head << tail,
679 BinaryKind::Shr => head >> tail,
680 BinaryKind::Add => head + tail,
681 BinaryKind::Sub => head - tail,
682 BinaryKind::Mul => head * tail,
683 BinaryKind::Div => head / tail,
684 BinaryKind::Rem => head % tail,
685 BinaryKind::Call => match tail {
686 ConValue::Empty => head.call(env, &[]),
687 ConValue::Tuple(args) => head.call(env, &args),
688 _ => Err(Error::TypeError()),
689 },
690 _ => Ok(head),
691 }
692 }
693}
694
695impl Interpret for Unary {
696 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
697 let Unary { kind, tail } = self;
698 if *kind == UnaryKind::Loop {
699 loop {
700 match tail.interpret(env) {
701 Err(Error { kind: ErrorKind::Break(value), .. }) => return Ok(value),
702 Err(Error { kind: ErrorKind::Continue, .. }) => continue,
703 e => e?,
704 };
705 }
706 }
707
708 let operator = match kind {
709 UnaryKind::Loop => unreachable!(),
710 UnaryKind::Deref => "deref",
711 UnaryKind::Neg => "neg",
712 UnaryKind::Not => "not",
713 UnaryKind::RangeExc => "RangeTo",
714 UnaryKind::RangeInc => "RangeToInc",
715 UnaryKind::At => "at",
716 UnaryKind::Tilde => "tilde",
717 };
718
719 let operand = tail.interpret(env)?;
720
721 if let ConValue::Struct(name, _) | ConValue::TupleStruct(name, _) = operand
722 && let Ok(ConValue::Module(m)) = env.get_mut(name)
723 && let Some(f) = m.get(&operator.into())
724 {
725 return f.clone().call(env, &[operand]);
726 }
727
728 if let Ok(ConValue::Module(m)) = env.get_mut(operand.typename().into())
729 && let Some(f) = m.get(&operator.into())
730 {
731 return f.clone().call(env, &[operand]);
732 }
733
734 env.call(operator.into(), &[operand])
735 }
736}
737
738fn cast(env: &Environment, value: ConValue, ty: Sym) -> IResult<ConValue> {
739 let value = match (value, ty.to_ref()) {
740 (value, "str") => return Ok(ConValue::Str(format!("{value}").into())),
741 (value, "String") => return Ok(ConValue::String(format!("{value}"))),
742 (ConValue::Empty, _) => 0,
743 (ConValue::Int(i), _) => i as _,
744 (ConValue::Bool(b), _) => b as _,
745 (ConValue::Char(c), _) => c as _,
746 (ConValue::Ref(v), _) => {
747 return cast(
748 env,
749 env.get_id(v).cloned().ok_or(Error::StackUnderflow())?,
750 ty,
751 );
752 }
753 (ConValue::Float(f), "f32" | "f64") => return Ok(ConValue::Float(f)),
754 (ConValue::Float(f), _) => f as _,
755 _ => Err(Error::TypeError())?,
756 };
757 Ok(match &*ty {
758 "u8" => ConValue::Int(value as u8 as _),
759 "i8" => ConValue::Int(value as i8 as _),
760 "u16" => ConValue::Int(value as u16 as _),
761 "i16" => ConValue::Int(value as i16 as _),
762 "u32" => ConValue::Int(value as u32 as _),
763 "i32" => ConValue::Int(value as i32 as _),
764 "u64" => ConValue::Int(value),
765 "i64" => ConValue::Int(value),
766 "f32" => ConValue::Float(value as f32 as _),
767 "f64" => ConValue::Float(value as f64 as _),
768 "char" => ConValue::Char(char::from_u32(value as _).unwrap_or('\u{fffd}')),
769 "bool" => ConValue::Bool(value != 0),
770 _ => Err(Error::NotDefined(ty))?,
771 })
772}
773
774impl Interpret for Cast {
775 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
776 let Cast { head, ty } = self;
777 let value = head.interpret(env)?;
778
779 if let TyKind::Tuple(TyTuple { types }) = &ty.kind
780 && types.as_slice().is_empty()
781 {
782 return Ok(ConValue::Empty);
783 }
784 let TyKind::Path(Path { absolute: false, parts }) = &ty.kind else {
785 Err(Error::TypeError())?
786 };
787 match parts.as_slice() {
788 [PathPart::Ident(ty)] => cast(env, value, *ty),
789 _ => Err(Error::TypeError()),
790 }
791 }
792}
793
794impl Interpret for Member {
795 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
796 let Member { head, kind } = self;
797 if let Ok(member) = assignment::addrof_member(env, self) {
799 return Ok(member.clone());
800 }
801 let mut values = vec![];
802
803 let addr = match (&head.kind, kind) {
805 (ExprKind::Path(p), MemberKind::Call(..)) => {
806 p.as_sym()
807 .and_then(|name| Some(ConValue::Ref(env.id_of(name).ok()?))) }
809 _ => None,
810 };
811
812 let mut value = head.interpret(env)?;
813
814 match (&value, &kind) {
816 (ConValue::Struct(_name, memb), MemberKind::Call(name, args))
817 if memb.contains_key(name) =>
818 {
819 let f = memb.get(name).cloned().expect("function exists");
820 values.push(addr.unwrap_or(value));
821 for arg in &args.exprs {
822 values.push(arg.interpret(env)?);
823 }
824 f.call(env, &values)
825 }
826 (_, MemberKind::Call(name, args)) => {
827 values.push(addr.unwrap_or(value));
828 for arg in &args.exprs {
829 values.push(arg.interpret(env)?);
830 }
831 env.call(*name, &values)
832 }
833 (_, kind) => assignment::project_memberkind(&mut value, kind).cloned(),
834 }
835 }
836}
837impl Interpret for Index {
838 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
839 let Self { head, indices } = self;
840 let mut head = head.interpret(env)?;
841 for index in indices {
842 head = head.index(&index.interpret(env)?, env)?;
843 }
844 Ok(head)
845 }
846}
847impl Interpret for Structor {
848 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
849 let Self { to: Path { absolute: _, parts }, init } = self;
850 use std::collections::HashMap;
851
852 let name = match parts.last() {
856 Some(PathPart::Ident(name)) => *name,
857 Some(PathPart::SelfTy) => "Self".into(),
858 Some(PathPart::SuperKw) => "super".into(),
859 None => "".into(),
860 };
861
862 let mut map = HashMap::new();
863 for Fielder { name, init } in init {
864 let value = match init {
865 Some(init) => init.interpret(env)?,
866 None => env.get(*name)?,
867 };
868 map.insert(*name, value);
869 }
870 Ok(ConValue::Struct(name, Box::new(map)))
871 }
872}
873
874impl Interpret for Path {
875 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
876 let Self { absolute: _, parts } = self;
877
878 assignment::addrof_path(env, parts).cloned()
879 }
880}
881impl Interpret for Literal {
882 fn interpret(&self, _env: &mut Environment) -> IResult<ConValue> {
883 Ok(match self {
884 Literal::String(value) => ConValue::from(value.as_str()),
885 Literal::Char(value) => ConValue::Char(*value),
886 Literal::Bool(value) => ConValue::Bool(*value),
887 Literal::Float(value) => ConValue::Float(f64::from_bits(*value)),
888 Literal::Int(value) => ConValue::Int(*value as _),
889 })
890 }
891}
892impl Interpret for Array {
893 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
894 let Self { values } = self;
895 let mut out = vec![];
896 for expr in values {
897 out.push(expr.interpret(env)?)
898 }
899 Ok(ConValue::Array(out.into()))
900 }
901}
902impl Interpret for ArrayRep {
903 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
904 let Self { value, repeat } = self;
905 let value = value.interpret(env)?;
906 let ConValue::Int(repeat) = repeat.interpret(env)? else {
907 Err(Error::TypeError())?
908 };
909 if repeat < 0 {
910 Err(Error::NotIndexable())?
912 }
913
914 Ok(ConValue::Array(vec![value; repeat as usize].into()))
915 }
916}
917impl Interpret for AddrOf {
918 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
919 let Self { mutable: _, expr } = self;
920 match &expr.kind {
921 ExprKind::Index(_) => todo!("AddrOf array index"),
922 ExprKind::Path(Path { parts, .. }) => match parts.as_slice() {
923 [PathPart::Ident(name)] => Ok(ConValue::Ref(env.id_of(*name)?)),
924 _ => todo!("Path traversal in AddrOf(\"{self}\")"),
925 },
926 _ => {
927 let value = expr.interpret(env)?;
928 let temp = env.stack_alloc(value)?;
929 Ok(ConValue::Ref(temp))
930 }
931 }
932 }
933}
934impl Interpret for Block {
935 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
936 let Self { stmts } = self;
937 let mut env = env.frame("block");
938 let mut out = ConValue::Empty;
939 for stmt in stmts {
940 out = stmt.interpret(&mut env)?;
941 }
942 Ok(out)
943 }
944}
945impl Interpret for Group {
946 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
947 let Self { expr } = self;
948 expr.interpret(env)
949 }
950}
951impl Interpret for Tuple {
952 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
953 let Self { exprs } = self;
954 Ok(ConValue::Tuple(
955 exprs
956 .iter()
957 .try_fold(vec![], |mut out, element| {
958 out.push(element.interpret(env)?);
959 Ok(out)
960 })?
961 .into(),
962 ))
963 }
964}
965impl Interpret for While {
966 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
967 let Self { cond, pass, fail } = self;
968 loop {
969 if cond.interpret(env)?.truthy()? {
970 match pass.interpret(env) {
971 Err(Error { kind: ErrorKind::Break(value), .. }) => break Ok(value),
972 Err(Error { kind: ErrorKind::Continue, .. }) => continue,
973 e => e?,
974 };
975 } else {
976 break fail.interpret(env);
977 }
978 }
979 }
980}
981impl Interpret for If {
982 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
983 let Self { cond, pass, fail } = self;
984 if cond.interpret(env)?.truthy()? {
985 pass.interpret(env)
986 } else {
987 fail.interpret(env)
988 }
989 }
990}
991impl Interpret for For {
992 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
993 let Self { bind, cond, pass, fail } = self;
994 let cond = cond.interpret(env)?;
995 let mut bounds: Box<dyn Iterator<Item = ConValue>> = match &cond {
997 ConValue::TupleStruct(name, values) => match name.to_ref() {
998 "RangeExc" => match values.as_ref().as_ref() {
999 &[ConValue::Int(from), ConValue::Int(to)] => {
1000 Box::new((from..to).map(ConValue::Int))
1001 }
1002 _ => Err(Error::NotIterable())?,
1003 },
1004 "RangeInc" => match values.as_ref().as_ref() {
1005 &[ConValue::Int(from), ConValue::Int(to)] => {
1006 Box::new((from..=to).map(ConValue::Int))
1007 }
1008 _ => Err(Error::NotIterable())?,
1009 },
1010 _ => Err(Error::NotIterable())?,
1011 },
1012 ConValue::Array(a) => Box::new(a.iter().cloned()),
1013 &ConValue::Slice(head, len) => Box::new((head..head + len).map(ConValue::Ref)),
1014 ConValue::Tuple(t) => Box::new(t.iter().cloned()),
1016 ConValue::Str(s) => Box::new(s.chars().map(ConValue::Char)),
1017 _ => Err(Error::TypeError())?,
1018 };
1019 loop {
1020 let mut env = env.frame("loop variable");
1021 if let Some(value) = bounds.next() {
1022 for (name, value) in pattern::substitution(&env, bind, value)? {
1023 env.insert(name, value);
1024 }
1025 match pass.interpret(&mut env) {
1026 Err(Error { kind: ErrorKind::Break(value), .. }) => break Ok(value),
1027 Err(Error { kind: ErrorKind::Continue, .. }) => continue,
1028 e => e?,
1029 };
1030 } else {
1031 break fail.interpret(&mut env);
1032 }
1033 }
1034 }
1035}
1036impl Interpret for Else {
1037 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
1038 let Self { body } = self;
1039 match body {
1040 Some(body) => body.interpret(env),
1041 None => Ok(ConValue::Empty),
1042 }
1043 }
1044}
1045impl Interpret for Return {
1046 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
1047 let Self { body } = self;
1048 Err(Error::Return(
1049 body.as_ref()
1050 .map(|body| body.interpret(env))
1051 .unwrap_or(Ok(ConValue::Empty))?,
1052 ))
1053 }
1054}
1055impl Interpret for Break {
1056 fn interpret(&self, env: &mut Environment) -> IResult<ConValue> {
1057 let Self { body } = self;
1058 Err(Error::Break(
1059 body.as_ref()
1060 .map(|body| body.interpret(env))
1061 .unwrap_or(Ok(ConValue::Empty))?,
1062 ))
1063 }
1064}