Skip to content

Commit 44dd3f4

Browse files
committed
add support for math operators, fix var redeclaration
1 parent 07ffffa commit 44dd3f4

File tree

6 files changed

+184
-50
lines changed

6 files changed

+184
-50
lines changed

src/compiler.rs

Lines changed: 113 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
use std::collections::HashMap;
2-
use std::io::Write;
32

43
use md5::{Digest, Md5};
54
use serde_json::{json, Value};
@@ -171,23 +170,15 @@ impl Compiler {
171170
Expr::Binary(left, op, right) => match op {
172171
// string concat lol
173172
Operator::Ampersand => {
174-
let string_1 = self.value_from_expr(left, current_id.clone());
175-
let string_2 = self.value_from_expr(right, current_id.clone());
176-
177-
self.push_block(
178-
&Block {
179-
opcode: "operator_join".to_string(),
180-
parent: Some(parent_id.to_string()),
181-
inputs: Some(HashMap::from([
182-
("STRING1".to_string(), string_1),
183-
("STRING2".to_string(), string_2),
184-
])),
185-
shadow: Some(false),
186-
top_level: Some(false),
187-
..Default::default()
188-
},
173+
self.compile_simple_operator(
174+
"STRING1",
175+
"STRING2",
176+
left,
177+
right,
178+
"operator_join",
189179
current_id,
190-
)
180+
parent_id,
181+
);
191182
}
192183
Operator::Bang => todo!(),
193184
Operator::EqualEqual => {
@@ -239,10 +230,50 @@ impl Compiler {
239230
Operator::Less => todo!(),
240231
Operator::GreaterEqual => todo!(),
241232
Operator::LessEqual => todo!(),
242-
Operator::Minus => todo!(),
243-
Operator::Plus => todo!(),
244-
Operator::Slash => todo!(),
245-
Operator::Star => todo!(),
233+
Operator::Minus => {
234+
self.compile_simple_operator(
235+
"NUM1",
236+
"NUM2",
237+
left,
238+
right,
239+
"operator_subtract",
240+
current_id,
241+
parent_id,
242+
);
243+
}
244+
Operator::Plus => {
245+
self.compile_simple_operator(
246+
"NUM1",
247+
"NUM2",
248+
left,
249+
right,
250+
"operator_add",
251+
current_id,
252+
parent_id,
253+
);
254+
}
255+
Operator::Slash => {
256+
self.compile_simple_operator(
257+
"NUM1",
258+
"NUM2",
259+
left,
260+
right,
261+
"operator_divide",
262+
current_id,
263+
parent_id,
264+
);
265+
}
266+
Operator::Star => {
267+
self.compile_simple_operator(
268+
"NUM1",
269+
"NUM2",
270+
left,
271+
right,
272+
"operator_multiply",
273+
current_id,
274+
parent_id,
275+
);
276+
}
246277
Operator::Caret => todo!(),
247278
Operator::None => panic!("we should never be here."),
248279
Operator::And => {
@@ -289,10 +320,43 @@ impl Compiler {
289320
current_id,
290321
);
291322
}
323+
Operator::PlusEqual => todo!(),
324+
Operator::MinusEqual => todo!(),
325+
Operator::StarEqual => todo!(),
326+
Operator::SlashEqual => todo!(),
292327
},
293328
}
294329
}
295330

331+
fn compile_simple_operator(
332+
&mut self,
333+
key1: &str,
334+
key2: &str,
335+
val1: &Expr,
336+
val2: &Expr,
337+
opcode: &str,
338+
current_id: String,
339+
parent_id: String,
340+
) {
341+
let val1 = self.value_from_expr(val1, current_id.clone());
342+
let val2 = self.value_from_expr(val2, current_id.clone());
343+
344+
self.push_block(
345+
&Block {
346+
opcode: opcode.to_string(),
347+
parent: Some(parent_id.to_string()),
348+
inputs: Some(HashMap::from([
349+
(key1.to_string(), val1),
350+
(key2.to_string(), val2),
351+
])),
352+
shadow: Some(false),
353+
top_level: Some(true),
354+
..Default::default()
355+
},
356+
current_id,
357+
)
358+
}
359+
296360
fn compile_conditional_control(
297361
&mut self,
298362
opcode: &str,
@@ -385,7 +449,7 @@ impl Compiler {
385449
//
386450
let input_shadow_num = match op {
387451
Operator::EqualEqual => 1,
388-
_ => todo!(),
452+
_ => 1,
389453
};
390454

391455
json!([3, id.to_string(), [10, ""]])
@@ -619,25 +683,27 @@ impl Compiler {
619683
let var_id =
620684
self.push_var(self.scope.clone(), var_name.clone(), var_type.clone());
621685

622-
let value = match expr {
623-
Expr::Number(value) => json!([1, [10, value.to_string()]]),
624-
Expr::String(value) => json!([1, [10, value.to_string()]]),
625-
Expr::Identifier(ident) => {
626-
let ident_id = self.get_var_id(self.scope.clone(), ident.clone());
627-
json!([1, [12, ident, ident_id]])
628-
}
629-
Expr::Bool(_) => todo!(),
630-
Expr::Binary(_, _, _) => {
631-
let expr_block_id = self.gen_block_id();
632-
self.compile_binary_expr(
633-
expr,
634-
current_id.clone(),
635-
expr_block_id.clone(),
636-
);
637-
638-
json!([3, expr_block_id, [10, ""]])
639-
}
640-
};
686+
let value = self.value_from_expr(expr, current_id.clone());
687+
688+
// let value = match expr {
689+
// Expr::Number(value) => json!([1, [10, value.to_string()]]),
690+
// Expr::String(value) => json!([1, [10, value.to_string()]]),
691+
// Expr::Identifier(ident) => {
692+
// let ident_id = self.get_var_id(self.scope.clone(), ident.clone());
693+
// json!([1, [12, ident, ident_id]])
694+
// }
695+
// Expr::Bool(_) => todo!(),
696+
// Expr::Binary(_, _, _) => {
697+
// let expr_block_id = self.gen_block_id();
698+
// self.compile_binary_expr(
699+
// expr,
700+
// current_id.clone(),
701+
// expr_block_id.clone(),
702+
// );
703+
//
704+
// json!([3, expr_block_id, [10, ""]])
705+
// }
706+
// };
641707

642708
let mut inputs = HashMap::new();
643709
inputs.insert("VALUE".to_string(), value);
@@ -697,6 +763,9 @@ impl Compiler {
697763
);
698764
}
699765
}
766+
Stmt::VariableAssignment(var_name, value) => {}
767+
Stmt::VariableMutation(var_name, op, value) => {}
768+
700769
_ => panic!("statment: {:#?} not valid in body", stmt),
701770
}
702771
}
@@ -1224,6 +1293,7 @@ impl Compiler {
12241293
/// returns the ID of the variable
12251294
fn push_var(&mut self, scope: Scope, var_name: String, var_type: Type) -> String {
12261295
// add an empty hashmap for the scope if it doesn't exist within the var table
1296+
// TODO: add heiarchy to scope
12271297
if !self
12281298
.var_table
12291299
.clone()
@@ -1232,6 +1302,8 @@ impl Compiler {
12321302
.contains(&scope)
12331303
{
12341304
self.var_table.insert(scope.clone(), HashMap::new());
1305+
} else {
1306+
panic!("variable {:?} already exists in scope", var_name);
12351307
}
12361308

12371309
let var_id = self.gen_var_id().to_string();

src/lexer.rs

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,17 @@ impl Lexer {
102102
}
103103
}
104104

105+
fn add_token_many_cond(&mut self, expected_matches: &[(char, TokenType)], fails: TokenType) {
106+
for pair in expected_matches {
107+
if self.compare(pair.0.clone()) {
108+
self.add_token(pair.1.clone());
109+
return;
110+
}
111+
}
112+
113+
self.add_token(fails);
114+
}
115+
105116
fn add_token(&mut self, token_type: TokenType) {
106117
let string: String = self.source[self.start..self.current].to_string();
107118

@@ -201,9 +212,24 @@ impl Lexer {
201212
'.' => self.add_token(TokenType::Dot),
202213
';' => self.add_token(TokenType::Semicolon),
203214
':' => self.add_token(TokenType::Colon),
204-
'+' => self.add_token(TokenType::Operator(Operator::Plus)),
215+
'+' => self.add_token_cond(
216+
'=',
217+
TokenType::Operator(Operator::PlusEqual),
218+
TokenType::Operator(Operator::Plus),
219+
),
220+
'-' => self.add_token_many_cond(
221+
&[
222+
('>', TokenType::Arrow),
223+
('=', TokenType::Operator(Operator::MinusEqual)),
224+
],
225+
TokenType::Operator(Operator::Minus),
226+
),
227+
'*' => self.add_token_cond(
228+
'=',
229+
TokenType::Operator(Operator::StarEqual),
230+
TokenType::Operator(Operator::Star),
231+
),
205232
'&' => self.add_token(TokenType::Operator(Operator::Ampersand)),
206-
'*' => self.add_token(TokenType::Operator(Operator::Star)),
207233
'^' => self.add_token(TokenType::Operator(Operator::Caret)),
208234
'!' => self.add_token_cond(
209235
'=',
@@ -225,14 +251,17 @@ impl Lexer {
225251
TokenType::Operator(Operator::GreaterEqual),
226252
TokenType::Operator(Operator::Greater),
227253
),
228-
'-' => self.add_token_cond('>', TokenType::Arrow, TokenType::Operator(Operator::Minus)),
229254
'/' => {
230255
if self.compare('/') {
231256
while self.peek() != '\n' && !self.is_at_end() {
232257
self.advance();
233258
}
234259
} else {
235-
self.add_token(TokenType::Operator(Operator::Slash));
260+
self.add_token_cond(
261+
'=',
262+
TokenType::Operator(Operator::SlashEqual),
263+
TokenType::Operator(Operator::Slash),
264+
);
236265
}
237266
}
238267
'"' => self.lex_string(),

src/main.rs

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,9 @@ pub fn compile_project(makefile_path: String) -> (Project, Vec<(TargetData, Vec<
4949
// println!("------------------------------------------------------------------");
5050

5151
let mut parser = Parser::new(tokens);
52-
targets.push((target, parser.parse()));
52+
let parsed = parser.parse();
53+
println!("{:#?}", parsed);
54+
targets.push((target, parsed));
5355
}
5456

5557
// println!("{:#?}", targets);

src/parser.rs

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use std::i8;
1+
use std::{i8, io::Write};
22

33
use crate::{
44
error::parse_error,
@@ -32,11 +32,20 @@ pub enum Key {
3232
Char(char), // a..=z, 0..=9
3333
}
3434

35+
#[derive(Debug, Clone)]
36+
pub enum MutationOperator {
37+
AddEqual,
38+
SubEqual,
39+
MultEqual,
40+
DivEqual,
41+
}
42+
3543
#[derive(Debug, Clone)]
3644
pub enum Stmt {
3745
Expression(Expr),
3846
VariableDeclaration(String, Type, Expr), // name, type, value
3947
VariableAssignment(String, Expr),
48+
VariableMutation(String, MutationOperator, Expr),
4049
FunctionDeclaration(String, Vec<(String, Type)>, Vec<Stmt>, Type), // name, arguments, body, return type
4150
EventHandler(Event, Vec<Stmt>), // event, body
4251
FunctionCall(String, Vec<Expr>), // name, arguments
@@ -274,6 +283,22 @@ impl Parser {
274283

275284
Stmt::VariableAssignment(ident, value)
276285
}
286+
TokenType::Operator(op) => {
287+
let op = match op {
288+
Operator::PlusEqual => MutationOperator::AddEqual,
289+
Operator::MinusEqual => MutationOperator::SubEqual,
290+
Operator::StarEqual => MutationOperator::MultEqual,
291+
Operator::SlashEqual => MutationOperator::DivEqual,
292+
_ => todo!(),
293+
};
294+
295+
self.advance();
296+
let value = self.parse_expression();
297+
self.expect(TokenType::Semicolon);
298+
self.advance();
299+
300+
Stmt::VariableMutation(ident, op, value)
301+
}
277302
_ => panic!(
278303
"unexpected token after parsing ident: {:?}",
279304
self.peek_next()

src/token.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,11 @@ pub enum Operator {
2323
And,
2424
Or,
2525

26+
PlusEqual,
27+
MinusEqual,
28+
StarEqual,
29+
SlashEqual,
30+
2631
// hack?
2732
None,
2833
}

test_project/sprite1.scuff

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
event flag_clicked {
2-
while (1 == 1) {
3-
let x: string = (x & "a");
4-
}
2+
let x: string = ("1" & "1");
3+
let y: number = (1 * 2);
4+
let y: number = (1 * 2);
5+
say(y);
56
}

0 commit comments

Comments
 (0)