add grassmudhorse

This commit is contained in:
2020-05-05 11:32:54 +08:00
parent 128e77c9df
commit f62f966eaf
4 changed files with 245 additions and 3 deletions

3
.gitignore vendored
View File

@@ -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

123
Cargo.lock generated Normal file
View 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
View 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
View 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)
}