diff --git a/rust/src/base/codegen.rs b/rust/src/base/codegen.rs index 83c1ae0f..eb9132d6 100644 --- a/rust/src/base/codegen.rs +++ b/rust/src/base/codegen.rs @@ -1,6 +1,6 @@ use super::func; use core::cmp::max; -use std::fmt::Display; +use std::{fmt::Display, usize}; #[derive(Debug, PartialEq, Clone)] pub enum Opcode { @@ -134,6 +134,7 @@ impl ConstPool { } pub const NO_ARG: usize = 0; +pub const ARG_WRONG: usize = usize::MAX; #[derive(Debug, PartialEq)] pub struct Inst { diff --git a/rust/src/compiler/ast.rs b/rust/src/compiler/ast.rs index b899a444..35de177f 100644 --- a/rust/src/compiler/ast.rs +++ b/rust/src/compiler/ast.rs @@ -4,7 +4,7 @@ use super::{ InputSource, TokenLex, ValuePool, }; use crate::base::{ - codegen::{Inst, Opcode, StaticData, VmStackType, NO_ARG}, + codegen::{Inst, Opcode, StaticData, VmStackType, ARG_WRONG, NO_ARG}, error::*, stdlib::{get_stdlib, RustFunction, BOOL, CHAR, FLOAT, INT, STR}, }; @@ -664,11 +664,10 @@ impl<'a> AstBuilder<'a> { self.check_next_token(TokenType::LeftBigBrace)?; // 最后需要跳转地址 let mut save_jump_opcode_idx = vec![]; - let last_should_be_jumped; loop { let op_idx = self.staticdata.inst.len(); // 本行是为了跳转到下一个分支 - self.add_bycode(Opcode::JumpIfFalse, 0); + self.add_bycode(Opcode::JumpIfFalse, ARG_WRONG); loop { let t = self.token_lexer.next_token()?; if t.tp == TokenType::RightBigBrace { @@ -678,13 +677,12 @@ impl<'a> AstBuilder<'a> { self.statement()?; } self.staticdata.inst[op_idx].operand = self.staticdata.get_last_opcode_id() + 1; + self.add_bycode(Opcode::Jump, ARG_WRONG); + save_jump_opcode_idx.push(self.staticdata.get_last_opcode_id()); let t = self.token_lexer.next_token()?; if t.tp == TokenType::Else { 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)?; continue; @@ -699,19 +697,26 @@ impl<'a> AstBuilder<'a> { self.token_lexer.next_back(t); self.statement()?; } - last_should_be_jumped = self.staticdata.get_last_opcode_id() + 1; break; } + save_jump_opcode_idx.pop(); + self.del_opcode().unwrap(); self.token_lexer.next_back(t); - last_should_be_jumped = self.staticdata.get_last_opcode_id() + 1; break; } for i in save_jump_opcode_idx { - self.staticdata.inst[i].operand = last_should_be_jumped; + self.staticdata.inst[i].operand = self.staticdata.get_last_opcode_id() + 1; } Ok(()) } + fn del_opcode(&mut self) -> Result<(), ()> { + match self.staticdata.inst.pop() { + Some(_) => Ok(()), + None => Err(()), + } + } + fn statement(&mut self) -> RunResult<()> { let t = self.token_lexer.next_token()?; match t.tp { @@ -1055,66 +1060,23 @@ if a<8{ assert_eq!( t.staticdata.inst, vec![ - Inst { - opcode: Opcode::LoadInt, - operand: 2 - }, - Inst { - opcode: Opcode::StoreInt, - operand: 0 - }, - Inst { - opcode: Opcode::LoadVarInt, - operand: 0 - }, - Inst { - opcode: Opcode::LoadInt, - operand: 3 - }, - Inst { - opcode: Opcode::LtInt, - operand: 0 - }, - Inst { - opcode: Opcode::JumpIfFalse, - operand: 15 - }, - Inst { - opcode: Opcode::Jump, - operand: 0 - }, - Inst { - opcode: Opcode::LoadVarInt, - operand: 0 - }, - Inst { - opcode: Opcode::LoadInt, - operand: 4 - }, - Inst { - opcode: Opcode::GtInt, - operand: 0 - }, - Inst { - opcode: Opcode::JumpIfFalse, - operand: 11 - }, - Inst { - opcode: Opcode::LoadInt, - operand: 3 - }, - Inst { - opcode: Opcode::LoadInt, - operand: 5 - }, - Inst { - opcode: Opcode::EqInt, - operand: 0 - }, - Inst { - opcode: Opcode::JumpIfFalse, - operand: 15 - } + Inst::new(Opcode::LoadInt, 2), + Inst::new(Opcode::StoreInt, 0), + Inst::new(Opcode::LoadVarInt, 0), + Inst::new(Opcode::LoadInt, 3), + Inst::new(Opcode::LtInt, 0), + Inst::new(Opcode::JumpIfFalse, 6), + Inst::new(Opcode::Jump, 17), + Inst::new(Opcode::LoadVarInt, 0), + Inst::new(Opcode::LoadInt, 4), + Inst::new(Opcode::GtInt, 0), + Inst::new(Opcode::JumpIfFalse, 11), + Inst::new(Opcode::Jump, 17), + Inst::new(Opcode::LoadInt, 3), + Inst::new(Opcode::LoadInt, 5), + Inst::new(Opcode::EqInt, 0), + Inst::new(Opcode::JumpIfFalse, 16), + Inst::new(Opcode::Jump, 17) ] ) } diff --git a/rust/src/tvm.rs b/rust/src/tvm.rs index abb9b55b..fcc32b24 100644 --- a/rust/src/tvm.rs +++ b/rust/src/tvm.rs @@ -64,7 +64,7 @@ impl<'a> DynaData<'a> { pub fn resize_var_store(&mut self, cap: usize) { // 宁浪费不放过 - self.var_store.resize(cap, 0 as *mut TrcInt); + self.var_store.resize(cap, ptr::null_mut::()); self.int_store.resize(cap, 0); self.float_store.resize(cap, 0.0); self.str_store.resize(cap, ptr::null_mut()); @@ -596,7 +596,9 @@ mod tests { fn gen_test_env(code: &str) -> Vm { let mut compiler = Compiler::new_string_compiler(Option::new(false, InputSource::StringInternal), code); - Vm::new_init(compiler.lex().unwrap()) + let com_tmp = compiler.lex().unwrap(); + // println!("{:?}", com_tmp.inst); + Vm::new_init(com_tmp) } #[test] @@ -617,14 +619,33 @@ mod tests { #[test] fn test_if_easy() { - let mut vm = gen_test_env(r#"if 1==1 { print("hello world") }"#); + let mut vm = gen_test_env(r#"if 1==1 { println("ok") }"#); 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") }"#); + let mut vm = gen_test_env(r#"if 1==1 { println("ok") } else { println("error") }"#); + vm.run().unwrap() + } + + #[test] + fn test_if_final() { + let mut vm = gen_test_env( + r#"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") + } +}"#, + ); vm.run().unwrap() } }