add grassmudhorse
This commit is contained in:
3
.gitignore
vendored
3
.gitignore
vendored
@@ -3,9 +3,6 @@
|
|||||||
# will have compiled files and executables
|
# will have compiled files and executables
|
||||||
/target/
|
/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
|
# These are backup files generated by rustfmt
|
||||||
**/*.rs.bk
|
**/*.rs.bk
|
||||||
|
|||||||
123
Cargo.lock
generated
Normal file
123
Cargo.lock
generated
Normal file
@@ -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"
|
||||||
10
Cargo.toml
Normal file
10
Cargo.toml
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
[package]
|
||||||
|
name = "grassmudhorse"
|
||||||
|
version = "0.1.0"
|
||||||
|
authors = ["Hatter Jiang <jht5945@gmail.com>"]
|
||||||
|
edition = "2018"
|
||||||
|
|
||||||
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
err-derive = "0.2.2"
|
||||||
112
src/main.rs
Normal file
112
src/main.rs
Normal file
@@ -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<char>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ParseChars {
|
||||||
|
fn next(&mut self) -> Option<char> {
|
||||||
|
let c = self.try_next();
|
||||||
|
if c.is_some() { self.index += 1; }
|
||||||
|
c
|
||||||
|
}
|
||||||
|
|
||||||
|
fn try_next(&self) -> Option<char> {
|
||||||
|
self.try_next_n(0_usize)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn try_next_n(&self, nn: usize) -> Option<char> {
|
||||||
|
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<Vec<Instruction>, 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)
|
||||||
|
}
|
||||||
|
|
||||||
Reference in New Issue
Block a user