diff --git a/rust/examples/if.trc b/rust/examples/if.trc new file mode 100644 index 00000000..19362335 --- /dev/null +++ b/rust/examples/if.trc @@ -0,0 +1,13 @@ +a:=90 +if a==90 { + println("i equal to 90") +} +if a < 89 { + println("i less than 90") +} else { + if a % 2 == 0 { + println("i is even") + } else { + println("i is odd") + } +} diff --git a/rust/src/compiler/ast.rs b/rust/src/compiler/ast.rs index e5aac412..b899a444 100644 --- a/rust/src/compiler/ast.rs +++ b/rust/src/compiler/ast.rs @@ -680,18 +680,27 @@ impl<'a> AstBuilder<'a> { self.staticdata.inst[op_idx].operand = self.staticdata.get_last_opcode_id() + 1; let t = self.token_lexer.next_token()?; if t.tp == TokenType::Else { - save_jump_opcode_idx.push(self.staticdata.get_last_opcode_id()); - self.add_bycode(Opcode::Jump, 0); let nxt_tok = self.token_lexer.next_token()?; if nxt_tok.tp == TokenType::If { + save_jump_opcode_idx.push(self.staticdata.get_last_opcode_id()); + self.add_bycode(Opcode::Jump, 0); // self.check_next_token(TokenType::If)?; self.expr(false)?; self.check_next_token(TokenType::LeftBigBrace)?; - } else { - self.token_lexer.next_back(nxt_tok); - self.check_next_token(TokenType::LeftBigBrace)?; + continue; + } + self.token_lexer.next_back(nxt_tok); + self.check_next_token(TokenType::LeftBigBrace)?; + loop { + let t = self.token_lexer.next_token()?; + if t.tp == TokenType::RightBigBrace { + break; + } + self.token_lexer.next_back(t); + self.statement()?; } - continue; + last_should_be_jumped = self.staticdata.get_last_opcode_id() + 1; + break; } self.token_lexer.next_back(t); last_should_be_jumped = self.staticdata.get_last_opcode_id() + 1; @@ -1068,7 +1077,7 @@ if a<8{ }, Inst { opcode: Opcode::JumpIfFalse, - operand: 19 + operand: 15 }, Inst { opcode: Opcode::Jump, @@ -1088,15 +1097,7 @@ if a<8{ }, Inst { opcode: Opcode::JumpIfFalse, - operand: 19 - }, - Inst { - opcode: Opcode::Jump, - operand: 0 - }, - Inst { - opcode: Opcode::JumpIfFalse, - operand: 19 + operand: 11 }, Inst { opcode: Opcode::LoadInt, @@ -1112,15 +1113,7 @@ if a<8{ }, Inst { opcode: Opcode::JumpIfFalse, - operand: 19 - }, - Inst { - opcode: Opcode::Jump, - operand: 0 - }, - Inst { - opcode: Opcode::JumpIfFalse, - operand: 19 + operand: 15 } ] ) diff --git a/rust/src/compiler/token.rs b/rust/src/compiler/token.rs index 258fe7a6..01f25662 100644 --- a/rust/src/compiler/token.rs +++ b/rust/src/compiler/token.rs @@ -813,7 +813,6 @@ impl TokenLex<'_> { pub fn check(&mut self) -> Result<(), RuntimeError> { if !self.braces_check.is_empty() { let unmatch_char = self.braces_check.pop().unwrap(); - self.clear_error(); return self.report_error_with_context(RuntimeError::new( Box::new(Context::new_line( &self.compiler_data.context.module_name, diff --git a/rust/src/tvm.rs b/rust/src/tvm.rs index 017a1135..abb9b55b 100644 --- a/rust/src/tvm.rs +++ b/rust/src/tvm.rs @@ -530,9 +530,10 @@ impl<'a> Vm<'a> { } Opcode::MoveStr => { // todo:inmprove performance - let ptr = self.dynadata.gc.alloc(TrcStr::new(unsafe { - self.dynadata.str_stack.pop().unwrap() - })); + let ptr = self + .dynadata + .gc + .alloc(TrcStr::new(self.dynadata.str_stack.pop().unwrap())); self.dynadata.obj_stack.push(ptr); } Opcode::StoreInt => { @@ -590,9 +591,7 @@ impl<'a> Vm<'a> { #[cfg(test)] mod tests { use super::*; - use crate::compiler::Compiler; - use crate::compiler::InputSource; - use crate::compiler::Option; + use crate::compiler::*; fn gen_test_env(code: &str) -> Vm { let mut compiler = @@ -615,4 +614,17 @@ mod tests { ); vm.run().unwrap() } + + #[test] + fn test_if_easy() { + let mut vm = gen_test_env(r#"if 1==1 { print("hello world") }"#); + vm.run().unwrap() + } + + #[test] + fn test_if_easy2() { + let mut vm = + gen_test_env(r#"if 1==1 { print("hello world") } else { print("hello world2") }"#); + vm.run().unwrap() + } } diff --git a/rust/src/tvm/stdlib/prelude.rs b/rust/src/tvm/stdlib/prelude.rs index fb907801..76972d07 100644 --- a/rust/src/tvm/stdlib/prelude.rs +++ b/rust/src/tvm/stdlib/prelude.rs @@ -50,7 +50,7 @@ pub fn println(fmt_string: str) -> void { io::stdout().write_all(b"\n").unwrap(); } -def_module!(module_name = prelude, functions = [print => print, println => print], classes = [ +def_module!(module_name = prelude, functions = [print => print, println => println], classes = [ TrcInt => int, TrcStr => str, TrcBool => bool,