1use std::fs;
3
4use crate::{
5 ast::*,
6 environment::Environment,
7 lexer::Lexer,
8 parser::Parser,
9 value::{Text, Value},
10};
11pub struct Interpreter {
12 env: Environment,
13}
14impl Interpreter {
15 pub fn new(env: Environment,) -> Self {
16 Self { env, }
17 }
18 pub fn eval_stmt(
19 &mut self,
20 stmt: &Stmt,
21 ) -> Result<Option<Value,>, String,> {
22 match stmt {
23 Stmt::Decl { name, init, } => {
24 let value = match init {
25 Some(expr,) => self.eval_expr(expr,)?,
26 None => Value::Text(Text::Empty,),
27 };
28 self.env.declare_var(name, value,)?;
29 Ok(None,)
30 },
31 Stmt::Print { expr, } => {
32 let val = self.eval_expr(expr,)?;
33 let text = val.expect_text();
34 println!("{}", text);
35 Ok(None,)
36 },
37 Stmt::External { path, functions, } => {
38 self.env.register_external_functions(path, functions,)?;
39 Ok(None,)
40 },
41 Stmt::Mod { path, } => {
42 let module_env = self.run_module(path,)?;
43 for (name, value,) in module_env.variables {
44 if self.env.has_var(&name,) {
45 return Err(format!(
46 "Variable '{}' already defined in current scope",
47 name
48 ),);
49 }
50 self.env.declare_var(&name, value,)?;
51 }
52 Ok(None,)
53 },
54 Stmt::Call { func, arg, } => {
55 let func_val = self.env.get_function(func,)?.clone();
56 let arg_val = self.eval_expr(arg,)?;
57 let arg_text = arg_val.expect_text().clone();
58 match func_val {
59 Value::NativeFunction(f,) => {
60 f(arg_text,);
61 Ok(None,)
62 },
63 _ => Err(format!("Function {} is not callable", func),),
64 }
65 },
66 Stmt::Lua { path, mappings, } => {
67 let lua_state = self.env.load_lua_script(path,)?;
68 for (dar_name, lua_func_name,) in mappings {
69 self.env.register_lua_function(
70 dar_name,
71 lua_func_name,
72 lua_state.clone(),
73 )?;
74 }
75 Ok(None,)
76 },
77 }
78 }
79 pub fn eval_expr(&mut self, expr: &Expr,) -> Result<Value, String,> {
80 match expr {
81 Expr::Variable(name,) => {
82 let val = self.env.get_var(name,)?;
83 Ok(val.clone(),)
84 },
85 Expr::StringLiteral(s,) => {
86 Ok(Value::Text(Text::Value(s.clone(),),),)
87 },
88 Expr::EmptyLiteral => Ok(Value::Text(Text::Empty,),),
89 Expr::MethodCall { obj, method, } => {
90 let obj_val = self.eval_expr(obj,)?;
91 let text = obj_val.expect_text().clone();
92 let result = match method {
93 Method::Upper => match text {
94 Text::Empty => {
95 return Err("runtime error: called .Upper() on \
96 empty"
97 .to_string(),);
98 },
99 Text::Value(s,) => Text::Value(s.to_uppercase(),),
100 },
101 };
102 Ok(Value::Text(result,),)
103 },
104 Expr::Call { func, arg, } => {
105 let func_val = self.env.get_function(func,)?.clone();
106 let arg_val = self.eval_expr(arg,)?;
107 let arg_text = arg_val.expect_text().clone();
108 match func_val {
109 Value::NativeFunction(f,) => {
110 Ok(Value::Text(f(arg_text,),),)
111 },
112 _ => Err(format!("Function {} is not callable", func),),
113 }
114 },
115 }
116 }
117 pub fn run(&mut self, stmts: &[Stmt],) -> Result<(), String,> {
118 for stmt in stmts {
119 self.eval_stmt(stmt,)?;
120 }
121 Ok((),)
122 }
123 pub fn run_module(&mut self, path: &str,) -> Result<Environment, String,> {
124 let source = fs::read_to_string(path,)
125 .map_err(|e| format!("Failed to read module '{}': {}", path, e),)?;
126 let lexer = Lexer::new(&source,);
127 let mut parser = Parser::new(lexer,)
128 .map_err(|e| format!("Module parse error: {}", e),)?;
129 let stmts =
130 parser.parse().map_err(|e| format!("Module parse error: {}", e),)?;
131 let module_env = Environment::new();
132 let old_env = std::mem::replace(&mut self.env, module_env,);
133 for stmt in &stmts {
134 self.eval_stmt(stmt,)?;
135 }
136 let module_env = std::mem::replace(&mut self.env, old_env,);
137 Ok(module_env,)
138 }
139}