This commit is contained in:
2026-05-21 13:26:23 +01:00
parent 0202722060
commit c3e82e45f0
+87 -21
View File
@@ -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 = &current[delta..];
},
Part::Raw(raw) => {
while current.starts_with(raw) {
delta += raw.len();
current = &current[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 = &current[1..];
count += 1;
}
res
},
Part::Raw(raw) => {
let res = current.starts_with(raw);
if res {
current = &current[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)
}