add grassmudhorse
This commit is contained in:
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