1use std::cell::RefCell;
4use std::collections::HashMap;
5use std::rc::Rc;
6use std::sync::Arc;
7
8use crate::interpreter::stdlib::http::HttpHandle;
9use crate::interpreter::stdlib::net::NetHandle;
10use crate::interpreter::stdlib::random::xoshiro::Xoshiro256;
11use crate::interpreter::values::FunctionData;
12use crate::lexer::tokentypes::TokenType;
13use crate::resolver::Resolver;
14use crate::{
15 ast::{ExprId, nodes::ExpressionKind, statements::TypeAnnotation},
16 interpreter::{
17 native::{IntoNativeFn, Module},
18 stdlib,
19 values::{MapKey, Value},
20 },
21 utils::{
22 errors::{Error, Reason},
23 source::SourceFile,
24 span::Span,
25 suggest::closest_match,
26 },
27};
28
29#[derive(Debug, Clone, PartialEq)]
31pub struct PItem {
32 pub value: Value,
34 pub type_annotation: TypeAnnotation,
36 pub is_const: bool,
38}
39
40#[derive(Debug, Clone, PartialEq)]
43pub enum EnvironmentItem {
44 PItem(PItem),
45}
46
47pub struct Evaluator {
49 pub globals: Vec<EnvironmentItem>,
51 pub environment: Vec<Vec<EnvironmentItem>>,
54 pub scope_pool: Vec<Vec<EnvironmentItem>>,
59 pub source_file: Option<SourceFile>,
61 pub root_module: Module,
63 pub return_value: Option<Value>,
65 pub is_breaking: bool,
67 pub is_continuing: bool,
69 pub output_buffer: Option<String>,
71 pub rng: Xoshiro256,
73 pub resolver: Resolver,
78 pub fn_names: HashMap<String, usize>,
80 pub user_args_offset: usize,
82 pub net_handles: HashMap<i64, NetHandle>,
84 pub net_next_handle: i64,
86 pub http_handles: HashMap<i64, HttpHandle>,
88 pub http_next_handle: i64,
90 pub records: HashMap<String, Vec<(String, TypeAnnotation)>>,
93 pub tags: HashMap<String, Vec<String>>,
96}
97
98impl Default for Evaluator {
99 fn default() -> Self {
100 Self::new()
101 }
102}
103
104impl Evaluator {
105 pub fn new() -> Self {
106 Self {
107 globals: vec![],
108 environment: vec![],
109 scope_pool: vec![],
110 source_file: None,
111 root_module: Module::new(""),
112 return_value: None,
113 is_breaking: false,
114 is_continuing: false,
115 output_buffer: None,
116 rng: Xoshiro256::default(),
117 resolver: Resolver::new(),
118 fn_names: HashMap::new(),
119 user_args_offset: 1,
120 net_handles: HashMap::new(),
121 net_next_handle: 1,
122 http_handles: HashMap::new(),
123 http_next_handle: 1,
124 records: HashMap::new(),
125 tags: HashMap::new(),
126 }
127 }
128
129 pub fn with_source_file(mut self, file: SourceFile) -> Self {
131 self.source_file = Some(file);
132 self
133 }
134
135 pub fn set_source_file(&mut self, file: SourceFile) {
137 self.source_file = Some(file);
138 }
139
140 pub fn with_module(mut self, m: Module) -> Self {
142 self.root_module.submodules.insert(m.name.clone(), m);
143 self
144 }
145
146 pub fn with_function<F, A>(mut self, name: impl Into<String>, f: F) -> Self
148 where
149 F: IntoNativeFn<A>,
150 {
151 self.root_module
152 .functions
153 .insert(name.into(), f.into_native());
154 self
155 }
156
157 pub fn with_stdlib(self) -> Self {
159 self.with_module(
160 Module::new("std")
161 .with_module(stdlib::math::module())
162 .with_module(stdlib::io::module())
163 .with_module(stdlib::bitwise::module())
164 .with_module(stdlib::string::module())
165 .with_module(stdlib::types::module())
166 .with_module(stdlib::array::module())
167 .with_module(stdlib::path::module())
168 .with_module(stdlib::fs::module())
169 .with_module(stdlib::random::module())
170 .with_module(stdlib::time::module())
171 .with_module(stdlib::process::module())
172 .with_module(stdlib::result::module())
173 .with_module(stdlib::terminal::module())
174 .with_module(stdlib::rl::module())
175 .with_module(stdlib::debug::module())
176 .with_module(stdlib::net::module())
177 .with_module(stdlib::http::module()),
178 )
179 }
180
181 pub fn with_user_args_offset(mut self, offset: usize) -> Self {
182 self.user_args_offset = offset;
183 self
184 }
185
186 pub fn err(&self, message: impl Into<String>, span: Span) -> Error {
188 let err = Error::at(Reason::Runtime, message, span);
189 match &self.source_file {
190 Some(file) => err.with_source_file(file),
191 None => err,
192 }
193 }
194
195 pub fn infer_type(value: &Value, is_const: bool) -> TypeAnnotation {
200 match value {
201 Value::Integer(_) => {
202 if is_const {
203 TypeAnnotation::CInt
204 } else {
205 TypeAnnotation::Int
206 }
207 }
208 Value::Float(_) => {
209 if is_const {
210 TypeAnnotation::CFloat
211 } else {
212 TypeAnnotation::Float
213 }
214 }
215 Value::String(_) => {
216 if is_const {
217 TypeAnnotation::CString
218 } else {
219 TypeAnnotation::String
220 }
221 }
222 Value::Bool(_) => {
223 if is_const {
224 TypeAnnotation::CBool
225 } else {
226 TypeAnnotation::Bool
227 }
228 }
229 Value::Byte(_) => {
230 if is_const {
231 TypeAnnotation::CByte
232 } else {
233 TypeAnnotation::Byte
234 }
235 }
236 Value::Char(_) => {
237 if is_const {
238 TypeAnnotation::CChar
239 } else {
240 TypeAnnotation::Char
241 }
242 }
243 Value::Values { items, .. } => {
244 let inner = items
245 .first()
246 .map(|v| Self::infer_type(v, false))
247 .unwrap_or(TypeAnnotation::Null);
248 if is_const {
249 TypeAnnotation::CArray(Box::new(inner))
250 } else {
251 TypeAnnotation::Array(Box::new(inner))
252 }
253 }
254 Value::Set { items, .. } => {
255 let inner = items
256 .first()
257 .map(|v| Self::infer_type(v, false))
258 .unwrap_or(TypeAnnotation::Null);
259 if is_const {
260 TypeAnnotation::CSet(Box::new(inner))
261 } else {
262 TypeAnnotation::Set(Box::new(inner))
263 }
264 }
265 Value::Map {
266 key_type,
267 value_type,
268 ..
269 } => {
270 if is_const {
271 TypeAnnotation::CMap(Box::new(key_type.clone()), Box::new(value_type.clone()))
272 } else {
273 TypeAnnotation::Map(Box::new(key_type.clone()), Box::new(value_type.clone()))
274 }
275 }
276 Value::Struct { name, .. } => {
277 if is_const {
278 TypeAnnotation::CRecord(name.clone())
279 } else {
280 TypeAnnotation::Record(name.clone())
281 }
282 }
283 Value::Enum { name, .. } => {
284 if is_const {
285 TypeAnnotation::CEnum(name.clone())
286 } else {
287 TypeAnnotation::Enum(name.clone())
288 }
289 }
290 Value::Null => TypeAnnotation::Null,
291 Value::Function { .. } => TypeAnnotation::Fn,
292 Value::Tuple(items) => {
293 let inner: Vec<TypeAnnotation> =
294 items.iter().map(|v| Self::infer_type(v, false)).collect();
295 if is_const {
296 TypeAnnotation::CTuple(Rc::new(inner))
297 } else {
298 TypeAnnotation::Tuple(Rc::new(inner))
299 }
300 }
301 Value::Error(_) => {
302 if is_const {
303 TypeAnnotation::CError
304 } else {
305 TypeAnnotation::Error
306 }
307 }
308 Value::Ok(inner) | Value::Err(inner) => {
309 let inner_ty = Self::infer_type(inner, false);
310 if is_const {
311 TypeAnnotation::CResult(Box::new(inner_ty))
312 } else {
313 TypeAnnotation::Result(Box::new(inner_ty))
314 }
315 }
316 }
317 }
318
319 pub fn value_compatible(value: &Value, expected: &TypeAnnotation) -> bool {
321 let actual = Self::infer_type(value, false);
322 Self::types_compatible(&actual, expected)
323 }
324
325 pub fn types_compatible(actual: &TypeAnnotation, expected: &TypeAnnotation) -> bool {
332 if actual == expected {
333 return true;
334 }
335 if *actual == TypeAnnotation::Null {
336 return true;
337 }
338 if *expected == TypeAnnotation::Null {
339 return true;
340 }
341 match (actual, expected) {
342 (
343 TypeAnnotation::Array(a) | TypeAnnotation::CArray(a),
344 TypeAnnotation::Array(b) | TypeAnnotation::CArray(b),
345 ) => Self::types_compatible(a, b),
346 (
347 TypeAnnotation::Tuple(a) | TypeAnnotation::CTuple(a),
348 TypeAnnotation::Tuple(b) | TypeAnnotation::CTuple(b),
349 ) => {
350 a.len() == b.len()
351 && a.iter()
352 .zip(b.iter())
353 .all(|(x, y)| Self::types_compatible(x, y))
354 }
355 (
356 TypeAnnotation::Error | TypeAnnotation::CError,
357 TypeAnnotation::Error | TypeAnnotation::CError,
358 ) => true,
359 (
360 TypeAnnotation::Record(a) | TypeAnnotation::CRecord(a),
361 TypeAnnotation::Record(b) | TypeAnnotation::CRecord(b),
362 ) => a == b,
363 (
364 TypeAnnotation::Result(_) | TypeAnnotation::CResult(_),
365 TypeAnnotation::Result(_) | TypeAnnotation::CResult(_),
366 ) => true,
367 (
368 TypeAnnotation::Enum(a) | TypeAnnotation::CEnum(a),
369 TypeAnnotation::Enum(b) | TypeAnnotation::CEnum(b),
370 ) => a == b,
371 (
372 TypeAnnotation::Map(ak, av) | TypeAnnotation::CMap(ak, av),
373 TypeAnnotation::Map(bk, bv) | TypeAnnotation::CMap(bk, bv),
374 ) => Self::types_compatible(ak, bk) && Self::types_compatible(av, bv),
375 (
376 TypeAnnotation::Set(a) | TypeAnnotation::CSet(a),
377 TypeAnnotation::Set(b) | TypeAnnotation::CSet(b),
378 ) => Self::types_compatible(a, b),
379 _ => false,
380 }
381 }
382
383 pub fn check_not_null(&self, value: &Value, span: Span) -> Result<(), Error> {
385 if matches!(value, Value::Null) {
386 Err(self.err("value is null", span))
387 } else {
388 Ok(())
389 }
390 }
391
392 pub fn evaluate(&mut self, id: ExprId) -> Result<Value, Error> {
393 let span = self.resolver.ast_arena.exprs.get(id).span;
394
395 #[cfg(feature = "debug")]
396 log::trace!("evaluate {:?} @ {:?}", id, span);
397
398 match &self.resolver.ast_arena.exprs.get(id).kind {
399 ExpressionKind::Null => Ok(Value::Null),
400 ExpressionKind::Integer(i) => Ok(Value::Integer(*i)),
401 ExpressionKind::Byte(b) => Ok(Value::Byte(*b)),
402 ExpressionKind::Bool(b) => Ok(Value::Bool(*b)),
403 ExpressionKind::Float(f) => Ok(Value::Float(*f)),
404 ExpressionKind::Character(c) => Ok(Value::Char(*c)),
405 ExpressionKind::String(s) => {
406 let s = s.clone();
407 Ok(Value::String(s))
408 }
409
410 ExpressionKind::Index { target, index } => {
411 let (target, index) = (*target, *index);
412 let target_span = self.resolver.ast_arena.exprs.get(target).span;
413 let index_span = self.resolver.ast_arena.exprs.get(index).span;
414
415 if let ExpressionKind::ResolvedIdentifier { depth, slot, .. } =
416 &self.resolver.ast_arena.exprs.get(target).kind
417 {
418 let (depth, slot) = (*depth, *slot);
419 let idx = self.evaluate(index)?;
420 self.check_not_null(&idx, index_span)?;
421 match idx {
422 Value::Integer(i) => {
423 if i < 0 {
424 return Err(
425 self.err(format!("index cannot be negative: {}", i), span)
426 );
427 }
428 return self.index_read(depth, slot, &[i as usize], span);
429 }
430 Value::Byte(b) => {
431 return self.index_read(depth, slot, &[b as usize], span);
432 }
433 _ => {
434 let arr = self.evaluate(target)?;
435 self.check_not_null(&arr, target_span)?;
436 return self.index_read_value(
437 &arr,
438 &idx,
439 target_span,
440 index_span,
441 span,
442 );
443 }
444 }
445 }
446
447 let arr = self.evaluate(target)?;
448 self.check_not_null(&arr, target_span)?;
449 let idx = self.evaluate(index)?;
450 self.check_not_null(&idx, index_span)?;
451 self.index_read_value(&arr, &idx, target_span, index_span, span)
452 }
453
454 ExpressionKind::ArrayLiteral(items) => {
455 let len = items.len();
456 let mut values = Vec::with_capacity(len);
457 for i in 0..len {
458 let item_id = match &self.resolver.ast_arena.exprs.get(id).kind {
461 ExpressionKind::ArrayLiteral(items) => items[i],
462 _ => unreachable!(),
463 };
464 values.push(self.evaluate(item_id)?);
465 }
466 let items_type = values
467 .first()
468 .map(|v| Self::infer_type(v, false))
469 .unwrap_or(TypeAnnotation::Null);
470
471 if items_type != TypeAnnotation::Null {
472 for (i, v) in values.iter().enumerate() {
473 let actual = Self::infer_type(v, false);
474 if !Self::types_compatible(&actual, &items_type) {
475 return Err(self.err(
476 format!(
477 "array element type mismatch: element {} is {:?}, expected {:?}",
478 i, actual, items_type,
479 ),
480 span,
481 ));
482 }
483 }
484 }
485 Ok(Value::Values {
486 items_type,
487 items: values,
488 })
489 }
490
491 ExpressionKind::SetLiteral(items) => {
492 let len = items.len();
493 let mut values = Vec::with_capacity(len);
494 for i in 0..len {
495 let item_id = match &self.resolver.ast_arena.exprs.get(id).kind {
496 ExpressionKind::SetLiteral(items) => items[i],
497 _ => unreachable!(),
498 };
499 values.push(self.evaluate(item_id)?);
500 }
501 let items_type = values
502 .first()
503 .map(|v| Self::infer_type(v, false))
504 .unwrap_or(TypeAnnotation::Null);
505
506 if items_type != TypeAnnotation::Null {
507 for (i, v) in values.iter().enumerate() {
508 let actual = Self::infer_type(v, false);
509 if !Self::types_compatible(&actual, &items_type) {
510 return Err(self.err(
511 format!(
512 "set element type mismatch: element {} is {:?}, expected {:?}",
513 i, actual, items_type,
514 ),
515 span,
516 ));
517 }
518 }
519 }
520 Ok(Value::Set {
521 items_type,
522 items: values,
523 })
524 }
525
526 ExpressionKind::MapLiteral(entries) => {
527 let len = entries.len();
528 let mut map = HashMap::with_capacity(len);
529 let mut key_type = TypeAnnotation::Null;
530 let mut value_type = TypeAnnotation::Null;
531
532 for i in 0..len {
533 let (key_id, value_id) = match &self.resolver.ast_arena.exprs.get(id).kind {
534 ExpressionKind::MapLiteral(entries) => entries[i],
535 _ => unreachable!(),
536 };
537 let key_val = self.evaluate(key_id)?;
538 let value_val = self.evaluate(value_id)?;
539
540 if i == 0 {
541 key_type = Self::infer_type(&key_val, false);
542 value_type = Self::infer_type(&value_val, false);
543 } else {
544 let actual_key = Self::infer_type(&key_val, false);
545 if !Self::types_compatible(&actual_key, &key_type) {
546 return Err(self.err(
547 format!(
548 "map key type mismatch: entry {} key is {:?}, expected {:?}",
549 i, actual_key, key_type
550 ),
551 span,
552 ));
553 }
554 let actual_value = Self::infer_type(&value_val, false);
555 if !Self::types_compatible(&actual_value, &value_type) {
556 return Err(self.err(
557 format!("map value type mismatch: entry {} value is {:?}, expected {:?}", i, actual_value, value_type),
558 span,
559 ));
560 }
561 }
562
563 let map_key = MapKey::from_value(&key_val).ok_or_else(|| {
564 self.err(
565 format!("type {} cannot be used as a map key", key_val.type_name()),
566 span,
567 )
568 })?;
569 map.insert(map_key, value_val);
570 }
571
572 Ok(Value::Map {
573 key_type,
574 value_type,
575 entries: Rc::new(RefCell::new(map)),
576 })
577 }
578
579 ExpressionKind::IndexAssign {
580 target,
581 index,
582 value,
583 } => {
584 let (target, index, value) = (*target, *index, *value);
585 self.index_assign(target, index, value, span)
586 }
587
588 ExpressionKind::Grouping(inner) => {
589 let inner = *inner;
590 self.evaluate(inner)
591 }
592
593 ExpressionKind::Binary {
594 left,
595 operator,
596 right,
597 } => {
598 let (left, operator, right) = (*left, operator.clone(), *right);
599
600 if matches!(operator, TokenType::And) {
601 let l = self.evaluate(left)?;
602 if let Value::Bool(false) = l {
603 return Ok(Value::Bool(false));
604 }
605 let r = self.evaluate(right)?;
606 return Ok(Value::Bool(matches!(r, Value::Bool(true))));
607 }
608
609 if matches!(operator, TokenType::Or) {
610 let l = self.evaluate(left)?;
611 if let Value::Bool(true) = l {
612 return Ok(Value::Bool(true));
613 }
614 let r = self.evaluate(right)?;
615 return Ok(Value::Bool(matches!(r, Value::Bool(true))));
616 }
617
618 let left_span = self.resolver.ast_arena.exprs.get(left).span;
619 let right_span = self.resolver.ast_arena.exprs.get(right).span;
620
621 let left_val = self.evaluate(left)?;
622 let right_val = self.evaluate(right)?;
623 if matches!(operator, TokenType::Compare | TokenType::BangEqual)
624 && (matches!(left_val, Value::Null) || matches!(right_val, Value::Null))
625 {
626 let result = matches!((&left_val, &right_val), (Value::Null, Value::Null));
627 return Ok(if matches!(operator, TokenType::Compare) {
628 Value::Bool(result)
629 } else {
630 Value::Bool(!result)
631 });
632 }
633 self.check_not_null(&left_val, left_span)?;
634 self.check_not_null(&right_val, right_span)?;
635 self.match_binary_operator(
636 left_val, left_span, right_val, right_span, &operator, span,
637 )
638 }
639
640 ExpressionKind::Unary { operator, operand } => {
641 let (operator, operand) = (operator.clone(), *operand);
642 let operand_span = self.resolver.ast_arena.exprs.get(operand).span;
643 let operand_val = self.evaluate(operand)?;
644 self.check_not_null(&operand_val, operand_span)?;
645 self.match_unary_operator(operand_val, operand_span, &operator, span)
646 }
647
648 ExpressionKind::ResolvedIdentifier { depth, slot, .. } => {
649 let (depth, slot) = (*depth, *slot);
650 self.get_value(depth, slot, span)
651 }
652
653 ExpressionKind::ResolvedAssign {
654 depth, slot, value, ..
655 } => {
656 let (depth, slot, value) = (*depth, *slot, *value);
657 let val = self.evaluate(value)?;
658 let inferred_type = Self::infer_type(&val, false);
659 self.assign_value(depth, slot, val.clone(), inferred_type, span)?;
660 Ok(val)
661 }
662
663 ExpressionKind::Call { .. } => {
664 let (path, len) = match &self.resolver.ast_arena.exprs.get(id).kind {
665 ExpressionKind::Call { path, args } => (path.clone(), args.len()),
666 _ => unreachable!(),
667 };
668 let mut evaluated_args = Vec::with_capacity(len);
669 for i in 0..len {
670 let arg_id = match &self.resolver.ast_arena.exprs.get(id).kind {
671 ExpressionKind::Call { args, .. } => args[i],
672 _ => unreachable!(),
673 };
674 evaluated_args.push(self.evaluate(arg_id)?);
675 }
676 self.call_path(&path, evaluated_args, span)
677 }
678
679 ExpressionKind::CallExpr { .. } => {
680 let (callee, len) = match &self.resolver.ast_arena.exprs.get(id).kind {
681 ExpressionKind::CallExpr { callee, args } => (*callee, args.len()),
682 _ => unreachable!(),
683 };
684 let func_val = self.evaluate(callee)?;
685 let mut evaluated_args = Vec::with_capacity(len);
686 for i in 0..len {
687 let arg_id = match &self.resolver.ast_arena.exprs.get(id).kind {
688 ExpressionKind::CallExpr { args, .. } => args[i],
689 _ => unreachable!(),
690 };
691 evaluated_args.push(self.evaluate(arg_id)?);
692 }
693 self.call_value(func_val, evaluated_args, span)
694 }
695
696 ExpressionKind::MethodCall { .. } => {
697 let (caller, method, len) = match &self.resolver.ast_arena.exprs.get(id).kind {
698 ExpressionKind::MethodCall {
699 caller,
700 method,
701 args,
702 } => (*caller, method.clone(), args.len()),
703 _ => unreachable!(),
704 };
705 let first_arg = self.evaluate(caller)?;
706 let mut evaluated_args = vec![first_arg];
707 for i in 0..len {
708 let arg_id = match &self.resolver.ast_arena.exprs.get(id).kind {
709 ExpressionKind::MethodCall { args, .. } => args[i],
710 _ => unreachable!(),
711 };
712 evaluated_args.push(self.evaluate(arg_id)?);
713 }
714 self.call_path(&method, evaluated_args, span)
715 }
716
717 ExpressionKind::ResolvedLambda { .. } => {
718 let (params, body, return_type, capture_depth) =
719 match &self.resolver.ast_arena.exprs.get(id).kind {
720 ExpressionKind::ResolvedLambda {
721 params,
722 body,
723 return_type,
724 capture_depth,
725 } => (
726 params.clone(),
727 body.clone(),
728 return_type.clone(),
729 *capture_depth,
730 ),
731 _ => unreachable!(),
732 };
733 let total = self.environment.len();
734 let start = total.saturating_sub(capture_depth);
735 let captured_env: Vec<Vec<EnvironmentItem>> = self.environment[start..].to_vec();
736
737 Ok(Value::Function(Rc::new(FunctionData {
738 params: Rc::new(params),
739 body: Rc::new(body),
740 return_type,
741 captured_env,
742 })))
743 }
744
745 ExpressionKind::Identifier(name) => {
746 Err(self.err(format!("undefined variable '{}'", name), span))
747 }
748 ExpressionKind::Assign { name, .. } => {
749 Err(self.err(format!("undefined variable '{}'", name), span))
750 }
751
752 ExpressionKind::Cast { value, target_type } => {
753 let (value, target_type) = (*value, target_type.clone());
754 let value_span = self.resolver.ast_arena.exprs.get(value).span;
755 let val = self.evaluate(value)?;
756 self.check_not_null(&val, value_span)?;
757 match (&val, &target_type) {
758 (Value::Integer(n), TypeAnnotation::Float) => Ok(Value::Float(*n as f64)),
759 (Value::Integer(n), TypeAnnotation::Byte) => Ok(Value::Byte(*n as u8)),
760 (Value::Integer(_), TypeAnnotation::Int) => Ok(val),
761 (Value::Float(f), TypeAnnotation::Int) => Ok(Value::Integer(*f as i64)),
762 (Value::Float(f), TypeAnnotation::Byte) => Ok(Value::Byte(*f as u8)),
763 (Value::Float(_), TypeAnnotation::Float) => Ok(val),
764 (Value::Byte(b), TypeAnnotation::Float) => Ok(Value::Float(*b as f64)),
765 (Value::Byte(b), TypeAnnotation::Int) => Ok(Value::Integer(*b as i64)),
766 (Value::Byte(_), TypeAnnotation::Byte) => Ok(val),
767 _ => Err(self.err(
768 format!(
769 "invalid cast: cannot cast {} to {:?}",
770 val.type_name(),
771 target_type
772 ),
773 span,
774 )),
775 }
776 }
777
778 ExpressionKind::TupleLiteral(items) => {
779 let len = items.len();
780 let mut values = Vec::with_capacity(len);
781 for i in 0..len {
782 let item_id = match &self.resolver.ast_arena.exprs.get(id).kind {
783 ExpressionKind::TupleLiteral(items) => items[i],
784 _ => unreachable!(),
785 };
786 values.push(self.evaluate(item_id)?);
787 }
788 Ok(Value::Tuple(values))
789 }
790
791 ExpressionKind::ErrorLiteral(inner) => {
792 let inner = *inner;
793 let val = self.evaluate(inner)?;
794 if matches!(val, Value::Error(_)) {
795 return Err(self.err("error cannot wrap another error", span));
796 }
797 Ok(Value::Error(Box::new(val)))
798 }
799 ExpressionKind::OkLiteral(inner) => {
800 let inner = *inner;
801 let val = self.evaluate(inner)?;
802 Ok(Value::Ok(Box::new(val)))
803 }
804 ExpressionKind::ErrLiteral(inner) => {
805 let inner = *inner;
806 let val = self.evaluate(inner)?;
807 Ok(Value::Err(Box::new(val)))
808 }
809
810 ExpressionKind::Propagate(inner) => {
811 let inner = *inner;
812 let val = self.evaluate(inner)?;
813 match val {
814 Value::Ok(v) => Ok(*v),
815 Value::Err(_) => {
816 self.return_value = Some(val);
817 Ok(Value::Null)
818 }
819 other => Ok(other),
820 }
821 }
822
823 ExpressionKind::StructLiteral { .. } => {
824 let (name, fields) = match &self.resolver.ast_arena.exprs.get(id).kind {
825 ExpressionKind::StructLiteral { name, fields } => {
826 (name.clone(), fields.clone())
827 }
828 _ => unreachable!(),
829 };
830
831 let mut evaluated: Vec<(String, Value)> = Vec::with_capacity(fields.len());
832 for (field_name, value_id) in &fields {
833 let value = self.evaluate(*value_id)?;
834 evaluated.push((field_name.clone(), value));
835 }
836
837 if let Some(declared_fields) = self.records.get(&name).cloned() {
838 if declared_fields.len() != evaluated.len() {
839 return Err(self.err(
840 format!(
841 "record `{}` expects {} field(s), got {}",
842 name,
843 declared_fields.len(),
844 evaluated.len()
845 ),
846 span,
847 ));
848 }
849
850 let mut ordered: Vec<(String, Value)> =
851 Vec::with_capacity(declared_fields.len());
852 for (field_name, field_type) in &declared_fields {
853 let Some((_, value)) = evaluated.iter().find(|(n, _)| n == field_name)
854 else {
855 return Err(self.err(
856 format!("record `{}` is missing field `{}`", name, field_name),
857 span,
858 ));
859 };
860 let value_type = Self::infer_type(value, false);
861 if !Self::types_compatible(&value_type, field_type)
862 && value_type != TypeAnnotation::Null
863 {
864 return Err(self.err(
865 format!(
866 "field `{}` of record `{}` expects {:?}, got {:?}",
867 field_name, name, field_type, value_type
868 ),
869 span,
870 ));
871 }
872 ordered.push((field_name.clone(), value.clone()));
873 }
874 for (field_name, _) in &evaluated {
875 if !declared_fields.iter().any(|(n, _)| n == field_name) {
876 return Err(self.err(
877 format!("record `{}` has no field `{}`", name, field_name),
878 span,
879 ));
880 }
881 }
882
883 Ok(Value::Struct {
884 name,
885 fields: Rc::new(std::cell::RefCell::new(ordered)),
886 })
887 } else {
888 Ok(Value::Struct {
889 name,
890 fields: Rc::new(std::cell::RefCell::new(evaluated)),
891 })
892 }
893 }
894
895 ExpressionKind::FieldAccess { .. } => {
896 let (target, field) = match &self.resolver.ast_arena.exprs.get(id).kind {
897 ExpressionKind::FieldAccess { target, field } => (*target, field.clone()),
898 _ => unreachable!(),
899 };
900 let target_span = self.resolver.ast_arena.exprs.get(target).span;
901 let target_val = self.evaluate(target)?;
902 match target_val {
903 Value::Struct { name, fields } => {
904 let fields = fields.borrow();
905 match fields.iter().find(|(n, _)| *n == field) {
906 Some((_, value)) => Ok(value.clone()),
907 None => Err(self
908 .err(format!("record `{}` has no field `{}`", name, field), span)),
909 }
910 }
911 other => Err(self
912 .err(
913 format!("cannot access field `{}` on {}", field, other.type_name()),
914 span,
915 )
916 .with_label(target_span, format!("this is {}", other.type_name()))),
917 }
918 }
919
920 ExpressionKind::FieldAssign { .. } => {
921 let (target, field, value) = match &self.resolver.ast_arena.exprs.get(id).kind {
922 ExpressionKind::FieldAssign {
923 target,
924 field,
925 value,
926 } => (*target, field.clone(), *value),
927 _ => unreachable!(),
928 };
929 let target_span = self.resolver.ast_arena.exprs.get(target).span;
930 let target_val = self.evaluate(target)?;
931 let new_val = self.evaluate(value)?;
932 match target_val {
933 Value::Struct { name, fields } => {
934 let mut fields = fields.borrow_mut();
935 match fields.iter_mut().find(|(n, _)| *n == field) {
936 Some((_, slot)) => {
937 *slot = new_val.clone();
938 Ok(new_val)
939 }
940 None => Err(self
941 .err(format!("record `{}` has no field `{}`", name, field), span)),
942 }
943 }
944 other => Err(self
945 .err(
946 format!("cannot assign field `{}` on {}", field, other.type_name()),
947 span,
948 )
949 .with_label(target_span, format!("this is {}", other.type_name()))),
950 }
951 }
952
953 ExpressionKind::EnumVariant { .. } => {
954 let (enum_name, variant) = match &self.resolver.ast_arena.exprs.get(id).kind {
955 ExpressionKind::EnumVariant { enum_name, variant } => {
956 (enum_name.clone(), variant.clone())
957 }
958 _ => unreachable!(),
959 };
960
961 if let Some(declared_variants) = self.tags.get(&enum_name)
962 && !declared_variants.contains(&variant)
963 {
964 return Err(self.err(
965 format!("tag `{}` has no variant `{}`", enum_name, variant),
966 span,
967 ));
968 }
969
970 Ok(Value::Enum {
971 name: enum_name,
972 variant,
973 })
974 }
975
976 _ => Ok(Value::Null),
977 }
978 }
979
980 pub fn call_value(
985 &mut self,
986 func: Value,
987 args: Vec<Value>,
988 span: Span,
989 ) -> Result<Value, Error> {
990 if let Value::Function(data) = func {
991 if data.params.len() != args.len() {
992 return Err(self.err(
993 format!(
994 "function expects {} argument(s), got {}",
995 data.params.len(),
996 args.len()
997 ),
998 span,
999 ));
1000 }
1001
1002 let saved_env = std::mem::replace(&mut self.environment, data.captured_env.clone());
1003 let saved_return = self.return_value.take();
1004
1005 self.push_scope();
1006
1007 for (slot, (_, arg)) in data.params.iter().zip(args).enumerate() {
1008 let arg_type = Self::infer_type(&arg, false);
1009 self.insert_value(slot, arg, arg_type, span)?;
1010 }
1011
1012 for statement in &*data.body {
1013 self.evaluate_statement(statement)?;
1014 if self.return_value.is_some() {
1015 break;
1016 }
1017 }
1018
1019 let result = self.return_value.take().unwrap_or(Value::Null);
1020
1021 self.environment = saved_env;
1022 self.return_value = saved_return;
1023
1024 if let Some(expected) = &data.return_type
1025 && *expected != TypeAnnotation::Null
1026 {
1027 let actual = Self::infer_type(&result, false);
1028 if !Self::types_compatible(&actual, expected) {
1029 return Err(self.err(
1030 format!(
1031 "function declared to return {:?} but returned {:?}",
1032 expected, actual
1033 ),
1034 span,
1035 ));
1036 }
1037 }
1038
1039 return Ok(result);
1040 }
1041
1042 Err(self.err("value is not callable", span))
1043 }
1044
1045 pub fn call_path(
1053 &mut self,
1054 path: &[String],
1055 args: Vec<Value>,
1056 span: Span,
1057 ) -> Result<Value, Error> {
1058 if let Some(f) = self.root_module.resolve(path) {
1059 let f = Arc::clone(f);
1060 return match f(self, args, span) {
1061 Ok(v) => Ok(v),
1062 Err(e) if e.span().is_some() => Err(match &self.source_file {
1063 Some(file) => e.with_source_file(file),
1064 None => e,
1065 }),
1066 Err(e) => Err(self.err(e.message(), span)),
1067 };
1068 }
1069 if path.len() == 1
1070 && let Some(&slot) = self.fn_names.get(&path[0])
1071 {
1072 let func = self.get_value(0, slot, span)?;
1073 return self.call_value(func, args, span);
1074 }
1075 let mut err = self.err(format!("undefined function {}", path.join("::")), span);
1076 if let Some(last) = path.last() {
1078 let candidates = stdlib::math::KEYWORDS
1079 .iter()
1080 .chain(stdlib::math::constants::KEYWORDS)
1081 .chain(stdlib::bitwise::KEYWORDS)
1082 .chain(stdlib::io::KEYWORDS)
1083 .chain(stdlib::string::KEYWORDS)
1084 .chain(stdlib::types::KEYWORDS)
1085 .chain(stdlib::array::KEYWORDS)
1086 .chain(stdlib::path::KEYWORDS)
1087 .chain(stdlib::fs::KEYWORDS)
1088 .chain(stdlib::random::KEYWORDS)
1089 .chain(stdlib::time::KEYWORDS)
1090 .chain(stdlib::process::KEYWORDS)
1091 .chain(stdlib::result::KEYWORDS)
1092 .chain(stdlib::terminal::KEYWORDS)
1093 .chain(stdlib::rl::KEYWORDS)
1094 .chain(stdlib::debug::KEYWORDS)
1095 .chain(stdlib::net::KEYWORDS)
1096 .chain(stdlib::http::KEYWORDS)
1097 .copied();
1098 if let Some(suggestion) = closest_match(last, candidates) {
1099 err = err.with_help(format!("did you mean `{}`?", suggestion));
1100 }
1101 }
1102 Err(err)
1103 }
1104}