From a40b6e09cd6ec578ea70c7036a3d3f1353308038 Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Wed, 6 May 2020 00:01:07 +0800 Subject: [PATCH] add InsId --- src/ins.rs | 135 +++++++++++++++++++++++++++++++++++++++------------- src/main.rs | 10 ++-- 2 files changed, 107 insertions(+), 38 deletions(-) diff --git a/src/ins.rs b/src/ins.rs index 10a9d49..f220f17 100644 --- a/src/ins.rs +++ b/src/ins.rs @@ -1,8 +1,77 @@ + +#[derive(Debug)] +pub enum InsId { + Push, // has data + Dup, + CopyN, // has data + Swap, + Pop, + PopN, // has data + Add, + Sub, + Mul, + Div, + Mod, + Store, + Retrieve, + DefineLabel, // has data + CallAtLabel, // has data + GotoLabel, // has data + GotoLabelE0, // has data + GotoLabelL0, // has data + ReturnCallAt, + End, + StdOutChar, + StdOutNum, + StdInChar, + StdInNum, +} + +impl InsId { + pub fn has_data(&self) -> bool { + match self { + InsId::Push | InsId::CopyN | InsId::PopN | + InsId::DefineLabel | InsId::CallAtLabel | + InsId::GotoLabel | InsId::GotoLabelE0 | InsId::GotoLabelL0 => true, + _ => false, + } + } + + pub fn new_instruction(&self, data: Option) -> Instruction { + match self { + InsId::Push => Instruction::Push(data.unwrap_or(0)), + InsId::Dup => Instruction::Dup, + InsId::CopyN => Instruction::CopyN(data.unwrap_or(0)), + InsId::Swap => Instruction::Swap, + InsId::Pop => Instruction::Pop, + InsId::PopN => Instruction::PopN(data.unwrap_or(0)), + InsId::Add => Instruction::Add, + InsId::Sub => Instruction::Sub, + InsId::Mul => Instruction::Mul, + InsId::Div => Instruction::Div, + InsId::Mod => Instruction::Mod, + InsId::Store => Instruction::Store, + InsId::Retrieve => Instruction::Retrieve, + InsId::DefineLabel => Instruction::DefineLabel(data.unwrap_or(0)), + InsId::CallAtLabel => Instruction::CallAtLabel(data.unwrap_or(0)), + InsId::GotoLabel => Instruction::GotoLabel(data.unwrap_or(0)), + InsId::GotoLabelE0 => Instruction::GotoLabelE0(data.unwrap_or(0)), + InsId::GotoLabelL0 => Instruction::GotoLabelL0(data.unwrap_or(0)), + InsId::ReturnCallAt => Instruction::ReturnCallAt, + InsId::End => Instruction::End, + InsId::StdOutChar => Instruction::StdOutChar, + InsId::StdOutNum => Instruction::StdOutNum, + InsId::StdInChar => Instruction::StdInChar, + InsId::StdInNum => Instruction::StdInNum, + } + } +} + #[derive(Debug)] pub enum InsType { Path(InsColl), - Node(Instruction), + Node(InsId), } #[derive(Debug)] @@ -19,57 +88,57 @@ pub struct InsColl { pub fn make_instruction_tree() -> InsColl { InsColl{ inses: vec![ Ins{ c: '草', ins_type: InsType::Path(InsColl{ inses: vec![ - Ins{ c: '草', ins_type: InsType::Node(Instruction::Push) }, + Ins{ c: '草', ins_type: InsType::Node(InsId::Push) }, Ins{ c: '马', ins_type: InsType::Path(InsColl{ inses: vec![ - Ins{ c: '草', ins_type: InsType::Node(Instruction::Dup) }, - Ins{ c: '泥', ins_type: InsType::Node(Instruction::Swap) }, - Ins{ c: '马', ins_type: InsType::Node(Instruction::Pop) } + Ins{ c: '草', ins_type: InsType::Node(InsId::Dup) }, + Ins{ c: '泥', ins_type: InsType::Node(InsId::Swap) }, + Ins{ c: '马', ins_type: InsType::Node(InsId::Pop) } ]})}, Ins{ c: '泥', ins_type: InsType::Path(InsColl{ inses: vec![ - Ins{ c: '草', ins_type: InsType::Node(Instruction::CopyN) }, - Ins{ c: '马', ins_type: InsType::Node(Instruction::PopN) } + Ins{ c: '草', ins_type: InsType::Node(InsId::CopyN) }, + Ins{ c: '马', ins_type: InsType::Node(InsId::PopN) } ]})}, ]})}, Ins{ c: '泥', ins_type: InsType::Path(InsColl{ inses: vec![ Ins{ c: '草', ins_type: InsType::Path(InsColl{ inses: vec![ Ins{ c: '草', ins_type: InsType::Path(InsColl{ inses: vec![ - Ins{ c: '草', ins_type: InsType::Node(Instruction::Add) }, - Ins{ c: '泥', ins_type: InsType::Node(Instruction::Sub) }, - Ins{ c: '马', ins_type: InsType::Node(Instruction::Mul) }, + Ins{ c: '草', ins_type: InsType::Node(InsId::Add) }, + Ins{ c: '泥', ins_type: InsType::Node(InsId::Sub) }, + Ins{ c: '马', ins_type: InsType::Node(InsId::Mul) }, ]})}, Ins{ c: '泥', ins_type: InsType::Path(InsColl{ inses: vec![ - Ins{ c: '草', ins_type: InsType::Node(Instruction::Div) }, - Ins{ c: '泥', ins_type: InsType::Node(Instruction::Mod) }, + Ins{ c: '草', ins_type: InsType::Node(InsId::Div) }, + Ins{ c: '泥', ins_type: InsType::Node(InsId::Mod) }, ]})}, ]})}, Ins{ c: '泥', ins_type: InsType::Path(InsColl{ inses: vec![ - Ins{ c: '草', ins_type: InsType::Node(Instruction::Store) }, - Ins{ c: '泥', ins_type: InsType::Node(Instruction::Retrieve) }, + Ins{ c: '草', ins_type: InsType::Node(InsId::Store) }, + Ins{ c: '泥', ins_type: InsType::Node(InsId::Retrieve) }, ]})}, Ins{ c: '马', ins_type: InsType::Path(InsColl{ inses: vec![ Ins{ c: '草', ins_type: InsType::Path(InsColl{ inses: vec![ - Ins{ c: '草', ins_type: InsType::Node(Instruction::StdOutChar) }, - Ins{ c: '泥', ins_type: InsType::Node(Instruction::StdOutNum) }, + Ins{ c: '草', ins_type: InsType::Node(InsId::StdOutChar) }, + Ins{ c: '泥', ins_type: InsType::Node(InsId::StdOutNum) }, ]})}, Ins{ c: '泥', ins_type: InsType::Path(InsColl{ inses: vec![ - Ins{ c: '草', ins_type: InsType::Node(Instruction::StdInChar) }, - Ins{ c: '泥', ins_type: InsType::Node(Instruction::StdInNum) }, + Ins{ c: '草', ins_type: InsType::Node(InsId::StdInChar) }, + Ins{ c: '泥', ins_type: InsType::Node(InsId::StdInNum) }, ]})}, ]})}, ]})}, Ins{ c: '马', ins_type: InsType::Path(InsColl{ inses: vec![ Ins{ c: '草', ins_type: InsType::Path(InsColl{ inses: vec![ - Ins{ c: '草', ins_type: InsType::Node(Instruction::DefineLabel) }, - Ins{ c: '泥', ins_type: InsType::Node(Instruction::CallAtLabel) }, - Ins{ c: '马', ins_type: InsType::Node(Instruction::GotoLabel) }, + Ins{ c: '草', ins_type: InsType::Node(InsId::DefineLabel) }, + Ins{ c: '泥', ins_type: InsType::Node(InsId::CallAtLabel) }, + Ins{ c: '马', ins_type: InsType::Node(InsId::GotoLabel) }, ]})}, Ins{ c: '泥', ins_type: InsType::Path(InsColl{ inses: vec![ - Ins{ c: '草', ins_type: InsType::Node(Instruction::GotoLabelE0) }, - Ins{ c: '泥', ins_type: InsType::Node(Instruction::GotoLabelL0) }, - Ins{ c: '马', ins_type: InsType::Node(Instruction::ReturnCallAt) }, + Ins{ c: '草', ins_type: InsType::Node(InsId::GotoLabelE0) }, + Ins{ c: '泥', ins_type: InsType::Node(InsId::GotoLabelL0) }, + Ins{ c: '马', ins_type: InsType::Node(InsId::ReturnCallAt) }, ]})}, Ins{ c: '马', ins_type: InsType::Path(InsColl{ inses: vec![ - Ins{ c: '马', ins_type: InsType::Node(Instruction::End) }, + Ins{ c: '马', ins_type: InsType::Node(InsId::End) }, ]})}, ]})}, ]} @@ -77,12 +146,12 @@ pub fn make_instruction_tree() -> InsColl { #[derive(Debug, Clone)] pub enum Instruction { - Push, + Push(isize), Dup, - CopyN, + CopyN(isize), Swap, Pop, - PopN, + PopN(isize), Add, Sub, Mul, @@ -90,11 +159,11 @@ pub enum Instruction { Mod, Store, Retrieve, - DefineLabel, - CallAtLabel, - GotoLabel, - GotoLabelE0, - GotoLabelL0, + DefineLabel(isize), + CallAtLabel(isize), + GotoLabel(isize), + GotoLabelE0(isize), + GotoLabelL0(isize), ReturnCallAt, End, StdOutChar, diff --git a/src/main.rs b/src/main.rs index 7544fdd..c789a48 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,7 +10,6 @@ const VALID_INSTRUCTION_CHARS: &str = "草泥马河蟹"; fn main() { let input = "草草草泥马 马草草草泥草草草草泥泥马 草马草 泥马草泥 草草草泥草泥草马 泥马草草 草草草泥马 泥草草草 草马草 草草草泥草泥泥马 泥草草泥 马泥草草泥草草草泥草泥马 马草马草泥草草草草泥泥马 马草草草泥草草草泥草泥马 草马马 马马马"; - let mut cs = "草草草泥草泥泥马".chars(); println!("{}", read_number(&mut cs)); println!("{:?}", parse_lang(input)); @@ -48,8 +47,9 @@ fn match_instruction(ins_coll: &InsColl, cs: &mut dyn Iterator) -> Op match &ins.ins_type { InsType::Path(ins_coll) => return match_instruction(&ins_coll, cs), InsType::Node(ins) => { - println!("{:?}", ins); - return Some(ins.clone()); + let data = if ins.has_data() { Some(read_number(cs)) } else { None }; + println!("{:?} {}", ins, if let Some(n) = data { n.to_string() } else { "".to_owned() }); + return Some(ins.new_instruction(data)); }, } } @@ -68,8 +68,8 @@ fn parse_lang(lang: &str) {// -> Result, ParseError> { VALID_INSTRUCTION_CHARS.chars().any(|vic| vic == *c) }); - while let Some(ins) = match_instruction(&instruction_tree_root, &mut cs) { - println!("{:?}", ins); + while let Some(_ins) = match_instruction(&instruction_tree_root, &mut cs) { + // println!("{:?}", ins); } }