Skip to content

Commit 189e8c2

Browse files
committed
chore: fixes
1 parent bffa5be commit 189e8c2

File tree

5 files changed

+85
-52
lines changed

5 files changed

+85
-52
lines changed

examples/fibonacci.bas

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
0 CLS
2+
10 PRINT "FIBONACCI SEQUENCE"
3+
20 PRINT "ENTER THE NUMBER OF TERMS TO CALCULATE"
4+
30 INPUT N
5+
40 LET A=0
6+
41 LET B=1
7+
43 LET F = 0
8+
60 PRINT F
9+
70 LET A = B
10+
71 LET B = F
11+
72 LET F = A + B
12+
74 LET N = N - 1
13+
80 IF N > 0 THEN GOTO 60
14+
90 END

src/ast.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ pub struct Identifier {
4848

4949
#[derive(Debug, Clone, PartialEq)]
5050
pub enum Literal {
51-
Number { value: usize },
51+
Number { value: f32 },
5252
String { value: String },
5353
}
5454

src/interpreter.rs

Lines changed: 53 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::ast::{
2-
ArithmeticOperator, Expression, Identifier, IfCondition, Line, Literal, RelationOperator,
3-
Statement, VarDeclaration,
2+
ArithmeticOperator, BinaryExpression, Expression, Identifier, IfCondition, Line, Literal,
3+
RelationOperator, Statement, UnaryExpression, UnaryOperator, VarDeclaration,
44
};
55
use crate::errors::RuntimeError;
66
use crate::parser::Parser;
@@ -14,7 +14,7 @@ use crate::io::{clear, load_file, read_line, save_file, set_prompt, write_line};
1414

1515
#[derive(Debug, Clone, PartialEq)]
1616
enum Value {
17-
Number(usize),
17+
Number(f32),
1818
String(String),
1919
// Boolean(bool),
2020
None,
@@ -84,52 +84,64 @@ impl Interpreter {
8484
match value {
8585
Some(value) => Ok(value.clone()),
8686
None => Err(RuntimeError::UndefinedVariable(
87-
self.context
88-
.program
89-
.get(self.context.current_line)
90-
.unwrap()
91-
.source,
87+
format!("{}", identifier.name).to_string(),
9288
)),
9389
}
9490
}
95-
Expression::Literal(literal) => match literal {
96-
Literal::Number { value } => Ok(Value::Number(*value)),
97-
Literal::String { value } => Ok(Value::String(value.clone())),
98-
},
99-
Expression::BinaryExpression(binary) => {
100-
let left = self.visit_expression(&binary.left)?;
101-
let right = self.visit_expression(&binary.right)?;
102-
103-
match (left, right) {
104-
(Value::Number(left), Value::Number(right)) => {
105-
let result = match binary.operator {
106-
ArithmeticOperator::Add => left + right,
107-
ArithmeticOperator::Subtract => left - right,
108-
ArithmeticOperator::Multiply => left * right,
109-
ArithmeticOperator::Divide => left / right,
110-
};
111-
112-
Ok(Value::Number(result))
113-
}
114-
(Value::String(left), Value::String(right)) => {
115-
let result = match binary.operator {
116-
ArithmeticOperator::Add => left + &right,
117-
_ => {
118-
return Err(RuntimeError::InvalidOperation(
119-
self.context.current_line,
120-
))
121-
}
122-
};
123-
124-
Ok(Value::String(result))
125-
}
91+
Expression::Literal(literal) => self.visit_literal(literal),
92+
Expression::UnaryExpression(unary) => self.visit_unary_expression(unary),
93+
Expression::BinaryExpression(binary) => self.visit_binary_expression(binary),
94+
_ => return Err(RuntimeError::InvalidOperation(self.context.current_line)),
95+
}
96+
}
97+
98+
fn visit_literal(&self, literal: &Literal) -> InterpreterResult {
99+
match literal {
100+
Literal::Number { value } => Ok(Value::Number(*value)),
101+
Literal::String { value } => Ok(Value::String(value.clone())),
102+
}
103+
}
104+
105+
fn visit_binary_expression(&self, binary: &BinaryExpression) -> InterpreterResult {
106+
let left = self.visit_expression(&binary.left)?;
107+
let right = self.visit_expression(&binary.right)?;
108+
109+
match (left, right) {
110+
(Value::Number(left), Value::Number(right)) => {
111+
let result = match binary.operator {
112+
ArithmeticOperator::Add => left + right,
113+
ArithmeticOperator::Subtract => left - right,
114+
ArithmeticOperator::Multiply => left * right,
115+
ArithmeticOperator::Divide => left / right,
116+
};
117+
118+
Ok(Value::Number(result))
119+
}
120+
(Value::String(left), Value::String(right)) => {
121+
let result = match binary.operator {
122+
ArithmeticOperator::Add => left + &right,
126123
_ => return Err(RuntimeError::InvalidOperation(self.context.current_line)),
127-
}
124+
};
125+
126+
Ok(Value::String(result))
128127
}
129128
_ => return Err(RuntimeError::InvalidOperation(self.context.current_line)),
130129
}
131130
}
132131

132+
fn visit_unary_expression(&self, unary: &UnaryExpression) -> InterpreterResult {
133+
let value = self.visit_expression(&unary.argument)?;
134+
135+
match value {
136+
Value::Number(number) => match unary.operator {
137+
Some(UnaryOperator::Plus) => Ok(Value::Number(number)),
138+
Some(UnaryOperator::Minus) => Ok(Value::Number(-number)),
139+
None => Ok(Value::Number(number)),
140+
},
141+
_ => Err(RuntimeError::InvalidOperation(self.context.current_line)),
142+
}
143+
}
144+
133145
fn visit_print_statement(&self, expressions: &Vec<Expression>) -> InterpreterResult {
134146
let mut results: Vec<String> = vec![];
135147
for expression in expressions {
@@ -247,7 +259,7 @@ impl Interpreter {
247259
value => return Err(RuntimeError::IllegalLineNumber(format!("{}", value))),
248260
};
249261

250-
self.context.current_line = location;
262+
self.context.current_line = location as usize;
251263

252264
Ok(Value::None)
253265
}

src/lexer.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ pub enum TokenKind {
2929
#[derive(Debug, Clone, PartialEq)]
3030
pub enum TokenValue {
3131
None,
32-
Digit(usize),
32+
Digit(f32),
3333
String(String),
3434
}
3535

src/parser.rs

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use std::thread::current;
12
use std::vec;
23

34
use crate::ast::*;
@@ -68,22 +69,22 @@ impl<'a> Parser<'a> {
6869
TokenKind::Identifier => Expression::Identifier(Identifier {
6970
name: match next_token.value {
7071
TokenValue::String(s) => s.clone(),
71-
_ => unreachable!(),
72+
_ => Err(SyntaxError::UnexpectedToken(next_token))?,
7273
},
7374
}),
7475
TokenKind::NumberLiteral => Expression::Literal(Literal::Number {
7576
value: match next_token.value {
7677
TokenValue::Digit(d) => d,
77-
_ => unreachable!(),
78+
_ => Err(SyntaxError::UnexpectedToken(next_token))?,
7879
},
7980
}),
8081
TokenKind::StringLiteral => Expression::Literal(Literal::String {
8182
value: match next_token.value {
8283
TokenValue::String(s) => s.clone(),
83-
_ => unreachable!(),
84+
_ => Err(SyntaxError::UnexpectedToken(next_token))?,
8485
},
8586
}),
86-
_ => unreachable!(),
87+
_ => Err(SyntaxError::UnexpectedToken(next_token))?,
8788
};
8889

8990
if operator.is_none() {
@@ -168,7 +169,10 @@ impl<'a> Parser<'a> {
168169
variables.push(Identifier {
169170
name: match self.lexer.next()?.value {
170171
TokenValue::String(s) => s.clone(),
171-
_ => unreachable!(),
172+
_ => {
173+
let current_token = self.lexer.peek()?;
174+
return Err(SyntaxError::UnexpectedToken(current_token));
175+
}
172176
},
173177
});
174178

@@ -203,7 +207,7 @@ impl<'a> Parser<'a> {
203207
TokenKind::LessThanOrEqual => RelationOperator::LessThanOrEqual,
204208
TokenKind::GreaterThan => RelationOperator::GreaterThan,
205209
TokenKind::GreaterThanOrEqual => RelationOperator::GreaterThanOrEqual,
206-
_ => unreachable!(),
210+
_ => Err(SyntaxError::UnexpectedToken(next_token))?,
207211
};
208212

209213
let right = self.parse_expression()?;
@@ -255,7 +259,10 @@ impl<'a> Parser<'a> {
255259
declaration: VarDeclaration {
256260
name: match name {
257261
TokenValue::String(s) => s.clone(),
258-
_ => unreachable!(),
262+
_ => Err(SyntaxError::UnexpectedIdentifier(
263+
format!("{:?}", value),
264+
self.lexer.offset(),
265+
))?,
259266
},
260267
value,
261268
},
@@ -343,12 +350,12 @@ impl<'a> Parser<'a> {
343350
self.lexer.next()?;
344351

345352
Ok(Line {
346-
number: line_number,
353+
number: line_number.map(|n| n as usize),
347354
statement: self.parse_statement()?,
348355
source: self.source[next_token.span.start..self.lexer.offset()].to_string(),
349356
})
350357
}
351-
_ => unreachable!(),
358+
_ => Err(SyntaxError::UnexpectedToken(next_token)),
352359
};
353360

354361
lines.push(line?);

0 commit comments

Comments
 (0)