Skip to content

Commit 8ab0b93

Browse files
Fixes: Fixed the and keywords not working inside statements, and Fixed the Division Operator Not Working.
1 parent 4704fce commit 8ab0b93

File tree

5 files changed

+90
-60
lines changed

5 files changed

+90
-60
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
[package]
2-
name = "td"
2+
name = "Tidal"
33
version = "1.4.0"
44
edition = "2021"
55

66
[dependencies]
7+
8+
[[bin]]
9+
name = "td"
10+
path = "src/main.rs"

code/file-8.td

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,13 @@ var a = 0;
22
var b = "hi";
33

44
for(var i = 0; i < 10; i = i + 1;) {
5-
/* print(i); */
5+
print(i);
66
if (i == 5) {
77
break;
88
} else {
99
a = a + i;
10-
continue;
1110
}
1211
}
12+
13+
print("");
14+
print(10 / 2);

src/interpreter.rs

Lines changed: 52 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,27 @@ pub fn interpret(ast: Vec<ASTNode>, is_verbose: bool) -> Option<Value> {
77
let mut result = None;
88

99
for node in ast {
10-
result = Some(interpret_node(&node, &mut symbol_table, is_verbose));
10+
result = Some(interpret_node(&node, &mut symbol_table, is_verbose, false));
11+
if let Value::Break = result.as_ref().unwrap() {
12+
panic!("Break statement outside of loop");
13+
}
14+
if let Value::Continue = result.as_ref().unwrap() {
15+
panic!("Continue statement outside of loop");
16+
}
1117
}
1218

1319
result
1420
}
1521

