1use std::{
4 error::Error,
5 fmt::Display,
6 ops::{Add, Div, Mul, Sub},
7};
8
9use sf::Stack;
10
11use crate::parser::ast::{BinaryOp, Expr, Literal, UnaryOp};
12
13pub mod sf;
14
15#[derive(Debug, Default, Clone)]
17pub struct Interpretter<'a> {
18 stack: Stack<'a>,
20}
21
22#[derive(Debug, Clone)]
24pub struct RuntimeError(pub String);
25
26impl Display for RuntimeError {
27 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
28 write!(f, "{}", self.0)
29 }
30}
31
32impl Error for RuntimeError {}
33
34impl<'a> Interpretter<'a> {
35 pub fn eval(&mut self, ast: &Expr<'a>) -> Result<Literal<'a>, RuntimeError> {
37 match ast {
38 Expr::ForLoop {
39 init,
40 cond,
41 inc,
42 exec,
43 } => {
44 self.eval(init)?;
45 while self.eval(cond)?.bool()? {
46 self.eval(exec)?;
47 self.eval(inc)?;
48 }
49
50 Ok(Literal::Null)
51 }
52 Expr::WhileLoop { condition, eval } => {
53 while self.eval(condition)?.bool()? {
54 self.eval(eval)?;
55 }
56
57 Ok(Literal::Null)
58 }
59 Expr::Conditional {
60 condition,
61 true_branch,
62 else_branch,
63 } => {
64 let condition = self.eval(condition)?.bool()?;
65
66 if condition {
67 self.eval(true_branch)
68 } else if let Some(else_branch) = else_branch {
69 self.eval(else_branch)
70 } else {
71 Ok(Literal::Null)
72 }
73 }
74 Expr::Block(all) => {
75 for val in all {
76 self.eval(val)?;
77 }
78
79 Ok(Literal::Null)
80 }
81 Expr::Variable(var) => self.stack.get(var).cloned(),
82 Expr::Print(node) => {
83 println!("{}", self.eval(node)?);
84 Ok(Literal::Null)
85 }
86 Expr::Assignment(name, val) => {
87 let val = self.eval(val)?;
88 self.stack.set(name.to_string(), val);
89 Ok(Literal::Null)
90 }
91 Expr::Literal(l) => Ok(*l),
92 Expr::Grouping(inner) => self.eval(inner),
93 Expr::Binary { op, left, right } => op.eval(self.eval(left)?, self.eval(right)?),
94 Expr::Unary { op, node } => op.eval(self.eval(node)?),
95 }
96 }
97}
98
99impl BinaryOp {
100 pub fn eval<'a>(
102 &self,
103 left: Literal<'a>,
104 right: Literal<'a>,
105 ) -> Result<Literal<'a>, RuntimeError> {
106 match self {
107 Self::Add => left + right,
108 Self::Sub => left - right,
109 Self::Mul => left * right,
110 Self::Div => left / right,
111
112 Self::Gt => Ok(Literal::Bool(left.number()? > right.number()?)),
113 Self::Gte => Ok(Literal::Bool(left.number()? >= right.number()?)),
114 Self::Lt => Ok(Literal::Bool(left.number()? < right.number()?)),
115 Self::Lte => Ok(Literal::Bool(left.number()? <= right.number()?)),
116
117 Self::Eq => left.equals(&right),
118 Self::Neq => left.not_equals(&right),
119 }
120 }
121}
122
123impl UnaryOp {
124 pub fn eval<'a>(&self, node: Literal<'a>) -> Result<Literal<'a>, RuntimeError> {
126 match self {
127 Self::Neg => Ok(Literal::Number(-node.number()?)),
128 Self::Not => Ok(Literal::Bool(!node.bool()?)),
129 }
130 }
131}
132
133impl Literal<'_> {
134 pub fn type_of(&self) -> &'static str {
136 match self {
137 Self::Number(_) => "number",
138 Self::String(_) => "string",
139 Self::Bool(_) => "bool",
140 Self::Null => "null",
141 }
142 }
143}
144
145impl Add for Literal<'_> {
146 type Output = Result<Self, RuntimeError>;
147
148 fn add(self, rhs: Self) -> Self::Output {
149 match (self, rhs) {
150 (Self::Number(n1), Self::Number(n2)) => Ok(Literal::Number(n1 + n2)),
151
152 _ => Err(RuntimeError(format!(
153 "Can't add literals of type {} and {} together",
154 self.type_of(),
155 rhs.type_of(),
156 ))),
157 }
158 }
159}
160
161impl Sub for Literal<'_> {
162 type Output = Result<Self, RuntimeError>;
163 fn sub(self, rhs: Self) -> Self::Output {
164 match (self, rhs) {
165 (Self::Number(n1), Self::Number(n2)) => Ok(Self::Number(n1 - n2)),
166
167 _ => Err(RuntimeError(format!(
168 "Can't subtract literals of type {} and {} together",
169 self.type_of(),
170 rhs.type_of(),
171 ))),
172 }
173 }
174}
175
176impl Mul for Literal<'_> {
177 type Output = Result<Self, RuntimeError>;
178 fn mul(self, rhs: Self) -> Self::Output {
179 match (self, rhs) {
180 (Self::Number(n1), Self::Number(n2)) => Ok(Self::Number(n1 * n2)),
181
182 _ => Err(RuntimeError(format!(
183 "Can't multiply literals of type {} and {} together",
184 self.type_of(),
185 rhs.type_of(),
186 ))),
187 }
188 }
189}
190
191impl Div for Literal<'_> {
192 type Output = Result<Self, RuntimeError>;
193 fn div(self, rhs: Self) -> Self::Output {
194 match (self, rhs) {
195 (Self::Number(n1), Self::Number(n2)) => Ok(Self::Number(n1 / n2)),
196 _ => Err(RuntimeError(format!(
197 "Can't divide literals of type {} and {} together",
198 self.type_of(),
199 rhs.type_of(),
200 ))),
201 }
202 }
203}
204
205impl<'a> Literal<'a> {
206 pub fn uint(&self) -> Result<usize, RuntimeError> {
209 match self {
210 Self::Number(n) if *n >= 0.0 && n.round() == *n => Ok(*n as usize),
211 _ => Err(RuntimeError(format!("{self} is not an unsigned integer"))),
212 }
213 }
214 pub fn number(&self) -> Result<f64, RuntimeError> {
216 match self {
217 Self::Number(n) => Ok(*n),
218 _ => Err(RuntimeError(format!("{self} is not a number"))),
219 }
220 }
221
222 pub fn bool(&self) -> Result<bool, RuntimeError> {
224 match self {
225 Self::Bool(val) => Ok(*val),
226 Self::Number(0.0) => Ok(false),
227 Self::Number(_) => Ok(true),
228 _ => Err(RuntimeError(format!("{self} is not a boolean"))),
229 }
230 }
231
232 pub fn equals(&self, other: &Self) -> Result<Literal<'a>, RuntimeError> {
234 match (self, other) {
235 (Self::Number(n1), Self::Number(n2)) => Ok(Self::Bool(n1 == n2)),
236 (Self::Bool(b1), Self::Bool(b2)) => Ok(Self::Bool(b1 == b2)),
237
238 (Self::Null, Self::Null) => Ok(Self::Bool(true)),
239
240 (crazy1, crazy2) => Ok(Literal::Bool(crazy1.to_string() == crazy2.to_string())),
241 }
242 }
243
244 pub fn not_equals(&self, other: &Self) -> Result<Literal<'a>, RuntimeError> {
246 match (self, other) {
247 (Self::Number(n1), Self::Number(n2)) => Ok(Self::Bool(n1 != n2)),
248 (Self::Bool(b1), Self::Bool(b2)) => Ok(Self::Bool(b1 != b2)),
249
250 (Self::Null, Self::Null) => Ok(Self::Bool(false)),
251
252 (crazy1, crazy2) => Ok(Literal::Bool(crazy1.to_string() != crazy2.to_string())),
253 }
254 }
255}