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