Skip to content

Commit

Permalink
impl trc shell
Browse files Browse the repository at this point in the history
  • Loading branch information
limuy2022 committed Mar 9, 2024
1 parent f27e431 commit 844e5b1
Show file tree
Hide file tree
Showing 10 changed files with 109 additions and 69 deletions.
6 changes: 3 additions & 3 deletions rust/src/base/codegen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,7 @@ impl Display for Opcode {
}
}

#[derive(Default)]
#[derive(Default, Clone)]
pub struct ConstPool {
pub intpool: Vec<i64>,
pub stringpool: Vec<String>,
Expand All @@ -136,7 +136,7 @@ impl ConstPool {
pub const NO_ARG: usize = 0;
pub const ARG_WRONG: usize = usize::MAX;

#[derive(Debug, PartialEq)]
#[derive(Debug, PartialEq, Clone)]
pub struct Inst {
pub opcode: Opcode,
pub operand: usize,
Expand All @@ -160,7 +160,7 @@ pub enum VmStackType {

pub type InstSet = Vec<Inst>;

#[derive(Default)]
#[derive(Default, Clone)]
pub struct StaticData {
pub constpool: ConstPool,
pub inst: InstSet,
Expand Down
1 change: 1 addition & 0 deletions rust/src/base/func.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
#[derive(Clone)]
pub struct Func {
pub name: String,
}
Expand Down
18 changes: 5 additions & 13 deletions rust/src/compiler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,24 +384,16 @@ impl Compiler {
self.input = input;
}

pub fn lex(&mut self) -> RunResult<StaticData> {
pub fn lex(&mut self) -> RunResult<AstBuilder> {
let token_lexer = TokenLex::new(self);
let mut ast_builder = ast::AstBuilder::new(token_lexer);
let mut ast_builder = AstBuilder::new(token_lexer);
ast_builder.generate_code()?;
Ok(ast_builder.return_static_data())
Ok(ast_builder)
}

pub fn lex_times(&mut self) -> RunResult<StaticData> {
pub fn get_token_lex(&mut self) -> TokenLex {
let token_lexer = TokenLex::new(self);
let mut ast_builder = ast::AstBuilder::new(token_lexer);
ast_builder.generate_code()?;
Ok(ast_builder.return_static_data())
}

pub fn get_ast_obj(&mut self) -> AstBuilder {
let token_lexer = TokenLex::new(self);
let ast_builder = ast::AstBuilder::new(token_lexer);
ast_builder
token_lexer
}

#[inline]
Expand Down
31 changes: 21 additions & 10 deletions rust/src/compiler/ast.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
use super::{
scope::{self, *},
token::TokenType,
InputSource, TokenLex, ValuePool,
};
use std::{borrow::Borrow, cell::RefCell, rc::Rc};

use rust_i18n::t;

use crate::base::{
codegen::{Inst, Opcode, StaticData, VmStackType, ARG_WRONG, NO_ARG},
error::*,
stdlib::{get_stdlib, RustFunction, BOOL, CHAR, FLOAT, INT, STR},
};
use rust_i18n::t;
use std::{borrow::Borrow, cell::RefCell, rc::Rc};

use super::{scope::*, token::TokenType, InputSource, TokenLex, ValuePool};

/// 过程间分析用的结构
#[derive(Default)]
Expand Down Expand Up @@ -67,7 +66,7 @@ impl Cache {
}

pub struct AstBuilder<'a> {
token_lexer: TokenLex<'a>,
pub token_lexer: TokenLex<'a>,
staticdata: StaticData,
self_scope: Rc<RefCell<SymScope>>,
process_info: LexProcess,
Expand Down Expand Up @@ -143,6 +142,10 @@ macro_rules! expr_gen {
}

impl<'a> AstBuilder<'a> {
pub fn clear_inst(&mut self) {
self.staticdata.inst.clear();
}

fn report_error<T>(&self, info: ErrorInfo) -> AstError<T> {
self.token_lexer.compiler_data.report_compiler_error(info)
}
Expand Down Expand Up @@ -221,6 +224,8 @@ impl<'a> AstBuilder<'a> {
}
}

pub fn modify_token_lexer(&mut self, token_lexer: TokenLex<'a>) {}

expr_gen!(expr9, expr9_, factor, TokenType::Power);
expr_gen!(
expr8,
Expand Down Expand Up @@ -256,8 +261,13 @@ impl<'a> AstBuilder<'a> {
expr_gen!(expr1, expr1_, expr2, TokenType::And);
expr_gen!(expr, expr_, expr1, TokenType::Or);

pub fn return_static_data(mut self) -> StaticData {
pub fn prepare_get_static(&mut self) -> &StaticData {
self.staticdata.constpool = self.token_lexer.const_pool.store_val_to_vm();
&self.staticdata
}

pub fn return_static_data(mut self) -> StaticData {
self.prepare_get_static();
self.staticdata
}

Expand Down Expand Up @@ -789,9 +799,10 @@ impl<'a> AstBuilder<'a> {

#[cfg(test)]
mod tests {
use super::*;
use crate::compiler::*;

use super::*;

macro_rules! gen_test_env {
($test_code:expr, $env_name:ident) => {
use crate::compiler::InputSource;
Expand Down
6 changes: 5 additions & 1 deletion rust/src/compiler/token.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ use rust_i18n::t;

use crate::{base::error::*, cfg::FLOAT_OVER_FLOW_LIMIT, hash_map};

use super::{Compiler, Context, Float, ValuePool};
use super::{Compiler, Context, Float, TokenIo, ValuePool};

#[derive(PartialEq, Debug, Clone, Hash, Eq)]
pub enum TokenType {
Expand Down Expand Up @@ -318,6 +318,10 @@ impl<'a> TokenLex<'a> {
}
}

pub fn modify_input(&mut self, source: Box<dyn TokenIo<Item = char>>) {
self.compiler_data.input = source;
}

fn lex_id(&mut self, c: char) -> RunResult<Token> {
Ok({
let mut retname: String = String::from(c);
Expand Down
9 changes: 4 additions & 5 deletions rust/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -57,14 +57,13 @@ pub fn run() -> Result<(), Box<dyn Error>> {
}
}
Commands::Tshell {} => {
tools::tshell::tshell();
tools::tshell::tshell()?;
}
Commands::Update {} => match tools::update::update() {
Err(e) => {
Commands::Update {} => {
if let Err(e) = tools::update::update() {
println!("{}", e);
}
Ok(_) => {}
},
}
Commands::Run {
optimize: opt,
files,
Expand Down
3 changes: 2 additions & 1 deletion rust/src/tools/compile_tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ use std::process::exit;

pub fn compile(opt: compiler::Option, dev: bool) {
let mut compiler = compiler::Compiler::new(opt);
match compiler.lex() {
let tmp = compiler.lex();
match tmp {
Ok(data) => {}
Err(e) => {
if dev {
Expand Down
4 changes: 2 additions & 2 deletions rust/src/tools/run.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ use crate::{
pub fn run(opt: compiler::Option) -> RunResult<()> {
let mut compiler = Compiler::new(opt);
let static_data = compiler.lex()?;
let mut run_vm = Vm::new();
run_vm.set_static_data(static_data);
let tmp = static_data.return_static_data();
let mut run_vm = Vm::new(&tmp);
run_vm.run()?;
Ok(())
}
50 changes: 45 additions & 5 deletions rust/src/tools/tshell.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,63 @@ use colored::*;
use rust_i18n::t;
use std::io::{self, Write};

use crate::compiler;
use crate::{
base::{codegen::StaticData, error::RunResult},
compiler,
tvm::Vm,
};

fn get_block() {}
fn get_block() -> String {
let mut block = String::new();
let mut cnt = 1;
loop {
let mut line = String::new();
io::stdin().read_line(&mut line).unwrap();
if line.ends_with('{') {
cnt += 1;
}
if line.ends_with('}') {
cnt -= 1;
if cnt == 0 {
break;
}
}
block += &line;
}
block
}

pub fn tshell() {
pub fn tshell() -> RunResult<()> {
println!("{}\n\n", t!("tshell.welcome").bold());
let mut compiler = compiler::Compiler::new_string_compiler(
compiler::Option::new(false, compiler::InputSource::StringInternal),
"",
);
// let ast = compiler.get_ast_obj();
let mut ast = compiler.lex()?;
let mut vm = unsafe { Vm::new(&*(ast.prepare_get_static() as *const StaticData)) };
loop {
print!("tshell>");
io::stdout().flush().unwrap();
let mut line = String::new();
io::stdin().read_line(&mut line).unwrap();
if line.ends_with('{') {
line += &get_block();
continue;
}
let source = Box::new(compiler::StringSource::new(line));
compiler.modify_input(source);
ast.token_lexer.modify_input(source);
ast.clear_inst();
ast.generate_code().unwrap_or_else(|e| {
eprintln!("{}", e);
});
vm.set_static_data(unsafe { &*(ast.prepare_get_static() as *const StaticData) });
match vm.run() {
Ok(_) => {}
Err(e) => {
eprintln!("{}", e);
}
}
}
}

mod tests {}
50 changes: 21 additions & 29 deletions rust/src/tvm.rs
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ pub struct Vm<'a> {
run_context: Context,
dynadata: DynaData<'a>,
pc: usize,
static_data: StaticData,
static_data: &'a StaticData,
}

#[derive(Debug, Clone)]
Expand Down Expand Up @@ -184,23 +184,8 @@ macro_rules! impl_opcode {
}};
}

impl Default for Vm<'_> {
fn default() -> Self {
Self::new()
}
}

impl<'a> Vm<'a> {
pub fn new() -> Self {
Self {
pc: 0,
dynadata: DynaData::new(),
run_context: Context::new(cfg::MAIN_MODULE_NAME),
static_data: StaticData::new(false),
}
}

fn new_init(static_data: StaticData) -> Self {
pub fn new(static_data: &'a StaticData) -> Self {
Self {
pc: 0,
dynadata: DynaData::new(),
Expand All @@ -209,7 +194,7 @@ impl<'a> Vm<'a> {
}
}

pub fn set_static_data(&mut self, static_data: StaticData) {
pub fn set_static_data(&mut self, static_data: &'a StaticData) {
self.static_data = static_data;
}

Expand Down Expand Up @@ -593,45 +578,51 @@ mod tests {
use super::*;
use crate::compiler::*;

fn gen_test_env(code: &str) -> Vm {
let mut compiler =
Compiler::new_string_compiler(Option::new(false, InputSource::StringInternal), code);
let com_tmp = compiler.lex().unwrap();
// println!("{:?}", com_tmp.inst);
Vm::new_init(com_tmp)
macro_rules! gen_test_env {
($code:expr, $var:ident) => {
let mut compiler = Compiler::new_string_compiler(
Option::new(false, InputSource::StringInternal),
$code,
);
let com_tmp = compiler.lex().unwrap();
// println!("{:?}", com_tmp.inst);
let tmp = com_tmp.return_static_data();
let mut $var = Vm::new(&tmp);
};
}

#[test]
fn test_stdfunc() {
let mut vm = gen_test_env(r#"print("{},{},{},{}", 1, "h", 'p', true)"#);
gen_test_env!(r#"print("{},{},{},{}", 1, "h", 'p', true)"#, vm);
vm.run().unwrap()
}

#[test]
fn test_var_define() {
let mut vm = gen_test_env(
gen_test_env!(
r#"a:=10
a=10
print("{}", a)"#,
vm
);
vm.run().unwrap()
}

#[test]
fn test_if_easy() {
let mut vm = gen_test_env(r#"if 1==1 { println("ok") }"#);
gen_test_env!(r#"if 1==1 { println("ok") }"#, vm);
vm.run().unwrap()
}

#[test]
fn test_if_easy2() {
let mut vm = gen_test_env(r#"if 1==1 { println("ok") } else { println("error") }"#);
gen_test_env!(r#"if 1==1 { println("ok") } else { println("error") }"#, vm);
vm.run().unwrap()
}

#[test]
fn test_if_final() {
let mut vm = gen_test_env(
gen_test_env!(
r#"a:=90
if a==90 {
println("i equal to 90")
Expand All @@ -645,6 +636,7 @@ if a < 89 {
println("i is odd")
}
}"#,
vm
);
vm.run().unwrap()
}
Expand Down

0 comments on commit 844e5b1

Please sign in to comment.