16-
fn interpret_node(node: &ASTNode, symbol_table: &mut HashMap<String, (Value, bool)>, is_verbose: bool) -> Value {
22+
fn interpret_node(node: &ASTNode, symbol_table: &mut HashMap<String, (Value, bool)>, is_verbose: bool, in_loop: bool) -> Value {
1723
match node {
1824
ASTNode::Number(val) => Value::Number(*val),
1925
ASTNode::String(val) => Value::String(val.clone()),
2026
ASTNode::Boolean(val) => Value::Boolean(*val),
2127
ASTNode::Null => Value::Null,
2228
ASTNode::BinaryOp(left, op, right) => {
23-
let left_val = interpret_node(left, symbol_table, is_verbose);
24-
let right_val = interpret_node(right, symbol_table, is_verbose);
29+
let left_val = interpret_node(left, symbol_table, is_verbose, in_loop);
30+
let right_val = interpret_node(right, symbol_table, is_verbose, in_loop);
2531
match (left_val, right_val) {
2632
(Value::Number(l), Value::Number(r)) => {
2733
match op {
@@ -64,7 +70,7 @@ fn interpret_node(node: &ASTNode, symbol_table: &mut HashMap<String, (Value, boo
6470
}
6571
},
6672
ASTNode::Print(expr) => {
67-
let value = interpret_node(expr, symbol_table, is_verbose);
73+
let value = interpret_node(expr, symbol_table, is_verbose, in_loop);
6874
if is_verbose {
6975
println!("call print({:?})", value);
7076
} else {
@@ -82,7 +88,7 @@ fn interpret_node(node: &ASTNode, symbol_table: &mut HashMap<String, (Value, boo
8288
},
8389
ASTNode::Var(name, expr, is_mutable) => {
8490
let value = if let Some(expr) = expr {
85-
interpret_node(expr, symbol_table, is_verbose)
91+
interpret_node(expr, symbol_table, is_verbose, in_loop)
8692
} else {
8793
Value::Null
8894
};
@@ -91,9 +97,9 @@ fn interpret_node(node: &ASTNode, symbol_table: &mut HashMap<String, (Value, boo
9197
println!("declare variable {} with {:?}", name, value);
9298
}
9399
Value::Null
94-
}
100+
},
95101
ASTNode::Assign(name, expr) => {
96-
let value = interpret_node(expr, symbol_table, is_verbose);
102+
let value = interpret_node(expr, symbol_table, is_verbose, in_loop);
97103
if let Some((_, is_mutable)) = symbol_table.get(name) {
98104
if !is_mutable {
99105
panic!("Cannot assign to immutable variable: {}", name);
@@ -106,17 +112,17 @@ fn interpret_node(node: &ASTNode, symbol_table: &mut HashMap<String, (Value, boo
106112
panic!("Variable not declared: {}", name);
107113
}
108114
Value::Null
109-
}
115+
},
110116
ASTNode::Identifier(name) => {
111117
if let Some((value, _)) = symbol_table.get(name) {
112118
value.clone()
113119
} else {
114120
panic!("Variable not found: {}", name);
115121
}
116-
}
122+
},
117123
ASTNode::Index(expr, index) => {
118-
let value = interpret_node(expr, symbol_table, is_verbose);
119-
let index = interpret_node(index, symbol_table, is_verbose);
124+
let value = interpret_node(expr, symbol_table, is_verbose, in_loop);
125+
let index = interpret_node(index, symbol_table, is_verbose, in_loop);
120126
match (value, index) {
121127
(Value::String(s), Value::Number(i)) => {
122128
if i < 0 || i >= s.len() as i32 {
@@ -126,9 +132,9 @@ fn interpret_node(node: &ASTNode, symbol_table: &mut HashMap<String, (Value, boo
126132
}
127133
_ => panic!("Invalid indexing operation"),
128134
}
129-
}
135+
},
130136
ASTNode::Type(expr) => {
131-
let value = interpret_node(expr, symbol_table, is_verbose);
137+
let value = interpret_node(expr, symbol_table, is_verbose, in_loop);
132138
let type_str = match value {
133139
Value::Number(_) => "int",
134140
Value::String(_) => "str",
@@ -142,21 +148,27 @@ fn interpret_node(node: &ASTNode, symbol_table: &mut HashMap<String, (Value, boo
142148
println!("call type({:?}) = {}", value, type_str);
143149
}
144150
Value::Type(type_str.to_string())
145-
}
151+
},
146152
ASTNode::TypeLiteral(type_name) => Value::Type(type_name.clone()),
147153
ASTNode::If(condition, if_block, elif_blocks, else_block) => {
148-
let condition_value = interpret_node(condition, symbol_table, is_verbose);
154+
let condition_value = interpret_node(condition, symbol_table, is_verbose, in_loop);
149155
if let Value::Boolean(true) = condition_value {
150156
for stmt in if_block {
151-
interpret_node(stmt, symbol_table, is_verbose);
157+
let result = interpret_node(stmt, symbol_table, is_verbose, in_loop);
158+
if matches!(result, Value::Break | Value::Continue) {
159+
return result;
160+
}
152161
}
153162
} else {
154163
let mut executed = false;
155164
for (elif_condition, elif_statements) in elif_blocks {
156-
let elif_condition_value = interpret_node(&elif_condition, symbol_table, is_verbose);
165+
let elif_condition_value = interpret_node(elif_condition, symbol_table, is_verbose, in_loop);
157166
if let Value::Boolean(true) = elif_condition_value {
158167
for stmt in elif_statements {
159-
interpret_node(stmt, symbol_table, is_verbose);
168+
let result = interpret_node(stmt, symbol_table, is_verbose, in_loop);
169+
if matches!(result, Value::Break | Value::Continue) {
170+
return result;
171+
}
160172
}
161173
executed = true;
162174
break;
@@ -165,43 +177,48 @@ fn interpret_node(node: &ASTNode, symbol_table: &mut HashMap<String, (Value, boo
165177
if !executed {
166178
if let Some(else_statements) = else_block {
167179
for stmt in else_statements {
168-
interpret_node(stmt, symbol_table, is_verbose);
180+
let result = interpret_node(stmt, symbol_table, is_verbose, in_loop);
181+
if matches!(result, Value::Break | Value::Continue) {
182+
return result;
183+
}
169184
}
170185
}
171186
}
172187
}
173188
Value::Null
174189
},
175190
ASTNode::For(init, condition, update, body) => {
176-
interpret_node(init, symbol_table, is_verbose);
191+
interpret_node(init, symbol_table, is_verbose, true);
177192
loop {
178-
let cond_value = interpret_node(condition, symbol_table, is_verbose);
193+
let cond_value = interpret_node(condition, symbol_table, is_verbose, true);
179194
if let Value::Boolean(false) = cond_value {
180195
break;
181196
}
182197

183-
let mut should_break = false;
184198
for stmt in body {
185-
let result = interpret_node(stmt, symbol_table, is_verbose);
199+
let result = interpret_node(stmt, symbol_table, is_verbose, true);
186200
match result {
187-
Value::Break => {
188-
should_break = true;
189-
break;
190-
},
201+
Value::Break => return Value::Null,
191202
Value::Continue => break,
192203
_ => {}
193204
}
194205
}
195206

196-
if should_break {
197-
break;
198-
}
199-
200-
interpret_node(update, symbol_table, is_verbose);
207+
interpret_node(update, symbol_table, is_verbose, true);
201208
}
202209
Value::Null
203210
},
204-
ASTNode::Break => Value::Break,
205-
ASTNode::Continue => Value::Continue,
211+
ASTNode::Break => {
212+
if !in_loop {
213+
panic!("Break statement outside of loop");
214+
}
215+
Value::Break
216+
},
217+
ASTNode::Continue => {
218+
if !in_loop {
219+
panic!("Continue statement outside of loop");
220+
}
221+
Value::Continue
222+
},
206223
}
207224
}

src/lexer.rs

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ impl<'a> Lexer<'a> {
5555
pub fn next_token(&mut self) -> Token {
5656
self.skip_whitespace();
5757

58-
if self.skip_comment() {
59-
return self.next_token();
58+
if let Some(token) = self.handle_comment() {
59+
return token;
6060
}
6161

6262
match self.input.next() {
@@ -152,26 +152,33 @@ impl<'a> Lexer<'a> {
152152
}
153153
}
154154

155-
fn skip_comment(&mut self) -> bool {
156-
if self.input.next_if(|&ch| ch == '/').is_some() && self.input.next_if(|&ch| ch == '*').is_some() {
157-
let mut depth = 1;
158-
while depth > 0 {
159-
match (self.input.next(), self.input.peek()) {
160-
(Some('*'), Some(&'/')) => {
161-
self.input.next();
162-
depth -= 1;
163-
},
164-
(Some('/'), Some(&'*')) => {
165-
self.input.next();
166-
depth += 1;
167-
},
168-
(Some(_), _) => {},
169-
(None, _) => panic!("Unterminated comment"),
170-
}
155+
fn handle_comment(&mut self) -> Option<Token> {
156+
if self.input.next_if(|&ch| ch == '/').is_some() {
157+
if self.input.next_if(|&ch| ch == '*').is_some() {
158+
self.skip_multiline_comment();
159+
return Some(self.next_token());
160+
} else {
161+
return Some(Token::Divide);
162+
}
163+
}
164+
None
165+
}
166+
167+
fn skip_multiline_comment(&mut self) {
168+
let mut depth = 1;
169+
while depth > 0 {
170+
match (self.input.next(), self.input.peek()) {
171+
(Some('*'), Some(&'/')) => {
172+
self.input.next();
173+
depth -= 1;
174+
},
175+
(Some('/'), Some(&'*')) => {
176+
self.input.next();
177+
depth += 1;
178+
},
179+
(Some(_), _) => {},
180+
(None, _) => panic!("Unterminated comment"),
171181
}
172-
true
173-
} else {
174-
false
175182
}
176183
}
177184

0 commit comments

Comments
 (0)