diff --git a/.gitignore b/.gitignore index 65f1105..19712ce 100644 --- a/.gitignore +++ b/.gitignore @@ -3,9 +3,6 @@ # will have compiled files and executables /target/ -# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries -# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html -Cargo.lock # These are backup files generated by rustfmt **/*.rs.bk diff --git a/Cargo.lock b/Cargo.lock new file mode 100644 index 0000000..218a49e --- /dev/null +++ b/Cargo.lock @@ -0,0 +1,123 @@ +# This file is automatically @generated by Cargo. +# It is not intended for manual editing. +[[package]] +name = "err-derive" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "22deed3a8124cff5fa835713fa105621e43bbdc46690c3a6b68328a012d350d4" +dependencies = [ + "proc-macro-error", + "proc-macro2", + "quote", + "rustversion", + "syn", + "synstructure", +] + +[[package]] +name = "grassmudhorse" +version = "0.1.0" +dependencies = [ + "err-derive", +] + +[[package]] +name = "proc-macro-error" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "98e9e4b82e0ef281812565ea4751049f1bdcdfccda7d3f459f2e138a40c08678" +dependencies = [ + "proc-macro-error-attr", + "proc-macro2", + "quote", + "syn", + "version_check", +] + +[[package]] +name = "proc-macro-error-attr" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f5444ead4e9935abd7f27dc51f7e852a0569ac888096d5ec2499470794e2e53" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "syn-mid", + "version_check", +] + +[[package]] +name = "proc-macro2" +version = "1.0.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8872cf6f48eee44265156c111456a700ab3483686b3f96df4cf5481c89157319" +dependencies = [ + "unicode-xid", +] + +[[package]] +name = "quote" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c1f4b0efa5fc5e8ceb705136bfee52cfdb6a4e3509f770b478cd6ed434232a7" +dependencies = [ + "proc-macro2", +] + +[[package]] +name = "rustversion" +version = "1.0.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b3bba175698996010c4f6dce5e7f173b6eb781fce25d2cfc45e27091ce0b79f6" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "syn" +version = "1.0.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "410a7488c0a728c7ceb4ad59b9567eb4053d02e8cc7f5c0e0eeeb39518369213" +dependencies = [ + "proc-macro2", + "quote", + "unicode-xid", +] + +[[package]] +name = "syn-mid" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7be3539f6c128a931cf19dcee741c1af532c7fd387baa739c03dd2e96479338a" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "synstructure" +version = "0.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "67656ea1dc1b41b1451851562ea232ec2e5a80242139f7e679ceccfb5d61f545" +dependencies = [ + "proc-macro2", + "quote", + "syn", + "unicode-xid", +] + +[[package]] +name = "unicode-xid" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "826e7639553986605ec5979c7dd957c7895e93eabed50ab2ffa7f6128a75097c" + +[[package]] +name = "version_check" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "078775d0255232fb988e6fccf26ddc9d1ac274299aaedcedce21c6f72cc533ce" diff --git a/Cargo.toml b/Cargo.toml new file mode 100644 index 0000000..f5dab42 --- /dev/null +++ b/Cargo.toml @@ -0,0 +1,10 @@ +[package] +name = "grassmudhorse" +version = "0.1.0" +authors = ["Hatter Jiang "] +edition = "2018" + +# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html + +[dependencies] +err-derive = "0.2.2" diff --git a/src/main.rs b/src/main.rs new file mode 100644 index 0000000..e3e450d --- /dev/null +++ b/src/main.rs @@ -0,0 +1,112 @@ +use err_derive::Error; + +#[derive(Debug, Error)] +pub enum ParseError { + #[error(display = "error syntax: {:?}", _0)] + ErrorSyntax(String), +} + +#[derive(Debug)] +enum Instruction { + Push, + Dup, + CopyN, + Swap, + Pop, + PopN, + Add, + Sub, + Mul, + Div, + Mod, + Store, + Retrieve, + DefineLabel, + CallAtLabel, + GotoLabel, + GotoLabelE0, + GotoLabelL0, + ReturnCallAt, + End, + StdOutChar, + StdOutNum, + StdInChar, + StdInNum, +} + +struct ParseChars { + index: usize, + chars: Vec, +} + +impl ParseChars { + fn next(&mut self) -> Option { + let c = self.try_next(); + if c.is_some() { self.index += 1; } + c + } + + fn try_next(&self) -> Option { + self.try_next_n(0_usize) + } + + fn try_next_n(&self, nn: usize) -> Option { + let i = self.index + nn; + if i >= self.chars.len() { + None + } else { + let c = self.chars[i]; + Some(c) + } + } +} + +const VALID_INSTRUCTION_CHARS: &str = "草泥马河蟹"; + +fn main() { + let input = "草草草泥马 马草草草泥草草草草泥泥马 草马草 泥马草泥 草草草泥草泥草马 泥马草草 草草草泥马 泥草草草 草马草 草草草泥草泥泥马 泥草草泥 马泥草草泥草草草泥草泥马 马草马草泥草草草草泥泥马 马草草草泥草草草泥草泥马 草马马 马马马"; + + println!("{:?}", parse_lang(input)); +} + +fn parse_lang(lang: &str) -> Result, ParseError> { + let mut r = vec![]; + + let mut cs = ParseChars{ index: 0_usize, chars: lang.chars().filter(|c| { + VALID_INSTRUCTION_CHARS.chars().any(|vic| vic == *c) + }).collect(), }; + while let Some(c) = cs.next() { + let nc = match cs.try_next() { + Some(nc) => nc, None => { + return Err(ParseError::ErrorSyntax( + format!("Syntax error: after {} has no valid char", c) + )); + }, + }; + if c == '草' && nc == '草' { // Push + cs.next(); + // todo parse + continue; + } + let nnc = match cs.try_next_n(1) { + Some(nc) => nc, None => { + return Err(ParseError::ErrorSyntax( + format!("Syntax error: after {}{} has no valid char", c, nc) + )); + }, + }; + if c == '草' && nc == '马' || nnc == '草' { // Dup + + } + let nnnc = match cs.try_next_n(2) { + Some(nc) => nc, None => { + return Err(ParseError::ErrorSyntax( + format!("Syntax error: after {}{}{} has no valid char", c, nc, nnc) + )); + }, + }; + } + + Ok(r) +} +