Sync
This commit is contained in:
+87
-21
@@ -1,3 +1,5 @@
|
|||||||
|
use std::str::Chars;
|
||||||
|
|
||||||
struct Type {
|
struct Type {
|
||||||
name: String,
|
name: String,
|
||||||
params: Vec<Type>,
|
params: Vec<Type>,
|
||||||
@@ -29,7 +31,6 @@ struct Class {
|
|||||||
entries: Vec<Decl>,
|
entries: Vec<Decl>,
|
||||||
methods: Vec<Function>,
|
methods: Vec<Function>,
|
||||||
}
|
}
|
||||||
struct Block(Vec<Statement>);
|
|
||||||
struct Function {
|
struct Function {
|
||||||
annotations: Vec<Annotation>,
|
annotations: Vec<Annotation>,
|
||||||
name: String,
|
name: String,
|
||||||
@@ -50,6 +51,7 @@ enum Annotation {
|
|||||||
Expr(String),
|
Expr(String),
|
||||||
}
|
}
|
||||||
enum Statement {
|
enum Statement {
|
||||||
|
Class(Class),
|
||||||
DeclLet(Decl),
|
DeclLet(Decl),
|
||||||
DeclVar(Decl),
|
DeclVar(Decl),
|
||||||
Assignment {
|
Assignment {
|
||||||
@@ -74,30 +76,94 @@ enum Expr {
|
|||||||
String(String),
|
String(String),
|
||||||
Number(String),
|
Number(String),
|
||||||
}
|
}
|
||||||
|
struct Block(Vec<Statement>);
|
||||||
enum TopLevel {
|
|
||||||
Class(Class),
|
|
||||||
Statement(Statement)
|
|
||||||
}
|
|
||||||
struct Program(Vec<TopLevel>);
|
|
||||||
struct ParseError(String);
|
struct ParseError(String);
|
||||||
struct Reader(String);
|
enum Part {
|
||||||
impl Reader {
|
Set(&'static str),
|
||||||
|
Raw(&'static str),
|
||||||
}
|
}
|
||||||
trait Parsed {
|
enum Selector {
|
||||||
fn enter(reader: &mut Reader) -> ;
|
Cap(Pattern),
|
||||||
fn exit(reader: &mut Reader) -> Result<(), ParseError>;
|
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> {
|
fn parse(source: &str) -> Result<Block,ParseError> {
|
||||||
Ok(Program(Vec::new()))
|
parse_block(source)
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user