diff --git a/src/lang.rs b/src/lang.rs index 375aa7e..c77397d 100644 --- a/src/lang.rs +++ b/src/lang.rs @@ -1,3 +1,5 @@ +use std::str::Chars; + struct Type { name: String, params: Vec, @@ -29,7 +31,6 @@ struct Class { entries: Vec, methods: Vec, } -struct Block(Vec); struct Function { annotations: Vec, 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); +struct Block(Vec); 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 { + PATTERN_CALL_START.eval(str).and_then(|_| { + Ok(()) + }); + Ok(Block(vec!())) } -impl Parsed for Expr { - +fn parse_block(str: &str) -> Result { + parse_call(str) } -fn parse(source: String) -> Result { - Ok(Program(Vec::new())) +fn parse(source: &str) -> Result { + parse_block(source) }