Sync
This commit is contained in:
+87
-21
@@ -1,3 +1,5 @@
|
||||
use std::str::Chars;
|
||||
|
||||
struct Type {
|
||||
name: String,
|
||||
params: Vec<Type>,
|
||||
@@ -29,7 +31,6 @@ struct Class {
|
||||
entries: Vec<Decl>,
|
||||
methods: Vec<Function>,
|
||||
}
|
||||
struct Block(Vec<Statement>);
|
||||
struct Function {
|
||||
annotations: Vec<Annotation>,
|
||||
name: String,
|
||||
@@ -50,6 +51,7 @@ enum Annotation {
|
||||
Expr(String),
|
||||
}
|
||||
enum Statement {
|
||||
Class(Class),
|
||||
DeclLet(Decl),
|
||||
DeclVar(Decl),
|
||||
Assignment {
|
||||
@@ -74,30 +76,94 @@ enum Expr {
|
||||
String(String),
|
||||
Number(String),
|
||||
}
|
||||
|
||||
enum TopLevel {
|
||||
Class(Class),
|
||||
Statement(Statement)
|
||||
}
|
||||
struct Program(Vec<TopLevel>);
|
||||
struct Block(Vec<Statement>);
|
||||
struct ParseError(String);
|
||||
struct Reader(String);
|
||||
impl Reader {
|
||||
|
||||
enum Part {
|
||||
Set(&'static str),
|
||||
Raw(&'static str),
|
||||
}
|
||||
trait Parsed {
|
||||
fn enter(reader: &mut Reader) -> ;
|
||||
fn exit(reader: &mut Reader) -> Result<(), ParseError>;
|
||||
enum Selector {
|
||||
Cap(Pattern),
|
||||
One(Part),
|
||||
Any(Part),
|
||||
}
|
||||
impl Parsed for TopLevel {
|
||||
|
||||
struct Pattern(&'static [Selector]);
|
||||
impl Pattern {
|
||||
fn eval<'a>(&self, str: &'a str) -> Result<(&'a str, Vec<&'a str>), ()> {
|
||||
let mut captures = Vec::new();
|
||||
let mut current = str;
|
||||
let mut count = 0;
|
||||
self.0.iter().try_for_each(|selector: &Selector| {
|
||||
match selector {
|
||||
Selector::Cap(pattern) => {
|
||||
pattern.eval(str).and_then(|(sum, _)| {
|
||||
captures.push(sum);
|
||||
Ok(())
|
||||
})
|
||||
},
|
||||
Selector::Any(part) => {
|
||||
let mut delta = 0;
|
||||
match part {
|
||||
Part::Set(set) => {
|
||||
delta = current.chars().take_while(|char| set.contains(*char)).count();
|
||||
current = ¤t[delta..];
|
||||
},
|
||||
Part::Raw(raw) => {
|
||||
while current.starts_with(raw) {
|
||||
delta += raw.len();
|
||||
current = ¤t[delta..];
|
||||
}
|
||||
},
|
||||
}
|
||||
count += delta;
|
||||
Ok(())
|
||||
}
|
||||
Selector::One(part) => {
|
||||
match part {
|
||||
Part::Set(set) => {
|
||||
let res = current.chars().next().is_some_and(|char| set.contains(char));
|
||||
if res {
|
||||
current = ¤t[1..];
|
||||
count += 1;
|
||||
}
|
||||
res
|
||||
},
|
||||
Part::Raw(raw) => {
|
||||
let res = current.starts_with(raw);
|
||||
if res {
|
||||
current = ¤t[raw.len()..];
|
||||
count += raw.len();
|
||||
}
|
||||
res
|
||||
}
|
||||
}.then_some(()).ok_or(())
|
||||
}
|
||||
}
|
||||
}).map(|_| (&str[..count],captures))
|
||||
}
|
||||
}
|
||||
impl Parsed for Statement {
|
||||
|
||||
const IDENTIFIER_START_SET: &str = "abcdefghijklmnopqrstuvwxyz_";
|
||||
const IDENTIFIER_REST_SET: &str = "abcdefghijklmnopqrstuvwxyz_1234567890";
|
||||
const WHITESPACE_SET: &str = "\n\r\t ";
|
||||
const PATTERN_IDENTIFIER: Pattern = Pattern(&[
|
||||
Selector::One(Part::Set(IDENTIFIER_START_SET)),
|
||||
Selector::Any(Part::Set(IDENTIFIER_REST_SET)),
|
||||
]);
|
||||
const PATTERN_WHITESPACE: Pattern = Pattern(&[Selector::Any(Part::Set(WHITESPACE_SET))]);
|
||||
const PATTERN_COMMENT: Pattern = Pattern(&[Selector::Any(Part::Raw())]);
|
||||
const PATTERN_CALL_START: Pattern = Pattern(&[
|
||||
Selector::Cap(PATTERN_IDENTIFIER),
|
||||
Selector::One(Part::Set("("))
|
||||
]);
|
||||
fn parse_call(str: &str) -> Result<Block,ParseError> {
|
||||
PATTERN_CALL_START.eval(str).and_then(|_| {
|
||||
Ok(())
|
||||
});
|
||||
Ok(Block(vec!()))
|
||||
}
|
||||
impl Parsed for Expr {
|
||||
|
||||
fn parse_block(str: &str) -> Result<Block,ParseError> {
|
||||
parse_call(str)
|
||||
}
|
||||
fn parse(source: String) -> Result<Program,ParseError> {
|
||||
Ok(Program(Vec::new()))
|
||||
fn parse(source: &str) -> Result<Block,ParseError> {
|
||||
parse_block(source)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user