aplang_lib/interpreter/
procedure.rs1use crate::interpreter::errors::RuntimeError;
2use crate::interpreter::{Interpreter, Value};
3use crate::parser::ast::{ProcDeclaration, Stmt, Variable};
4use miette::SourceSpan;
5use std::collections::HashMap;
6use std::rc::Rc;
7use std::sync::Arc;
8
9pub type FunctionMap = HashMap<String, (Rc<dyn Callable>, Option<Arc<ProcDeclaration>>)>;
10pub trait Callable {
17 fn call(
18 &self,
19 interpreter: &mut Interpreter,
20 args: &[Value],
21 args_tokens: &[SourceSpan],
22 source: Arc<str>,
23 ) -> Result<Value, RuntimeError>;
24 fn arity(&self) -> u8;
25}
26
27pub struct Procedure {
28 pub name: String,
29 pub params: Vec<Variable>,
30 pub body: Stmt,
31}
32
33impl Callable for Procedure {
34 fn call(
35 &self,
36 interpreter: &mut Interpreter,
37 args: &[Value],
38 args_tokens: &[SourceSpan],
39 source: Arc<str>,
40 ) -> Result<Value, RuntimeError> {
41 let cached_return_value = interpreter.return_value.clone();
43
44 interpreter.venv.initialize_empty_scope();
47
48 self.params
51 .iter()
52 .zip(args.iter().cloned())
53 .for_each(|(param, arg)| interpreter.venv.define(Arc::new(param.clone()), arg));
54
55 interpreter.stmt(&self.body)?;
57
58 let return_value = interpreter.return_value.clone();
59 interpreter.return_value = cached_return_value;
61
62 interpreter.venv.scrape();
64
65 match return_value {
66 None => Ok(Value::Null),
67 Some(value) => Ok(value),
68 }
69 }
70
71 fn arity(&self) -> u8 {
72 self.params.len().try_into().unwrap()
73 }
74}
75
76pub struct NativeProcedure {
77 pub name: String,
78 pub arity: u8,
79 pub callable: fn(
80 &mut Interpreter,
81 &[Value],
82 args_tokens: &[SourceSpan],
83 source: Arc<str>,
84 ) -> Result<Value, RuntimeError>,
85}
86
87impl Callable for NativeProcedure {
88 fn call(
89 &self,
90 interpreter: &mut Interpreter,
91 args: &[Value],
92 args_tokens: &[SourceSpan],
93 source: Arc<str>,
94 ) -> Result<Value, RuntimeError> {
95 (self.callable)(interpreter, args, args_tokens, source)
96 }
97
98 fn arity(&self) -> u8 {
99 self.arity
100 }
101}