1use std::collections::HashMap;
2use std::env;
3use std::fs::File;
4use std::io::Read;
5use std::process::exit;
6
7use serde::{Deserialize, Serialize};
8
9use crate::chunk::CompilerModuleChunk;
10use crate::chunk::OpCode::*;
11use crate::chunk::{Chunk, ClassChunk, FunctionChunk, FunctionType, Instr, ModuleChunk, OpCode};
12use crate::debug::{disassemble_class_chunk, disassemble_fn_chunk};
13use crate::native::native_functions::NATIVE_FUNCTIONS;
14use crate::precedence::{get_rule, ParseFn, Precedence};
15
16use crate::scanner::{Scanner, Token, TokenType};
17use crate::value::Value;
18use crate::VERSION;
19
20const DEFAULT_FILE_NAME: &str = "script";
21const MAX_MODULES: usize = 255;
22const MAX_JUMP: usize = 65535;
23
24#[derive(Debug)]
25pub struct Compiler {
26 modules: Vec<CompilerModuleChunk>,
28 module_table: HashMap<String, usize>,
30 parent_modules: Vec<usize>,
32 current_module: usize,
34 current_module_code: usize,
36
37 had_error: bool,
38 panic_mode: bool,
39 quiet_mode: bool,
40 debug_mode: bool,
41 wait_mode: bool,
43}
44
45impl Compiler {
46 fn current_chunk(&mut self) -> &mut Chunk {
47 let index = self.current_module().current_function;
48 &mut self
49 .current_module()
50 .functions
51 .get_mut(index)
52 .unwrap()
53 .chunk
54 }
55
56 fn current_chunk_code(&mut self) -> &mut Chunk {
57 let index = self.current_code_module().current_function;
58 &mut self
59 .current_code_module()
60 .functions
61 .get_mut(index)
62 .unwrap()
63 .chunk
64 }
65
66 fn current_chunk_ref(&self) -> &Chunk {
67 &self
68 .current_module_ref()
69 .functions
70 .get(self.current_module_ref().current_function)
71 .unwrap()
72 .chunk
73 }
74
75 fn current_fn(&mut self) -> &mut FunctionChunk {
76 let index = self.current_module_ref().current_function;
77 self.current_module().functions.get_mut(index).unwrap()
78 }
79
80 fn current_fn_type(&self) -> FunctionType {
81 self.current_module_ref()
82 .functions
83 .get(self.current_module_ref().current_function)
84 .unwrap()
85 .fn_type
86 }
87
88 fn current_class(&mut self) -> &mut ClassChunk {
90 let index = self.current_module().current_class.unwrap();
91 self.current_module().classes.get_mut(index).unwrap()
92 }
93
94 pub fn current_module(&mut self) -> &mut CompilerModuleChunk {
95 self.modules.get_mut(self.current_module).unwrap()
96 }
97
98 pub fn current_code_module(&mut self) -> &mut CompilerModuleChunk {
99 self.modules.get_mut(self.current_module_code).unwrap()
100 }
101
102 pub fn set_current_module(&mut self, m: CompilerModuleChunk) {
104 self.modules[self.current_module_code] = m;
105 }
106
107 fn current_module_ref(&self) -> &CompilerModuleChunk {
108 self.modules.get(self.current_module).unwrap()
109 }
110
111 fn current_code_module_ref(&self) -> &CompilerModuleChunk {
112 self.modules.get(self.current_module_code).unwrap()
113 }
114
115 fn advance(&mut self) {
116 let mut m = self.current_code_module().clone();
118 let mut m2 = self.current_code_module().clone();
119 m2.tokens.push(m.scanner.scan_token()); self.set_current_module(m);
121 self.current_code_module().tokens = m2.tokens;
122 if self.current().token_type == TokenType::Error {
123 self.error(self.current().lexeme.clone().as_str());
124 self.advance();
125 }
126 }
127
128 fn previous(&self) -> &Token {
129 &self.current_code_module_ref().tokens[self.current_code_module_ref().tokens.len() - 2]
130 }
131
132 fn current(&self) -> &Token {
133 &self.current_code_module_ref().tokens[self.current_code_module_ref().tokens.len() - 1]
134 }
135
136 fn consume(&mut self, token_type: TokenType, msg: &str) {
138 self.advance();
139 if self.previous().token_type == TokenType::Semicolon {
140 if self.wait_mode {
141 let file = self.current_module().scanner.file.clone();
142 let line = self.current_module().scanner.cur_line;
143 let s = format!(
144 "{}:{}: {}",
145 file, line,
146 self.current_module()
147 .scanner
148 .code
149 .split("\n")
150 .collect::<Vec<&str>>()
151 .iter()
152 .nth(line - 1)
153 .unwrap()
154 );
155 self.emit_constant(Value::PhoenixString(s));
156 self.emit_instr(OpCreateString);
157 self.emit_instr(OpWait);
158 }
159 }
160 if !(self.previous().token_type == token_type) {
161 self.error(msg);
162 }
163 }
164
165 fn match_cur(&mut self, token_type: TokenType) -> bool {
166 if !self.check(token_type) {
167 false
168 } else {
169 self.advance();
170 true
171 }
172 }
173
174 fn check(&self, token_type: TokenType) -> bool {
175 self.current().token_type == token_type
176 }
177
178 fn error(&mut self, message: &str) {
179 if self.panic_mode {
180 return;
181 } self.had_error = true;
184 self.panic_mode = true;
185
186 if self.quiet_mode {
187 return;
188 }
189
190 let token = self.previous();
191 eprint!(
192 "[{}:{}] Error",
193 self.current_module_ref().scanner.file.clone(),
194 token.line_num + 1
195 );
196 match token.token_type {
197 TokenType::EOF => eprint!(" at end of file"),
198 TokenType::Error => (), _ => eprint!(" at '{}'", token.lexeme),
200 }
201
202 eprintln!(": {}", message);
203 }
204
205 fn synchronize(&mut self) {
206 self.panic_mode = false;
207
208 while !self.check(TokenType::EOF) {
209 if self.previous().token_type == TokenType::Semicolon {
210 return;
211 }
212 match self.current().token_type {
213 TokenType::Class
214 | TokenType::Fun
215 | TokenType::Var
216 | TokenType::For
217 | TokenType::If
218 | TokenType::While
219 | TokenType::Print
220 | TokenType::Return => return,
221 _ => (),
222 }
223 self.advance();
224 }
225 }
226
227 fn emit_instr(&mut self, op_code: OpCode) {
228 let instr = Instr {
230 op_code,
231 line_num: self.previous().line_num,
232 };
233 self.current_chunk_code().write_instruction(instr)
234 }
235
236 fn emit_instrs(&mut self, op_codes: &[OpCode]) {
237 for oc in op_codes {
238 self.emit_instr(*oc)
239 }
240 }
241
242 fn emit_constant(&mut self, value: Value) -> usize {
243 let index = self.add_constant(value);
244 self.emit_instr(OpConstant(index));
245 index
246 }
247
248 fn add_constant(&mut self, value: Value) -> usize {
249 match self
250 .current_module()
251 .constants
252 .iter()
253 .position(|x| x == &value)
254 {
255 Some(i) => i,
256 None => {
257 self.current_module().constants.push(value);
258 self.current_module().constants.len() - 1
259 }
260 }
261 }
262
263 fn emit_return(&mut self) {
264 if self.current_fn_type() == FunctionType::Initializer {
265 self.emit_instrs(&[OpGetLocal(0), OpReturn]);
266 } else {
267 self.emit_instrs(&[OpNil, OpReturn]);
268 }
269 }
270
271 fn emit_jump(&mut self) -> usize {
275 self.emit_instr(OpJump(usize::MAX));
276 self.current_chunk().code.len() - 1
277 }
278
279 fn emit_jif(&mut self) -> usize {
283 self.emit_instr(OpJumpIfFalse(usize::MAX));
284 self.current_chunk().code.len() - 1
285 }
286
287 fn patch_jump(&mut self, index: usize) {
289 let jump_amount = self.current_chunk().code.len() - index;
290 if jump_amount > MAX_JUMP {
291 self.error("Too much code to jump over");
292 }
293
294 let jump_instr = self.current_chunk().code.get_mut(index).unwrap();
295 macro_rules! replace_jump {
296 ($jump_type: path) => {{
297 jump_instr.op_code = $jump_type(jump_amount)
298 }};
299 }
300
301 match jump_instr.op_code {
302 OpJump(_) => replace_jump!(OpCode::OpJump),
303 OpJumpIfFalse(_) => replace_jump!(OpCode::OpJumpIfFalse),
304 _ => panic!(
305 "Compiler panic: Attempted to patch a non_jump op code instruction: {:?}",
306 jump_instr
307 ),
308 }
309 }
310
311 fn emit_loop(&mut self, loop_start: usize) {
313 let offset = self.current_chunk().code.len() - loop_start;
314 let loop_op = OpLoop(offset);
315
316 if offset > (u16::MAX as usize) {
317 self.error("Loop body too large");
318 }
319
320 self.emit_instr(loop_op);
321 }
322
323 fn end_compilation(&mut self) {
325 self.emit_return();
326 }
327
328 fn end_scope(&mut self) {
330 for _ in 0..self.current_module().resolver.end_scope() {
331 self.emit_instr(OpPop); }
333 }
334
335 fn declare_variable(&mut self) {
337 let str_val = self.previous().lexeme.clone();
338 let success = self.current_module().resolver.declare_variable(str_val);
339 if !success {
340 self.error("Variable with this name already declared in this scope");
341 }
342 }
343
344 fn parse_precedence(&mut self, prec: Precedence) {
345 self.advance();
346
347 let prefix_rule = (get_rule(self.previous().token_type)).prefix;
350 let can_assign = prec <= Precedence::Assignment;
352 self.call_parse_fn(prefix_rule, can_assign);
353
354 while prec <= get_rule(self.current().token_type).precedence {
356 self.advance();
357 let infix_rule = (get_rule(self.previous().token_type)).infix;
358 self.call_parse_fn(infix_rule, can_assign);
359 }
360
361 if can_assign && self.previous().token_type == TokenType::Equal {
363 self.error("Invalid assignment target");
364 }
365 }
366
367 fn call_parse_fn(&mut self, parse_fn: ParseFn, can_assign: bool) {
368 match parse_fn {
369 ParseFn::None => self.error("Expected expression"),
370 ParseFn::Binary => self.binary(),
371 ParseFn::Grouping => self.grouping(),
372 ParseFn::Unary => self.unary(),
373 ParseFn::Number => self.number(),
374 ParseFn::Literal => self.literal(),
375 ParseFn::String => self.string(),
376 ParseFn::List => self.list(can_assign),
377 ParseFn::HashMap => self.hashmap(can_assign),
378 ParseFn::Variable => self.variable(can_assign),
379 ParseFn::And => self.and_operator(),
380 ParseFn::Or => self.or_operator(),
381 ParseFn::Call => self.call(),
382 ParseFn::Dot => self.dot(can_assign),
383 ParseFn::This => self.this(),
384 ParseFn::Super => self.super_(),
385 ParseFn::Increment => { }
386 }
387 }
388
389 fn declaration(&mut self) {
390 if self.match_cur(TokenType::Fun) {
391 self.fun_declaration();
392 } else if self.match_cur(TokenType::Class) {
393 self.class_declaration();
394 } else if self.match_cur(TokenType::Var) {
395 self.var_declaration();
396 } else {
397 self.statement();
398 }
399 if self.panic_mode {
400 self.synchronize();
401 }
402 }
403
404 fn fun_declaration(&mut self) {
405 let global = self.parse_variable("Expected function name");
406 self.current_module().resolver.mark_initialized(); self.function(FunctionType::Function);
408 self.define_variable(global); }
410
411 fn class_declaration(&mut self) {
412 self.consume(
413 TokenType::Identifier,
414 "Expected class name after keyword 'class'",
415 );
416 let name = self.previous().lexeme.clone();
417 let name_index = self.identifier_constant(&name);
418 self.declare_variable();
419
420 let class = ClassChunk::new(name);
421 let old_class = self.current_module().current_class;
422 self.current_module().classes.push(class);
423
424 let class_index = self.current_module().classes.len() - 1;
425 self.current_module().current_class = Some(class_index);
426
427 self.emit_instr(OpClass(class_index));
428 self.define_variable(name_index);
429
430 if self.match_cur(TokenType::Less) {
432 self.consume(TokenType::Identifier, "Expected superclass name");
433 let superclass_name = &self.previous().lexeme.clone();
438 let mut superclass_index: Option<usize> = None;
439 for (i, class_def) in self.current_module().classes.iter().enumerate() {
440 if class_def.name.eq(superclass_name) {
441 superclass_index = Some(i);
442 }
443 }
444
445 if superclass_index == self.current_module().current_class {
446 self.error("A class cannot inherit from itself");
447 }
448
449 match superclass_index {
450 Some(i) => {
451 let superclass = &self.current_module().classes[i];
452 for (name_index, fn_index) in superclass.methods.clone().iter() {
453 self.current_class().methods.insert(*name_index, *fn_index);
454 let name = self.current_module().identifier_constants[*name_index].clone();
456 if name.as_str().eq("init") {
457 self.current_class().has_init = true;
458 }
459 }
460 self.current_class().superclass = superclass_index;
461 }
462 None => {
463 self.error(format!("'{}' is not a valid superclass", superclass_name).as_str())
464 }
465 }
466 }
467
468 self.consume(TokenType::LeftBrace, "Expected '{' before class body");
469 while !self.check(TokenType::RightBrace) && !self.check(TokenType::EOF) {
470 self.method();
471 }
472 self.consume(TokenType::RightBrace, "Expected '}' after class body");
473
474 self.current_module().current_class = old_class;
475 }
476
477 fn var_declaration(&mut self) {
482 let global = self.parse_variable("Expected variable name");
483 if self.match_cur(TokenType::Equal) {
484 self.expression();
485 } else {
486 self.emit_instr(OpNil);
487 }
488 self.consume(
489 TokenType::Semicolon,
490 "Expected ';' after variable declaration",
491 );
492 self.define_variable(global);
493 }
494
495 fn parse_variable(&mut self, error_msg: &str) -> usize {
499 self.consume(TokenType::Identifier, error_msg);
500 if NATIVE_FUNCTIONS
502 .lock()
503 .unwrap()
504 .contains_key(&*self.previous().lexeme)
505 {
506 self.error("Cannot redefine a native function");
507 }
508 self.declare_variable();
509
510 if self.current_module().resolver.is_global() {
511 let str_val = self.previous().lexeme.clone();
512 self.identifier_constant(&str_val)
513 } else {
514 0
515 }
516 }
517
518 fn identifier_constant(&mut self, str_val: &String) -> usize {
522 match self
524 .current_module()
525 .identifier_constants
526 .iter()
527 .position(|x| x == str_val)
528 {
529 Some(i) => i,
530 None => {
531 self.current_module()
532 .identifier_constants
533 .push(str_val.to_string());
534 self.current_module().identifier_constants.len() - 1
535 }
536 }
537 }
538
539 pub fn identifier_constant_module(&mut self, str_val: &String, module: usize) -> usize {
543 match self
545 .modules
546 .get_mut(module)
547 .unwrap()
548 .identifier_constants
549 .iter()
550 .position(|x| x == str_val)
551 {
552 Some(i) => i,
553 None => {
554 self.modules
555 .get_mut(module)
556 .unwrap()
557 .identifier_constants
558 .push(str_val.to_string());
559 self.modules
560 .get_mut(module)
561 .unwrap()
562 .identifier_constants
563 .len()
564 - 1
565 }
566 }
567 }
568
569 fn define_variable(&mut self, global: usize) {
572 if self.current_module().resolver.is_global() {
573 self.emit_instr(OpDefineGlobal(global));
574 } else {
575 self.current_module().resolver.mark_initialized();
576 }
577 }
578
579 fn statement(&mut self) {
580 if self.match_cur(TokenType::Print) {
581 self.print_statement();
582 } else if self.match_cur(TokenType::Import) {
583 self.import_statement();
584 } else if self.match_cur(TokenType::Return) {
585 self.return_statement();
586 } else if self.match_cur(TokenType::If) {
587 self.if_statement();
588 } else if self.match_cur(TokenType::While) {
589 self.while_statement();
590 } else if self.match_cur(TokenType::For) {
591 self.for_statement();
592 } else if self.match_cur(TokenType::LeftBrace) {
593 self.current_module().resolver.begin_scope();
594 self.block();
595 self.end_scope();
596 } else {
597 self.expression_statement();
598 }
599 }
600
601 fn print_statement(&mut self) {
602 self.expression();
603 self.consume(
604 TokenType::Semicolon,
605 "Expected ';' after value in print statement",
606 );
607 self.emit_instr(OpPrint);
608 }
609
610 fn import_statement(&mut self) {
611 if self.current_fn_type() != FunctionType::Script {
613 self.error("Can't import in a function");
614 }
615 self.consume(TokenType::Identifier, "Expected identifier after import");
618 let name = self.previous().lexeme.clone();
619 self.consume(TokenType::Semicolon, "Expected ';' after import statement");
620 let mut path = env::current_dir().unwrap();
624 path.push(name.clone());
625 path.set_extension("phx");
626 if self.debug_mode {
628 println!("Importing module: {}", path.clone().to_str().unwrap());
629 }
630 let mut file = match File::open(path.clone()) {
631 Ok(f) => f,
632 Err(e) => {
633 self.error(format!("Could not open file: {}", e).as_str());
634 return;
635 }
636 };
637 let mut contents = String::new();
639 match file.read_to_string(&mut contents) {
640 Ok(_) => {}
641 Err(e) => {
642 self.error(format!("Could not read file: {}", e).as_str());
643 return;
644 }
645 }
646 let module = CompilerModuleChunk::new(
647 false,
648 name.clone(),
649 path.to_str().unwrap().to_string(),
650 contents,
651 );
652 if self.modules.len() > MAX_MODULES {
653 println!(
654 "[{}:{}] Can't load more than {} modules (maybe recursive imports?)",
655 self.current_module().scanner.file.clone(),
656 self.current_module().scanner.cur_line,
657 MAX_MODULES
658 );
659 exit(0);
660 }
661 self.modules.push(module);
662 self.parent_modules.push(self.current_module);
663 self.current_module = self.modules.len() - 1;
664 self.current_module_code = self.current_module;
665 self.module_table
666 .insert(name.clone(), self.modules.len() - 1);
667
668 let first_token = self.current_module().scanner.scan_token();
670 self.current_module().tokens.push(first_token.clone()); self.current_module()
673 .functions
674 .push(FunctionChunk::new(None, 0, FunctionType::Script)); if let TokenType::Error = first_token.token_type {
678 self.advance();
679 self.error(first_token.lexeme.as_str());
680 }
681 while !self.match_cur(TokenType::EOF) {
682 self.declaration();
683 }
684 self.end_compilation();
686
687 let index_of_module = self.current_module;
689 self.current_module = self.parent_modules.pop().unwrap();
690 self.current_module_code = self.current_module;
691
692 self.emit_constant(Value::PhoenixModule(index_of_module));
694 let index = self.identifier_constant(&name);
695 self.define_variable(index);
696 self.emit_instr(OpImport(index_of_module));
697 }
699
700 fn return_statement(&mut self) {
701 if self.current_fn_type() == FunctionType::Script {
702 self.error("Cannot return from top-level code");
703 }
704
705 if self.match_cur(TokenType::Semicolon) {
706 self.emit_return();
708 } else {
709 if self.current_fn_type() == FunctionType::Initializer {
710 self.error("Cannot return a value from an initializer");
711 }
712
713 self.expression();
714 self.consume(TokenType::Semicolon, "Expected ';' after return value");
715 self.emit_instr(OpReturn);
716 }
717 }
718
719 fn if_statement(&mut self) {
720 if self.match_cur(TokenType::LeftParen) {
723 self.advance();
724 self.expression();
725 self.consume(TokenType::RightParen, "Expected ')' after condition");
726 } else {
727 self.expression();
728 }
729
730 let jump_index = self.emit_jif();
732
733 self.emit_instr(OpPop); self.statement(); if self.match_cur(TokenType::Else) {
737 let else_jump = self.emit_jump(); self.patch_jump(jump_index);
739 self.emit_instr(OpPop); self.statement(); self.patch_jump(else_jump);
742 } else {
743 self.patch_jump(jump_index); }
745 }
746
747 fn while_statement(&mut self) {
748 let loop_start = self.current_chunk().code.len();
749
750 self.expression();
752 let exit_jump = self.emit_jif();
755
756 self.emit_instr(OpPop);
757 self.statement();
758 self.emit_loop(loop_start);
759
760 self.patch_jump(exit_jump);
761 self.emit_instr(OpPop);
762 }
763
764 fn for_statement(&mut self) {
765 self.consume(TokenType::LeftParen, "Expected '(' after 'for'");
766
767 self.current_module().resolver.begin_scope();
768
769 if self.match_cur(TokenType::Semicolon) {
771 } else if self.match_cur(TokenType::Var) {
773 self.var_declaration();
774 } else {
775 self.expression_statement(); }
777
778 let mut loop_start = self.current_chunk().code.len(); let mut exit_jump = None;
780
781 if !self.match_cur(TokenType::Semicolon) {
783 self.expression();
784 self.consume(TokenType::Semicolon, "Expected ';' after loop condition");
785 exit_jump = Some(self.emit_jif());
786 self.emit_instr(OpPop); } if !self.match_cur(TokenType::RightParen) {
790 let body_jump = self.emit_jump(); let increment_start = self.current_chunk().code.len();
794 self.expression(); self.emit_instr(OpPop); self.consume(TokenType::RightParen, "Expected ')' after for loop clauses");
797
798 self.emit_loop(loop_start); loop_start = increment_start; self.patch_jump(body_jump); }
803
804 self.statement();
805 self.emit_loop(loop_start);
806
807 if let Some(offset) = exit_jump {
808 self.patch_jump(offset);
809 self.emit_instr(OpPop);
810 }
811
812 self.end_scope();
813 }
814
815 fn block(&mut self) {
816 while !self.check(TokenType::RightBrace) && !self.check(TokenType::EOF) {
817 self.declaration();
818 }
819 self.consume(TokenType::RightBrace, "Expected '}' after block"); }
821
822 fn this(&mut self) {
825 if self.current_module().current_class.is_none() {
826 self.error("Cannot use keyword 'this' outside of a class");
827 }
828 self.variable(false);
829 }
830
831 fn super_(&mut self) {
833 if self.current_module().current_class.is_none() {
834 self.error("Cannot use keyword 'super' outside of a class");
835 return; }
837
838 let superclass_index = if self.current_class().superclass.is_none() {
839 self.error("Cannot use keyword 'super' in a class which does not inherit a class");
840 0 } else {
842 self.current_class().superclass.unwrap()
843 };
844
845 self.consume(TokenType::Dot, "Expected '.' after 'super'");
846 self.consume(TokenType::Identifier, "Expected superclass method name");
847 let name = self.previous().lexeme.clone();
848 let name_index = self.identifier_constant(&name);
849
850 let superclass_val = Value::PhoenixClass(superclass_index);
855 self.emit_constant(superclass_val);
856 self.named_variable(&String::from("this"), false); self.emit_instr(OpGetSuper(name_index));
858 }
859
860 fn method(&mut self) {
861 self.consume(TokenType::Identifier, "Expected method name");
862 let name = self.previous().lexeme.clone();
863 let name_index = self.identifier_constant(&name);
864
865 let index = if name.eq("init") {
866 self.current_class().has_init = true;
867 self.function(FunctionType::Initializer)
868 } else {
869 self.function(FunctionType::Method)
870 };
871 self.current_class().methods.insert(name_index, index); }
882
883 fn function(&mut self, fun_type: FunctionType) -> usize {
885 let index = self.start_child(fun_type);
888 self.current_module().resolver.begin_scope();
889
890 self.consume(TokenType::LeftParen, "Expected '(' after function name");
891 if !self.check(TokenType::RightParen) {
892 loop {
893 let param_constant = self.parse_variable("Expected parameter name");
894 self.define_variable(param_constant);
895
896 let cur_function = self.current_fn();
897 cur_function.arity += 1;
898 if cur_function.arity > 255 {
899 self.error("Cannot have more than 255 parameters");
900 }
901
902 if !self.match_cur(TokenType::Comma) {
903 break;
904 }
905 }
906 }
907 self.consume(
908 TokenType::RightParen,
909 "Expected ')' after function parameters",
910 );
911
912 self.consume(TokenType::LeftBrace, "Expected '{' before function body");
913 self.block();
914
915 let upvalues = self.current_module().resolver.pop();
916 let has_upvalues = !upvalues.is_empty();
917 if !upvalues.is_empty() {
918 self.current_fn().set_upvalues(upvalues); }
920
921 self.end_child();
922
923 if fun_type != FunctionType::Method && fun_type != FunctionType::Initializer {
924 self.emit_constant(Value::PhoenixFunction(index));
926
927 if has_upvalues {
928 self.emit_instr(OpClosure);
929 }
930 }
931
932 index
933 }
934
935 fn expression_statement(&mut self) {
936 self.expression();
937 self.consume(TokenType::Semicolon, "Expected ';' after value");
938 self.emit_instr(OpPop);
939 }
940
941 fn expression(&mut self) {
942 self.parse_precedence(Precedence::Assignment)
943 }
944
945 fn and_operator(&mut self) {
946 let end_jump = self.emit_jif();
947
948 self.emit_instr(OpPop);
949 self.parse_precedence(Precedence::And); self.patch_jump(end_jump); }
953
954 fn or_operator(&mut self) {
955 let else_jump = self.emit_jif();
957
958 let end_jump = self.emit_jump();
960
961 self.patch_jump(else_jump);
962 self.emit_instr(OpPop);
963 self.parse_precedence(Precedence::Or);
964
965 self.patch_jump(end_jump);
966 }
967
968 fn number(&mut self) {
969 let s = &self.previous().lexeme;
973
974 if let Ok(value) = s.parse::<i64>() {
976 self.emit_constant(Value::Long(value));
977 } else {
978 if let Ok(value) = if s.ends_with('f') {
980 &s[0..s.len() - 1]
981 } else {
982 s
983 }
984 .parse::<f32>()
985 {
986 self.emit_constant(Value::Float(value));
987 } else {
988 self.error(format!("Invalid number: {s}").as_str());
989 }
990 }
991 }
992
993 fn literal(&mut self) {
994 match self.previous().token_type {
995 TokenType::False => self.emit_instr(OpFalse),
996 TokenType::True => self.emit_instr(OpTrue),
997 TokenType::Nil => self.emit_instr(OpNil),
998 _ => unreachable!(
999 "Unreachable state reached, attempted to make a literal out of a non-literal type???"
1000 ),
1001 }
1002 }
1003
1004 fn string(&mut self) {
1005 let str_val = self.previous().lexeme.clone();
1006 let cleaned = str_val[1..str_val.len() - 1].to_string();
1007
1008 self.emit_constant(Value::PhoenixString(cleaned));
1009 self.emit_instr(OpCreateString);
1010 }
1011
1012 fn list(&mut self, _can_assign: bool) {
1013 let mut size = 0;
1015 if !self.check(TokenType::RightBracket) {
1016 loop {
1017 self.expression();
1018 size += 1;
1019 if !self.match_cur(TokenType::Comma) {
1020 break;
1021 }
1022 }
1023 }
1024 self.consume(TokenType::RightBracket, "Expected ']' after list");
1025 self.emit_instr(OpCreateList(size));
1026 }
1027
1028 fn hashmap(&mut self, _can_assign: bool) {
1029 let mut size = 0;
1033 if !self.check(TokenType::RightBrace) {
1034 loop {
1035 self.expression();
1036 self.consume(TokenType::Colon, "Expected ':' after key");
1037 self.expression();
1038 size += 1;
1039 if !self.match_cur(TokenType::Comma) {
1040 break;
1041 }
1042 }
1043 }
1044 self.consume(TokenType::RightBrace, "Expected '}' after hashmap");
1045 self.emit_instr(OpCreateHashMap(size));
1046 }
1047
1048 fn variable(&mut self, can_assign: bool) {
1054 let name = &self.previous().lexeme.clone();
1055 self.named_variable(name, can_assign)
1056 }
1057
1058 fn named_variable(&mut self, name: &String, can_assign: bool) {
1064 let local_arg = match self.current_module().resolver.resolve_local(name) {
1065 Some(opt) => opt,
1066 None => {
1067 self.error("Cannot read local variable in its own initializer");
1068 return;
1069 }
1070 };
1071
1072 let (get_op, set_op) = if let Some(local_index) = local_arg {
1074 (OpGetLocal(local_index), OpSetLocal(local_index))
1075 } else if let Some(upvalue_index) = self.current_module().resolver.resolve_upvalue(name) {
1076 (OpGetUpvalue(upvalue_index), OpSetUpvalue(upvalue_index))
1077 } else {
1078 let global_arg = self.identifier_constant(name); if self.match_cur(TokenType::LeftParen) {
1081 let arg_count = self.argument_list();
1082 (
1083 OpCallGlobal(self.current_module, global_arg, arg_count),
1084 OpSetGlobal(global_arg),
1085 )
1086 } else {
1087 (OpGetGlobal(global_arg), OpSetGlobal(global_arg))
1088 }
1089 };
1090
1091 macro_rules! emit_assign {
1096 ($operation: path) => {{
1097 self.emit_instr(get_op);
1098 self.advance();
1099 self.expression();
1100 self.emit_instr($operation);
1101 self.emit_instr(set_op);
1102 }};
1103 }
1104 if can_assign {
1105 match self.current().token_type {
1106 TokenType::Equal => {
1107 self.advance();
1108 self.expression();
1109 self.emit_instr(set_op);
1110 }
1111 TokenType::PlusAssign => emit_assign!(OpAdd),
1112 TokenType::MinusAssign => emit_assign!(OpSubtract),
1113 TokenType::StarAssign => emit_assign!(OpMultiply),
1114 TokenType::SlashAssign => emit_assign!(OpDivide),
1115 TokenType::PlusPlus => {
1116 self.emit_instr(get_op);
1117 self.emit_constant(Value::Long(1));
1118 self.emit_instr(OpAdd);
1119 self.emit_instr(set_op);
1120 }
1121 TokenType::MinusMinus => {
1122 self.emit_instr(get_op);
1123 self.emit_constant(Value::Long(1));
1124 self.emit_instr(OpSubtract);
1125 self.emit_instr(set_op);
1126 }
1127 TokenType::LeftBracket => {
1128 self.advance();
1130 self.emit_instr(get_op);
1131 self.expression();
1132 self.consume(TokenType::RightBracket, "Expected ']' after index");
1133 if self.match_cur(TokenType::Equal) {
1134 self.expression();
1135 self.emit_instr(OpSetIndex);
1136 } else {
1138 self.emit_instr(OpGetIndex);
1139 }
1140 }
1141 _ => self.emit_instr(get_op),
1142 }
1143 } else {
1144 self.emit_instr(get_op);
1145 }
1146 }
1147
1148 fn grouping(&mut self) {
1149 self.expression();
1150 self.consume(TokenType::RightParen, "Expected ')' after expression");
1151 }
1152
1153 fn unary(&mut self) {
1154 let operator_type = self.previous().token_type;
1155 self.parse_precedence(Precedence::Unary); match operator_type {
1157 TokenType::Minus => self.emit_instr(OpNegate),
1158 TokenType::Bang => self.emit_instr(OpNot),
1159 _ => (), }
1161 }
1162
1163 fn binary(&mut self) {
1164 let operator_type = self.previous().token_type;
1165
1166 let rule = get_rule(operator_type);
1167 self.parse_precedence(rule.next_precedence());
1168
1169 match operator_type {
1171 TokenType::Plus => self.emit_instr(OpAdd),
1172 TokenType::Minus => self.emit_instr(OpSubtract),
1173 TokenType::Star => self.emit_instr(OpMultiply),
1174 TokenType::Slash => self.emit_instr(OpDivide),
1175 TokenType::BangEqual => self.emit_instrs(&[OpEqual, OpNot]),
1176 TokenType::EqualEqual => self.emit_instr(OpEqual),
1177 TokenType::Greater => self.emit_instr(OpGreater),
1178 TokenType::GreaterEqual => self.emit_instrs(&[OpLess, OpNot]),
1179 TokenType::Less => self.emit_instr(OpLess),
1180 TokenType::LessEqual => self.emit_instrs(&[OpGreater, OpNot]),
1181 _ => {
1182 self.error("Invalid binary operator");
1183 } }
1185 }
1186
1187 fn call(&mut self) {
1190 let arg_count = self.argument_list();
1191 self.emit_instr(OpCall(arg_count, self.current_module))
1192 }
1193
1194 fn argument_list(&mut self) -> usize {
1196 let mut arg_count = 0;
1197 if !self.check(TokenType::RightParen) {
1198 loop {
1199 self.expression();
1200 if arg_count == 255 {
1201 self.error("Cannot have more than 255 arguments");
1202 }
1203 arg_count += 1;
1204
1205 if !self.match_cur(TokenType::Comma) {
1206 break;
1207 }
1208 }
1209 }
1210 self.consume(
1211 TokenType::RightParen,
1212 "Expected ')' after function argument list",
1213 );
1214 arg_count
1215 }
1216
1217 fn dot(&mut self, can_assign: bool) {
1218 let module_name = &self.current_module_ref().tokens
1219 [self.current_module_ref().tokens.len() - 3]
1220 .lexeme
1221 .clone();
1222 if self.module_table.contains_key(module_name) {
1224 self.emit_instr(OpPop);
1226 let module_index = *self.module_table.get(module_name).unwrap();
1228 let current_module = self.current_module;
1232 self.current_module = module_index;
1233 self.expression();
1235 self.current_module = current_module;
1236 return;
1237 }
1238 self.consume(TokenType::Identifier, "Expected property name after '.'");
1239 let name_index = self.identifier_constant(&self.previous().lexeme.clone());
1240 if can_assign && self.match_cur(TokenType::Equal) {
1246 self.expression();
1249 self.emit_instr(OpSetProperty(name_index));
1250 } else if self.match_cur(TokenType::LeftParen) {
1251 let arg_count = self.argument_list();
1255 self.emit_instr(OpInvoke(name_index, arg_count, self.current_module));
1256 } else if self.match_cur(TokenType::LeftBracket) {
1257 self.emit_instr(OpGetProperty(name_index));
1258 self.expression();
1259 self.consume(TokenType::RightBracket, "Expected ']' after index");
1260 if self.match_cur(TokenType::Equal) {
1261 self.expression();
1262 self.emit_instr(OpSetIndex);
1263 } else {
1265 self.emit_instr(OpGetIndex);
1266 }
1267 } else {
1268 self.emit_instr(OpGetProperty(name_index));
1269 }
1270 }
1271
1272 fn start_child(&mut self, function_type: FunctionType) -> usize {
1274 let function_name = self.previous().lexeme.clone();
1275 self.current_module().functions.push(FunctionChunk::new(
1276 Some(function_name),
1277 0,
1278 function_type,
1279 ));
1280 self.current_module().resolver.push(function_type);
1281 let index = self.current_module_ref().current_function;
1282 self.current_module().parent_functions.push(index);
1283 self.current_module().current_function = self.current_module().functions.len() - 1;
1284
1285 self.current_module().functions.len() - 1
1286 }
1287
1288 fn end_child(&mut self) {
1290 let last_instr = self.current_chunk_ref().code.last();
1292 if last_instr.is_none() || last_instr.unwrap().op_code != OpReturn {
1293 self.emit_return();
1294 }
1295 self.current_module().current_function =
1296 self.current_module().parent_functions.pop().unwrap();
1297 }
1298
1299 #[deprecated(note = "Use new instead")]
1300 pub fn new_default(code: String, quiet: bool, start_line: usize) -> Compiler {
1301 Compiler::new_file(
1302 DEFAULT_FILE_NAME.to_string(),
1303 code,
1304 quiet,
1305 start_line,
1306 false,
1307 false,
1308 )
1309 }
1310
1311 pub fn new_file(
1312 file: String,
1313 code: String,
1314 quiet: bool,
1315 start_line: usize,
1316 debug_mode: bool,
1317 wait_mode: bool,
1318 ) -> Compiler {
1319 let mut compiler = Compiler {
1320 modules: vec![CompilerModuleChunk::new(
1321 true,
1322 "main".to_string(),
1323 file.to_string(),
1324 code.clone(),
1325 )],
1326 module_table: Default::default(),
1327 parent_modules: vec![],
1328 current_module: 0,
1329 current_module_code: 0,
1330
1331 had_error: false,
1332 panic_mode: false,
1333 quiet_mode: quiet,
1334 debug_mode,
1335 wait_mode,
1336 };
1337 compiler.new_start(file, code, quiet, start_line, 0);
1338 compiler
1339 }
1340
1341 pub fn new_start(
1343 &mut self,
1344 file: String,
1345 code: String,
1346 quiet: bool,
1347 start_line: usize,
1348 start_pos: usize,
1349 ) {
1350 self.current_module().scanner = Scanner::new(file, code, start_line);
1351 self.current_module().scanner.cur_pos = start_pos;
1352 self.current_module().scanner.start_pos = start_pos;
1353 self.quiet_mode = quiet;
1354 }
1355
1356 pub fn compile(&mut self, debug: bool) -> Option<CompilationResult> {
1357 self.debug_mode = debug;
1358 let first_token = self.current_module().scanner.scan_token();
1359 self.current_module().tokens.push(first_token.clone()); self.current_module()
1362 .functions
1363 .push(FunctionChunk::new(None, 0, FunctionType::Script)); if let TokenType::Error = first_token.token_type {
1367 self.advance();
1368 self.error(first_token.lexeme.as_str());
1369 }
1370 while !self.match_cur(TokenType::EOF) {
1371 self.declaration();
1372 }
1373 self.end_compilation();
1374
1375 if !self.had_error {
1376 if debug {
1377 for m in self.modules.iter() {
1378 println!("========= module: {} =========", m.scanner.file);
1379 for (index, fn_chunk) in m.functions.iter().enumerate() {
1380 if fn_chunk.fn_type != FunctionType::Method
1381 && fn_chunk.fn_type != FunctionType::Initializer
1382 {
1383 disassemble_fn_chunk(
1384 m.scanner.file.as_str().to_string(),
1385 index,
1386 fn_chunk,
1387 &m.constants,
1388 &m.identifier_constants,
1389 );
1390 }
1391 }
1392
1393 for class_chunk in m.classes.iter() {
1394 disassemble_class_chunk(
1395 class_chunk,
1396 &m.functions,
1397 &m.classes,
1398 &m.constants,
1399 &m.identifier_constants,
1400 );
1401 }
1402 }
1403 }
1404 Some(CompilationResult {
1405 version: VERSION.to_string(),
1406 modules: self
1407 .modules
1408 .clone()
1409 .iter()
1410 .map(|m| ModuleChunk::from(m.clone()))
1411 .collect(),
1412 modules_table: self.module_table.clone(),
1413 cur_pos: self.current_module().scanner.cur_pos,
1414 })
1415 } else {
1416 None
1417 }
1418 }
1419
1420 pub fn compile_code(code: String, debug: bool, wait: bool) -> Option<CompilationResult> {
1421 let mut compiler =
1422 Compiler::new_file(DEFAULT_FILE_NAME.to_string(), code, false, 0, debug, wait);
1423 compiler.compile(debug)
1424 }
1425}
1426
1427impl Clone for Compiler {
1428 fn clone(&self) -> Self {
1429 Compiler {
1430 modules: self.modules.clone(),
1431 module_table: self.module_table.clone(),
1432 parent_modules: self.parent_modules.clone(),
1433 current_module: self.current_module,
1434 current_module_code: 0,
1435
1436 had_error: self.had_error,
1437 panic_mode: self.panic_mode,
1438 quiet_mode: self.quiet_mode,
1439 debug_mode: false,
1440 wait_mode: self.wait_mode,
1441 }
1442 }
1443}
1444
1445#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
1446pub struct CompilationResult {
1447 pub version: String,
1448 pub modules: Vec<ModuleChunk>,
1449 pub modules_table: HashMap<String, usize>,
1450 pub cur_pos: usize,
1451}
1452
1453impl Default for CompilationResult {
1454 fn default() -> Self {
1455 CompilationResult::new()
1456 }
1457}
1458
1459impl CompilationResult {
1460 pub fn new() -> CompilationResult {
1461 CompilationResult {
1462 version: VERSION.to_string(),
1463 modules: vec![],
1464 modules_table: Default::default(),
1465 cur_pos: 0,
1466 }
1467 }
1468
1469 }