Skip to content

Commit ae4358f

Browse files
Feat: Implementing functions and operators (add, bul, mul...).
1 parent 509b8fd commit ae4358f

3 files changed

Lines changed: 65 additions & 5 deletions

File tree

compiler/src/main.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ fn main() {
2929

3030
initialize_logger();
3131

32-
let source = "dict()\ndict(a=1)\n{'a': 1}\ndict({'a': 1})";
32+
let source = "def add(a, b): a + b\nresult = add(1, 2)";
3333

3434
let chunk = modules::parser::Parser::new(source, modules::lexer::lexer(source)).parse();
3535

compiler/src/modules/parser.rs

Lines changed: 58 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,8 @@ pub enum OpCode {
5252
CallStr, CallInt, CallRange, Phi, CallChr, CallType,
5353
CallFloat, CallBool, CallRound, CallMin, CallMax, CallSum,
5454
CallSorted, CallEnumerate, CallZip, CallList, CallTuple, CallDict,
55-
CallIsInstance, CallSet, CallInput, CallOrd, BuildDict, BuildList
55+
CallIsInstance, CallSet, CallInput, CallOrd, BuildDict, BuildList,
56+
MakeFunction, Add, Sub, Mul, Div
5657
}
5758

5859
#[derive(Debug)] pub struct Instruction { pub opcode: OpCode, pub operand: u16 }
@@ -65,6 +66,7 @@ pub struct SSAChunk {
6566
pub instructions: Vec<Instruction>,
6667
pub constants: Vec<Value>,
6768
pub names: Vec<String>,
69+
pub functions: Vec<(Vec<String>, SSAChunk)>
6870
}
6971

7072
impl SSAChunk {
@@ -124,11 +126,13 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
124126
}
125127

126128
fn current_version(&self, name: &str) -> u32 { self.ssa_versions.get(name).copied().unwrap_or(0) }
129+
127130
fn increment_version(&mut self, name: &str) -> u32 {
128131
let v = self.current_version(name) + 1;
129132
self.ssa_versions.insert(name.to_string(), v);
130133
v
131134
}
135+
132136
fn emit_load_ssa(&mut self, name: String) {
133137
let v = self.current_version(&name);
134138
let ssa = format!("{}_{}", name, v);
@@ -176,15 +180,27 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
176180
let t = self.advance();
177181
match t.kind {
178182
TokenType::Name => self.name(t),
183+
TokenType::Def => { self.func_def(); return; },
179184
TokenType::String => self.emit_const(Value::Str(parse_string(self.lexeme(&t)))),
180185
TokenType::Int | TokenType::Float => self.parse_number(self.lexeme(&t), t.kind),
181186
TokenType::True => self.emit_const(Value::Bool(true)),
182187
TokenType::False => self.emit_const(Value::Bool(false)),
183188
TokenType::None => self.emit_const(Value::None),
184189
TokenType::FstringStart => self.fstring(),
185190
TokenType::Minus => { self.expr(); self.chunk.emit(OpCode::Minus, 0); },
186-
TokenType::Lbrace => self.dict_literal(), // ← agrega
187-
TokenType::Lsqb => self.list_literal(), // ← agrega
191+
TokenType::Lbrace => self.dict_literal(),
192+
TokenType::Lsqb => self.list_literal(),
193+
_ => {}
194+
}
195+
self.binary_op();
196+
}
197+
198+
fn binary_op(&mut self) {
199+
match self.peek() {
200+
Some(TokenType::Plus) => { self.advance(); self.expr(); self.chunk.emit(OpCode::Add, 0); }
201+
Some(TokenType::Minus) => { self.advance(); self.expr(); self.chunk.emit(OpCode::Sub, 0); }
202+
Some(TokenType::Star) => { self.advance(); self.expr(); self.chunk.emit(OpCode::Mul, 0); }
203+
Some(TokenType::Slash) => { self.advance(); self.expr(); self.chunk.emit(OpCode::Div, 0); }
188204
_ => {}
189205
}
190206
}
@@ -302,14 +318,52 @@ impl<'src, I: Iterator<Item = Token>> Parser<'src, I> {
302318
"ord" => { let a = self.parse_args(); self.chunk.emit(OpCode::CallOrd, a); }
303319
"range" => self.call_range(),
304320
_ => {
305-
let i = self.chunk.push_name(&name);
321+
let v = self.current_version(&name);
322+
let i = self.chunk.push_name(&format!("{}_{}", name, v));
306323
self.chunk.emit(OpCode::LoadName, i);
307324
let a = self.parse_args();
308325
self.chunk.emit(OpCode::Call, a);
309326
}
310327
}
311328
}
312329

330+
fn func_def(&mut self) {
331+
let fname = { let n = self.advance(); self.lexeme(&n).to_string() };
332+
let params = self.parse_params();
333+
let body = self.compile_body(&params);
334+
335+
let fi = self.chunk.functions.len() as u16;
336+
self.chunk.functions.push((params, body));
337+
self.chunk.emit(OpCode::MakeFunction, fi);
338+
339+
let ver = self.increment_version(&fname);
340+
let i = self.chunk.push_name(&format!("{}_{}", fname, ver));
341+
self.chunk.emit(OpCode::StoreName, i);
342+
}
343+
344+
fn parse_params(&mut self) -> Vec<String> {
345+
self.advance(); // (
346+
let mut params = Vec::new();
347+
while !matches!(self.peek(), Some(TokenType::Rpar) | None) {
348+
let p = self.advance();
349+
params.push(self.lexeme(&p).to_string());
350+
if matches!(self.peek(), Some(TokenType::Comma)) { self.advance(); }
351+
}
352+
self.advance(); // )
353+
if matches!(self.peek(), Some(TokenType::Colon)) { self.advance(); }
354+
params
355+
}
356+
357+
fn compile_body(&mut self, params: &[String]) -> SSAChunk {
358+
let (saved_chunk, saved_ver) = (std::mem::take(&mut self.chunk), std::mem::take(&mut self.ssa_versions));
359+
for p in params { self.ssa_versions.insert(p.clone(), 0); }
360+
self.stmt();
361+
self.chunk.emit(OpCode::ReturnValue, 0);
362+
let body = std::mem::take(&mut self.chunk);
363+
(self.chunk, self.ssa_versions) = (saved_chunk, saved_ver);
364+
body
365+
}
366+
313367
fn call_range(&mut self) {
314368
self.advance();
315369
let mut args = Vec::new();

compiler/tests/cases/parser_cases.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,11 @@
3434
["a", "1", "a", "1", "a", "1"],
3535
[],
3636
[["CallDict",0], ["PopTop",0], ["LoadConst",0], ["LoadConst",1], ["CallDict",1], ["PopTop",0], ["LoadConst",2], ["LoadConst",3], ["BuildDict",1], ["PopTop",0], ["LoadConst",4], ["LoadConst",5], ["BuildDict",1], ["CallDict",1], ["PopTop",0], ["ReturnValue",0]]
37+
],
38+
[
39+
"def add(a, b): a + b\nresult = add(1, 2)",
40+
["1", "2"],
41+
["add_1", "result_1"],
42+
[["MakeFunction",0], ["StoreName",0], ["PopTop",0], ["LoadName",0], ["LoadConst",0], ["LoadConst",1], ["Call",2], ["StoreName",1], ["PopTop",0], ["ReturnValue",0]]
3743
]
3844
]

0 commit comments

Comments
 (0)