Skip to content

Commit

Permalink
finish if
Browse files Browse the repository at this point in the history
  • Loading branch information
limuy2022 committed Mar 9, 2024
1 parent 3769e65 commit d598b6d
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 75 deletions.
3 changes: 2 additions & 1 deletion rust/src/base/codegen.rs
Original file line number Diff line number Diff line change
@@ -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 {
Expand Down Expand Up @@ -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 {
Expand Down
100 changes: 31 additions & 69 deletions rust/src/compiler/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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},
};
Expand Down Expand Up @@ -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 {
Expand All @@ -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;
Expand All @@ -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 {
Expand Down Expand Up @@ -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)
]
)
}
Expand Down
31 changes: 26 additions & 5 deletions rust/src/tvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<TrcInt>());
self.int_store.resize(cap, 0);
self.float_store.resize(cap, 0.0);
self.str_store.resize(cap, ptr::null_mut());
Expand Down Expand Up @@ -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]
Expand All @@ -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()
}
}

0 comments on commit d598b6d

Please sign in to comment.