diff --git a/src/backend.rs b/src/backend.rs index b65efe7..fb0c47f 100644 --- a/src/backend.rs +++ b/src/backend.rs @@ -81,6 +81,10 @@ impl<'a> Vm { let sum = unwrap!().wrapping_add(unwrap!()); self.stack.push(sum); }, + "-" => { + let sum = unwrap!().wrapping_sub(unwrap!()); + self.stack.push(sum); + }, "*" => { let prod = unwrap!().wrapping_mul(unwrap!()); self.stack.push(prod); diff --git a/src/compile.rs b/src/compile.rs new file mode 100644 index 0000000..42ed3a9 --- /dev/null +++ b/src/compile.rs @@ -0,0 +1,280 @@ +pub fn codegen(parser: &mut Parser) -> String { + let code = String::new(); + code.push_str(include_str!("macros.S")); + + macro_rules! paren_matching { + ($start:expr, $end:expr) => {{ + let start = $start; + let end = $end; + let mut depth = 1; + let mut content = String::new(); + + let item = { + loop { + if let Some(item) = parser.inner_next() { + content.push_str(item); + content.push_str(" "); + if start(item) { + depth += 1; + } + if end(item) { + depth -= 1; + } + if depth == 0 { + break Some(item); + } + } else { + break None; + } + } + }; + + (item, content) + }} + } + + while let Some(item) = parser.next() { + match item { + Number(n) => code.push_str(format!("li64(r1, {});\npush(r1);\n").as_str()), + Word(w) => { + match w { + "." => { + println!("im too lazy to support . wahhhhhhhh"); + }, + "+" => { + code.push_str("pop(r32);\n"); + code.push_str("pop(r33);\n"); + code.push_str("add64(r1, r32, r33);\n"); + code.push_str("push(r1);\n"); + }, + "*" => { + code.push_str("pop(r32);\n"); + code.push_str("pop(r33);\n"); + code.push_str("mul64(r1, r32, r33);\n"); + code.push_str("push(r1);\n"); + }, + "/" => { + code.push_str("pop(r32);\n"); + code.push_str("pop(r33);\n"); + code.push_str("diru64(r1, r0, r33, r32);\n"); + code.push_str("push(r1);\n"); + }, + "=" => { + if unwrap!() == unwrap!() { + self.stack.push(1); + } else { + self.stack.push(0); + } + }, + "<>" => { + if unwrap!() != unwrap!() { + self.stack.push(1); + } else { + self.stack.push(0) + } + }, + "<" => { + if unwrap!() > unwrap!() { + self.stack.push(1); + } else { + self.stack.push(0); + } + }, + ">" => { + if unwrap!() < unwrap!() { + self.stack.push(1); + } else { + self.stack.push(0); + } + } + "MOD"|"mod" => { + let stack_top = unwrap!(); + let stack_second = unwrap!(); + let rem = stack_second.wrapping_rem(stack_top); + self.stack.push(rem); + }, + "*/" => { + let n3 = unwrap!(); + let n2 = unwrap!(); + let n1 = unwrap!(); + + let d = n1 * n2; + let n4 = d/n3; + + self.stack.push(n4); + }, + "TRACE"|"trace" => { + match parser.inner_next() { + Some("stack") => { + for item in &self.stack { + println!("{:?}", item); + } + }, + Some("data") => { + println!("{:?}", self.dictionary.data); + }, + Some("words") => { + println!("{:?}", self.dictionary.words); + }, + + subcommand => { + println!("Subcommand {:?} is not supported. Supported subcommands are stack or dataspace.", subcommand); + } + } + }, + "/MOD"|"/mod" => { + let stack_top = unwrap!(); + let stack_second = unwrap!(); + let rem = stack_second.wrapping_rem(stack_top); + let quo = stack_second.wrapping_div(stack_top); + self.stack.push(rem); + self.stack.push(quo); + }, + "SWAP"|"swap" => { + let stack_top = unwrap!(); + let stack_second = unwrap!(); + self.stack.push(stack_top); + self.stack.push(stack_second); + }, + "DROP"|"drop" => { + let _ = self.stack.pop(); + }, + "HERE"|"here" => { + self.stack.push(self.dictionary.dp); + }, + "@" => { + let addr = unwrap!(); + self.stack.push(*self.dictionary.data.get(&addr).unwrap_or(&0)); + }, + "!" => { + let addr = unwrap!(); + let content = unwrap!(); + self.dictionary.data.insert(addr, content); + }, + "," => { + let content = unwrap!(); + self.dictionary.dp += 1; + self.dictionary.data.insert(self.dictionary.dp, content); + }, + "ALLOT"|"allot" => { + self.dictionary.dp += unwrap!(); + }, + "CREATE"|"create" => { + self.dictionary.dp += 1; + let Some(Word(word_name)) = parser.next() else { println!("ERROR: Word name not given."); std::process::exit(1) }; + self.dictionary.words.insert(word_name.to_string(), self.dictionary.dp.to_string()); + }, + "VARIABLE"|"variable" => { + self.dictionary.dp += 1; + let Some(Word(word_name)) = parser.next() else { println!("ERROR: Word name not given."); std::process::exit(1) }; + self.dictionary.words.insert(word_name.to_string(), self.dictionary.dp.to_string()); + + }, + "DUP"|"dup" => { + let stack_top = unwrap!(); + self.stack.push(stack_top); + self.stack.push(stack_top); + }, + "IF"|"if" => { + let expr = unwrap!(); + let (_, content) = paren_matching!(|x| matches!(x, "IF"|"if"), |x| matches!(x, "THEN"|"then")); + + if expr == 0 { + // Do nothing. + } else { + self.vmrun(&mut Parser::new(content.as_str())); + } + }, + + "THEN"|"then" => {} + "(" => { + let mut next = parser.inner_next(); + while next != Some(")") && next != None { + next = parser.inner_next_back(); + } + }, + "stacklen" => { + self.stack.push(self.stack.len() as u64); + } + "DO"|"do" => { + let start = unwrap!(); + let limit = unwrap!(); + let (_, action) = paren_matching!(|x| matches!(x, "DO"|"do"), |x| matches!(x, "LOOP"|"loop")); + + for i in start..limit { + self.dictionary.words.insert("I".to_string(), i.to_string()); + self.dictionary.words.insert("i".to_string(), i.to_string()); + self.vmrun(&mut Parser::new(action.as_str())); + } + self.dictionary.words.remove("I"); + self.dictionary.words.remove("i"); + }, + "+!" => { + let addr = unwrap!(); + let amnt = unwrap!(); + self.dictionary.data.insert(addr, self.dictionary.data.get(&addr).unwrap_or(&0) + amnt); + }, + "LOOP"|"loop" => {}, + "BEGIN"|"begin" => { + let (next, action) = paren_matching!(|x| matches!(x, "BEGIN"|"begin"), |x| matches!(x, "UNTIL"|"until"|"WHILE"|"while")); + + match next { + Some("UNTIL")|Some("until") => { + self.vmrun(&mut Parser::new(action.as_str())); + + while unwrap!() == 0 { + self.vmrun(&mut Parser::new(action.as_str())); + } + }, + Some("WHILE")|Some("while") => { + let mut condition = String::new(); + let mut next = parser.inner_next(); + while !matches!(next, Some("REPEAT")|Some("repeat")|None) { + condition.push_str(next.unwrap()); + condition.push_str(" "); + next = parser.inner_next_back(); + } + self.vmrun(&mut Parser::new(condition.as_str())); + let mut cond_bool = unwrap!(); + while cond_bool != 0 { + self.vmrun(&mut Parser::new(action.as_str())); + self.vmrun(&mut Parser::new(condition.as_str())); + cond_bool = unwrap!(); + } + }, + _ => { + println!("ERROR: BEGIN without UNTIL or WHILE"); + std::process::exit(1); + } + } + }, + "UNTIL"|"until" => {}, + "WHILE"|"while" => {}, + "REPEAT"|"repeat" => {}, + ":" => { + let Some(Word(word_name)) = parser.next() else { println!("ERROR: Word name not given."); std::process::exit(1); }; + let (_, word_content) = paren_matching!(|x| matches!(x, ":"), |x| matches!(x, ";")); + + self.dictionary.words.insert(word_name.to_string(), word_content); + }, + ";" => {}, + "BYE"|"bye" => { + std::process::exit(0); + }, + "clearstack" => { + self.stack = Vec::new(); + }, + word => { + let words = self.dictionary.words.clone(); + if let Some(word_content) = words.get(word) { + self.vmrun(&mut Parser::new(word_content)); + } else { + println!("WARNING: word {:?} does not exist, will clear stack.", word); + self.stack = Vec::new(); + } + } + } + } + } + } +} diff --git a/src/compile.rs~ b/src/compile.rs~ new file mode 100644 index 0000000..c0da7d3 --- /dev/null +++ b/src/compile.rs~ @@ -0,0 +1,286 @@ + pub fn vmrun(&mut self, parser: &mut Parser) { + macro_rules! unwrap { + () => { + match self.stack.pop() { + Some(v) => { + v + }, + None => { + println!("ERROR: stack empty"); + std::process::exit(1); + } + } + } + } + macro_rules! paren_matching { + ($start:expr, $end:expr) => {{ + let start = $start; + let end = $end; + let mut depth = 1; + let mut content = String::new(); + + let item = { + loop { + if let Some(item) = parser.inner_next() { + content.push_str(item); + content.push_str(" "); + if start(item) { + depth += 1; + } + if end(item) { + depth -= 1; + } + if depth == 0 { + break Some(item); + } + } else { + break None; + } + } + }; + + (item, content) + }} + } + + while let Some(item) = parser.next() { + match item { + Number(n) => self.stack.push(n), + Word(w) => { + match w { + "." => { + println!("{:?} ok", unwrap!()); + }, + "+" => { + let sum = unwrap!().wrapping_add(unwrap!()); + self.stack.push(sum); + }, + "*" => { + let prod = unwrap!().wrapping_mul(unwrap!()); + self.stack.push(prod); + }, + "/" => { + let stack_top = unwrap!(); + let stack_second = unwrap!(); + let quo = stack_second.wrapping_div(stack_top); + self.stack.push(quo); + }, + "=" => { + if unwrap!() == unwrap!() { + self.stack.push(1); + } else { + self.stack.push(0); + } + }, + "<>" => { + if unwrap!() != unwrap!() { + self.stack.push(1); + } else { + self.stack.push(0) + } + }, + "<" => { + if unwrap!() > unwrap!() { + self.stack.push(1); + } else { + self.stack.push(0); + } + }, + ">" => { + if unwrap!() < unwrap!() { + self.stack.push(1); + } else { + self.stack.push(0); + } + } + "MOD"|"mod" => { + let stack_top = unwrap!(); + let stack_second = unwrap!(); + let rem = stack_second.wrapping_rem(stack_top); + self.stack.push(rem); + }, + "*/" => { + let n3 = unwrap!(); + let n2 = unwrap!(); + let n1 = unwrap!(); + + let d = n1 * n2; + let n4 = d/n3; + + self.stack.push(n4); + }, + "TRACE"|"trace" => { + match parser.inner_next() { + Some("stack") => { + for item in &self.stack { + println!("{:?}", item); + } + }, + Some("data") => { + println!("{:?}", self.dictionary.data); + }, + Some("words") => { + println!("{:?}", self.dictionary.words); + }, + + subcommand => { + println!("Subcommand {:?} is not supported. Supported subcommands are stack or dataspace.", subcommand); + } + } + }, + "/MOD"|"/mod" => { + let stack_top = unwrap!(); + let stack_second = unwrap!(); + let rem = stack_second.wrapping_rem(stack_top); + let quo = stack_second.wrapping_div(stack_top); + self.stack.push(rem); + self.stack.push(quo); + }, + "SWAP"|"swap" => { + let stack_top = unwrap!(); + let stack_second = unwrap!(); + self.stack.push(stack_top); + self.stack.push(stack_second); + }, + "DROP"|"drop" => { + let _ = self.stack.pop(); + }, + "HERE"|"here" => { + self.stack.push(self.dictionary.dp); + }, + "@" => { + let addr = unwrap!(); + self.stack.push(*self.dictionary.data.get(&addr).unwrap_or(&0)); + }, + "!" => { + let addr = unwrap!(); + let content = unwrap!(); + self.dictionary.data.insert(addr, content); + }, + "," => { + let content = unwrap!(); + self.dictionary.dp += 1; + self.dictionary.data.insert(self.dictionary.dp, content); + }, + "ALLOT"|"allot" => { + self.dictionary.dp += unwrap!(); + }, + "CREATE"|"create" => { + self.dictionary.dp += 1; + let Some(Word(word_name)) = parser.next() else { println!("ERROR: Word name not given."); std::process::exit(1) }; + self.dictionary.words.insert(word_name.to_string(), self.dictionary.dp.to_string()); + }, + "VARIABLE"|"variable" => { + self.dictionary.dp += 1; + let Some(Word(word_name)) = parser.next() else { println!("ERROR: Word name not given."); std::process::exit(1) }; + self.dictionary.words.insert(word_name.to_string(), self.dictionary.dp.to_string()); + + }, + "DUP"|"dup" => { + let stack_top = unwrap!(); + self.stack.push(stack_top); + self.stack.push(stack_top); + }, + "IF"|"if" => { + let expr = unwrap!(); + let (_, content) = paren_matching!(|x| matches!(x, "IF"|"if"), |x| matches!(x, "THEN"|"then")); + + if expr == 0 { + // Do nothing. + } else { + self.vmrun(&mut Parser::new(content.as_str())); + } + }, + + "THEN"|"then" => {} + "(" => { + let mut next = parser.inner_next(); + while next != Some(")") && next != None { + next = parser.inner_next_back(); + } + }, + "stacklen" => { + self.stack.push(self.stack.len() as u64); + } + "DO"|"do" => { + let start = unwrap!(); + let limit = unwrap!(); + let (_, action) = paren_matching!(|x| matches!(x, "DO"|"do"), |x| matches!(x, "LOOP"|"loop")); + + for i in start..limit { + self.dictionary.words.insert("I".to_string(), i.to_string()); + self.dictionary.words.insert("i".to_string(), i.to_string()); + self.vmrun(&mut Parser::new(action.as_str())); + } + self.dictionary.words.remove("I"); + self.dictionary.words.remove("i"); + }, + "+!" => { + let addr = unwrap!(); + let amnt = unwrap!(); + self.dictionary.data.insert(addr, self.dictionary.data.get(&addr).unwrap_or(&0) + amnt); + }, + "LOOP"|"loop" => {}, + "BEGIN"|"begin" => { + let (next, action) = paren_matching!(|x| matches!(x, "BEGIN"|"begin"), |x| matches!(x, "UNTIL"|"until"|"WHILE"|"while")); + + match next { + Some("UNTIL")|Some("until") => { + self.vmrun(&mut Parser::new(action.as_str())); + + while unwrap!() == 0 { + self.vmrun(&mut Parser::new(action.as_str())); + } + }, + Some("WHILE")|Some("while") => { + let mut condition = String::new(); + let mut next = parser.inner_next(); + while !matches!(next, Some("REPEAT")|Some("repeat")|None) { + condition.push_str(next.unwrap()); + condition.push_str(" "); + next = parser.inner_next_back(); + } + self.vmrun(&mut Parser::new(condition.as_str())); + let mut cond_bool = unwrap!(); + while cond_bool != 0 { + self.vmrun(&mut Parser::new(action.as_str())); + self.vmrun(&mut Parser::new(condition.as_str())); + cond_bool = unwrap!(); + } + }, + _ => { + println!("ERROR: BEGIN without UNTIL or WHILE"); + std::process::exit(1); + } + } + }, + "UNTIL"|"until" => {}, + "WHILE"|"while" => {}, + "REPEAT"|"repeat" => {}, + ":" => { + let Some(Word(word_name)) = parser.next() else { println!("ERROR: Word name not given."); std::process::exit(1); }; + let (_, word_content) = paren_matching!(|x| matches!(x, ":"), |x| matches!(x, ";")); + + self.dictionary.words.insert(word_name.to_string(), word_content); + }, + ";" => {}, + "BYE"|"bye" => { + std::process::exit(0); + }, + "clearstack" => { + self.stack = Vec::new(); + }, + word => { + let words = self.dictionary.words.clone(); + if let Some(word_content) = words.get(word) { + self.vmrun(&mut Parser::new(word_content)); + } else { + println!("WARNING: word {:?} does not exist, will clear stack.", word); + self.stack = Vec::new(); + } + } + } + } + } + } + } diff --git a/src/macros.S b/src/macros.S new file mode 100644 index 0000000..91d4cfe --- /dev/null +++ b/src/macros.S @@ -0,0 +1,9 @@ +fn push(val) { + st(val, r254, 0, 64); + addi8(r254, r254, -64); +} + +fn pop(size, reg) { + addi8(r254, r254, size); + ld(reg, r254, 0, size); +} diff --git a/src/macros.S~ b/src/macros.S~ new file mode 100644 index 0000000..d5782c5 --- /dev/null +++ b/src/macros.S~ @@ -0,0 +1,19 @@ +fn push(val) { + li64(r1, val); + st(r1, r254, 0, 8); + addi8(r254, r254, -8); +} + +fn pop(reg) { + addi8(r254, r254, 8); + ld(reg, r254, 0, 8); +} + +fn number_to_str(n) { + // Iterate over digits and add 48 to every digit. + // To get the digits from a number, you can use merged divide-remainder. + // This is similar to /MOD in forth. + // Assume you have 20 digits. + + +} diff --git a/src/main.rs b/src/main.rs index f384a3b..03ddafc 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,6 +2,7 @@ use std::io::Write; use std::fs::read_to_string; pub mod parse; pub mod backend; +// pub mod compile; use parse::Parser; use backend::Vm; diff --git a/tags b/tags new file mode 100644 index 0000000..a1deaa8 --- /dev/null +++ b/tags @@ -0,0 +1,172 @@ +!_TAG_EXTRA_DESCRIPTION anonymous /Include tags for non-named objects like lambda/ +!_TAG_EXTRA_DESCRIPTION fileScope /Include tags of file scope/ +!_TAG_EXTRA_DESCRIPTION pseudo /Include pseudo tags/ +!_TAG_EXTRA_DESCRIPTION subparser /Include tags generated by subparsers/ +!_TAG_FIELD_DESCRIPTION epoch /the last modified time of the input file (only for F\/file kind tag)/ +!_TAG_FIELD_DESCRIPTION file /File-restricted scoping/ +!_TAG_FIELD_DESCRIPTION input /input file/ +!_TAG_FIELD_DESCRIPTION name /tag name/ +!_TAG_FIELD_DESCRIPTION pattern /pattern/ +!_TAG_FIELD_DESCRIPTION typeref /Type and name of a variable or typedef/ +!_TAG_FIELD_DESCRIPTION!Asm properties /properties (req, vararg for parameters)/ +!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/ +!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/ +!_TAG_KIND_DESCRIPTION!Asm d,define /defines/ +!_TAG_KIND_DESCRIPTION!Asm l,label /labels/ +!_TAG_KIND_DESCRIPTION!Asm m,macro /macros/ +!_TAG_KIND_DESCRIPTION!Asm s,section /sections/ +!_TAG_KIND_DESCRIPTION!Asm t,type /types (structs and records)/ +!_TAG_KIND_DESCRIPTION!D M,module /modules/ +!_TAG_KIND_DESCRIPTION!D T,template /templates/ +!_TAG_KIND_DESCRIPTION!D V,version /version statements/ +!_TAG_KIND_DESCRIPTION!D X,mixin /mixins/ +!_TAG_KIND_DESCRIPTION!D a,alias /aliases/ +!_TAG_KIND_DESCRIPTION!D c,class /classes/ +!_TAG_KIND_DESCRIPTION!D e,enumerator /enumerators (values inside an enumeration)/ +!_TAG_KIND_DESCRIPTION!D f,function /function definitions/ +!_TAG_KIND_DESCRIPTION!D g,enum /enumeration names/ +!_TAG_KIND_DESCRIPTION!D i,interface /interfaces/ +!_TAG_KIND_DESCRIPTION!D m,member /class, struct, and union members/ +!_TAG_KIND_DESCRIPTION!D n,namespace /namespaces/ +!_TAG_KIND_DESCRIPTION!D s,struct /structure names/ +!_TAG_KIND_DESCRIPTION!D u,union /union names/ +!_TAG_KIND_DESCRIPTION!D v,variable /variable definitions/ +!_TAG_KIND_DESCRIPTION!JSON a,array /arrays/ +!_TAG_KIND_DESCRIPTION!JSON b,boolean /booleans/ +!_TAG_KIND_DESCRIPTION!JSON n,number /numbers/ +!_TAG_KIND_DESCRIPTION!JSON o,object /objects/ +!_TAG_KIND_DESCRIPTION!JSON s,string /strings/ +!_TAG_KIND_DESCRIPTION!JSON z,null /nulls/ +!_TAG_KIND_DESCRIPTION!Rust C,constant /A constant/ +!_TAG_KIND_DESCRIPTION!Rust M,macro /Macro Definition/ +!_TAG_KIND_DESCRIPTION!Rust P,method /A method/ +!_TAG_KIND_DESCRIPTION!Rust c,implementation /implementation/ +!_TAG_KIND_DESCRIPTION!Rust e,enumerator /An enum variant/ +!_TAG_KIND_DESCRIPTION!Rust f,function /Function/ +!_TAG_KIND_DESCRIPTION!Rust g,enum /Enum/ +!_TAG_KIND_DESCRIPTION!Rust i,interface /trait interface/ +!_TAG_KIND_DESCRIPTION!Rust m,field /A struct field/ +!_TAG_KIND_DESCRIPTION!Rust n,module /module/ +!_TAG_KIND_DESCRIPTION!Rust s,struct /structural type/ +!_TAG_KIND_DESCRIPTION!Rust t,typedef /Type Alias/ +!_TAG_KIND_DESCRIPTION!Rust v,variable /Global variable/ +!_TAG_OUTPUT_EXCMD mixed /number, pattern, mixed, or combineV2/ +!_TAG_OUTPUT_FILESEP slash /slash or backslash/ +!_TAG_OUTPUT_MODE u-ctags /u-ctags or e-ctags/ +!_TAG_OUTPUT_VERSION 0.0 /current.age/ +!_TAG_PARSER_VERSION!Asm 0.0 /current.age/ +!_TAG_PARSER_VERSION!D 0.0 /current.age/ +!_TAG_PARSER_VERSION!JSON 0.0 /current.age/ +!_TAG_PARSER_VERSION!Rust 0.0 /current.age/ +!_TAG_PATTERN_LENGTH_LIMIT 96 /0 for no limit/ +!_TAG_PROC_CWD /home/goren/Code/fourth/ // +!_TAG_PROGRAM_AUTHOR Universal Ctags Team // +!_TAG_PROGRAM_NAME Universal Ctags /Derived from Exuberant Ctags/ +!_TAG_PROGRAM_URL https://ctags.io/ /official site/ +!_TAG_PROGRAM_VERSION 6.0.0 /p6.0.20221218.0/ +!_TAG_ROLE_DESCRIPTION!Asm!section placement /placement where the assembled code goes/ +0 target/debug/.fingerprint/fourth-0eb22537b83d0b36/test-bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":183265222628/;" o array:local +0 target/debug/.fingerprint/fourth-c58712c3665fe72a/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":110397424744/;" o array:local +0 target/debug/.fingerprint/fourth-d5bfd771d6ea8237/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":131263742483/;" o array:local +0 target/release/.fingerprint/fourth-96ade2603d15be13/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":356732962844/;" o array:local +15729799797837862367 target/.rustc_info.json /^{"rustc_fingerprint":15313746258697816560,"outputs":{"4614504638168534921":{"success":true,"stat/;" o object:outputs +4614504638168534921 target/.rustc_info.json /^{"rustc_fingerprint":15313746258697816560,"outputs":{"4614504638168534921":{"success":true,"stat/;" o object:outputs +CheckDepInfo target/debug/.fingerprint/fourth-0eb22537b83d0b36/test-bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":183265222628/;" o object:local.0 +CheckDepInfo target/debug/.fingerprint/fourth-c58712c3665fe72a/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":110397424744/;" o object:local.0 +CheckDepInfo target/debug/.fingerprint/fourth-d5bfd771d6ea8237/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":131263742483/;" o object:local.0 +CheckDepInfo target/release/.fingerprint/fourth-96ade2603d15be13/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":356732962844/;" o object:local.0 +Dictionary src/backend.rs /^struct Dictionary {$/;" s +Item src/parse.rs /^ type Item = TokenType<'a>;$/;" t implementation:Parser +Number src/parse.rs /^ Number(u64),$/;" e enum:TokenType +Parser src/parse.rs /^impl<'a> Iterator for Parser<'a> {$/;" c +Parser src/parse.rs /^impl<'a> Parser<'a> {$/;" c +Parser src/parse.rs /^pub struct Parser<'a> {$/;" s +TokenType src/parse.rs /^pub enum TokenType<'a> {$/;" g +Vm src/backend.rs /^impl<'a> Vm {$/;" c +Vm src/backend.rs /^pub struct Vm {$/;" s +Word src/parse.rs /^ Word(&'a str),$/;" e enum:TokenType +backend src/main.rs /^pub mod backend;$/;" n +code target/.rustc_info.json /^{"rustc_fingerprint":15313746258697816560,"outputs":{"4614504638168534921":{"success":true,"stat/;" n object:outputs.15729799797837862367 +code target/.rustc_info.json /^{"rustc_fingerprint":15313746258697816560,"outputs":{"4614504638168534921":{"success":true,"stat/;" n object:outputs.4614504638168534921 +codegen src/compile.rs /^pub fn codegen(parser: &mut Parser) -> String {$/;" f +compile src/main.rs /^pub mod compile;$/;" n +compile_kind target/debug/.fingerprint/fourth-0eb22537b83d0b36/test-bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":183265222628/;" n +compile_kind target/debug/.fingerprint/fourth-c58712c3665fe72a/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":110397424744/;" n +compile_kind target/debug/.fingerprint/fourth-d5bfd771d6ea8237/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":131263742483/;" n +compile_kind target/release/.fingerprint/fourth-96ade2603d15be13/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":356732962844/;" n +config target/debug/.fingerprint/fourth-0eb22537b83d0b36/test-bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":183265222628/;" n +config target/debug/.fingerprint/fourth-c58712c3665fe72a/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":110397424744/;" n +config target/debug/.fingerprint/fourth-d5bfd771d6ea8237/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":131263742483/;" n +config target/release/.fingerprint/fourth-96ade2603d15be13/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":356732962844/;" n +data src/backend.rs /^ data: HashMap,$/;" m struct:Dictionary +dep_info target/debug/.fingerprint/fourth-0eb22537b83d0b36/test-bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":183265222628/;" s object:local.0.CheckDepInfo +dep_info target/debug/.fingerprint/fourth-c58712c3665fe72a/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":110397424744/;" s object:local.0.CheckDepInfo +dep_info target/debug/.fingerprint/fourth-d5bfd771d6ea8237/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":131263742483/;" s object:local.0.CheckDepInfo +dep_info target/release/.fingerprint/fourth-96ade2603d15be13/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":356732962844/;" s object:local.0.CheckDepInfo +deps target/debug/.fingerprint/fourth-0eb22537b83d0b36/test-bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":183265222628/;" a +deps target/debug/.fingerprint/fourth-c58712c3665fe72a/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":110397424744/;" a +deps target/debug/.fingerprint/fourth-d5bfd771d6ea8237/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":131263742483/;" a +deps target/release/.fingerprint/fourth-96ade2603d15be13/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":356732962844/;" a +dictionary src/backend.rs /^ dictionary: Dictionary$/;" m struct:Vm +dp src/backend.rs /^ dp: u64,$/;" m struct:Dictionary +features target/debug/.fingerprint/fourth-0eb22537b83d0b36/test-bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":183265222628/;" s +features target/debug/.fingerprint/fourth-c58712c3665fe72a/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":110397424744/;" s +features target/debug/.fingerprint/fourth-d5bfd771d6ea8237/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":131263742483/;" s +features target/release/.fingerprint/fourth-96ade2603d15be13/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":356732962844/;" s +fn src/macros.S /^fn number_to_str(n) {$/;" l +fn src/macros.S /^fn pop(reg) {$/;" l +fn src/macros.S /^fn push(val) {$/;" l +inner_next src/parse.rs /^ pub fn inner_next(&mut self) -> Option<&'a str> {$/;" P implementation:Parser +inner_next_back src/parse.rs /^ pub fn inner_next_back(&mut self) -> Option<&'a str> {$/;" P implementation:Parser +local target/debug/.fingerprint/fourth-0eb22537b83d0b36/test-bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":183265222628/;" a +local target/debug/.fingerprint/fourth-c58712c3665fe72a/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":110397424744/;" a +local target/debug/.fingerprint/fourth-d5bfd771d6ea8237/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":131263742483/;" a +local target/release/.fingerprint/fourth-96ade2603d15be13/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":356732962844/;" a +main src/main.rs /^fn main() -> std::io::Result<()> {$/;" f +metadata target/debug/.fingerprint/fourth-0eb22537b83d0b36/test-bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":183265222628/;" n +metadata target/debug/.fingerprint/fourth-c58712c3665fe72a/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":110397424744/;" n +metadata target/debug/.fingerprint/fourth-d5bfd771d6ea8237/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":131263742483/;" n +metadata target/release/.fingerprint/fourth-96ade2603d15be13/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":356732962844/;" n +new src/backend.rs /^ pub fn new() -> Self {$/;" P implementation:Vm +new src/parse.rs /^ pub fn new(source: &'a str) -> Parser {$/;" P implementation:Parser +next src/parse.rs /^ fn next(&mut self) -> Option> {$/;" P implementation:Parser +outputs target/.rustc_info.json /^{"rustc_fingerprint":15313746258697816560,"outputs":{"4614504638168534921":{"success":true,"stat/;" o +paren_matching src/backend.rs /^ macro_rules! paren_matching {$/;" M method:Vm::vmrun +paren_matching src/compile.rs /^ macro_rules! paren_matching {$/;" M function:codegen +parse src/main.rs /^pub mod parse;$/;" n +path target/debug/.fingerprint/fourth-0eb22537b83d0b36/test-bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":183265222628/;" n +path target/debug/.fingerprint/fourth-c58712c3665fe72a/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":110397424744/;" n +path target/debug/.fingerprint/fourth-d5bfd771d6ea8237/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":131263742483/;" n +path target/release/.fingerprint/fourth-96ade2603d15be13/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":356732962844/;" n +profile target/debug/.fingerprint/fourth-0eb22537b83d0b36/test-bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":183265222628/;" n +profile target/debug/.fingerprint/fourth-c58712c3665fe72a/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":110397424744/;" n +profile target/debug/.fingerprint/fourth-d5bfd771d6ea8237/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":131263742483/;" n +profile target/release/.fingerprint/fourth-96ade2603d15be13/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":356732962844/;" n +repl src/main.rs /^fn repl() {$/;" f +rustc target/debug/.fingerprint/fourth-0eb22537b83d0b36/test-bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":183265222628/;" n +rustc target/debug/.fingerprint/fourth-c58712c3665fe72a/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":110397424744/;" n +rustc target/debug/.fingerprint/fourth-d5bfd771d6ea8237/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":131263742483/;" n +rustc target/release/.fingerprint/fourth-96ade2603d15be13/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":356732962844/;" n +rustc_fingerprint target/.rustc_info.json /^{"rustc_fingerprint":15313746258697816560,"outputs":{"4614504638168534921":{"success":true,"stat/;" n +rustflags target/debug/.fingerprint/fourth-0eb22537b83d0b36/test-bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":183265222628/;" a +rustflags target/debug/.fingerprint/fourth-c58712c3665fe72a/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":110397424744/;" a +rustflags target/debug/.fingerprint/fourth-d5bfd771d6ea8237/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":131263742483/;" a +rustflags target/release/.fingerprint/fourth-96ade2603d15be13/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":356732962844/;" a +split_whitespace src/parse.rs /^ pub(crate) split_whitespace: SplitWhitespace<'a>$/;" m struct:Parser +stack src/backend.rs /^ stack: Vec,$/;" m struct:Vm +status target/.rustc_info.json /^{"rustc_fingerprint":15313746258697816560,"outputs":{"4614504638168534921":{"success":true,"stat/;" s object:outputs.15729799797837862367 +status target/.rustc_info.json /^{"rustc_fingerprint":15313746258697816560,"outputs":{"4614504638168534921":{"success":true,"stat/;" s object:outputs.4614504638168534921 +stderr target/.rustc_info.json /^{"rustc_fingerprint":15313746258697816560,"outputs":{"4614504638168534921":{"success":true,"stat/;" s object:outputs.15729799797837862367 +stderr target/.rustc_info.json /^{"rustc_fingerprint":15313746258697816560,"outputs":{"4614504638168534921":{"success":true,"stat/;" s object:outputs.4614504638168534921 +stdout target/.rustc_info.json /^{"rustc_fingerprint":15313746258697816560,"outputs":{"4614504638168534921":{"success":true,"stat/;" s object:outputs.15729799797837862367 +stdout target/.rustc_info.json /^{"rustc_fingerprint":15313746258697816560,"outputs":{"4614504638168534921":{"success":true,"stat/;" s object:outputs.4614504638168534921 +success target/.rustc_info.json /^{"rustc_fingerprint":15313746258697816560,"outputs":{"4614504638168534921":{"success":true,"stat/;" b object:outputs.15729799797837862367 +success target/.rustc_info.json /^{"rustc_fingerprint":15313746258697816560,"outputs":{"4614504638168534921":{"success":true,"stat/;" b object:outputs.4614504638168534921 +successes target/.rustc_info.json /^{"rustc_fingerprint":15313746258697816560,"outputs":{"4614504638168534921":{"success":true,"stat/;" o +target target/debug/.fingerprint/fourth-0eb22537b83d0b36/test-bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":183265222628/;" n +target target/debug/.fingerprint/fourth-c58712c3665fe72a/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":110397424744/;" n +target target/debug/.fingerprint/fourth-d5bfd771d6ea8237/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":131263742483/;" n +target target/release/.fingerprint/fourth-96ade2603d15be13/bin-fourth.json /^{"rustc":3462548589188548201,"features":"[]","target":6449572106981162502,"profile":356732962844/;" n +unwrap src/backend.rs /^ macro_rules! unwrap {$/;" M method:Vm::vmrun +vmrun src/backend.rs /^ pub fn vmrun(&mut self, parser: &mut Parser) {$/;" P implementation:Vm +words src/backend.rs /^ words: HashMap$/;" m struct:Dictionary