diff options
Diffstat (limited to 'src/frontend/parse.rs')
-rw-r--r-- | src/frontend/parse.rs | 218 |
1 files changed, 134 insertions, 84 deletions
diff --git a/src/frontend/parse.rs b/src/frontend/parse.rs index 8616346..352599b 100644 --- a/src/frontend/parse.rs +++ b/src/frontend/parse.rs @@ -9,17 +9,17 @@ use Token::*; use Literal::*; use Punctuation::*; -struct Input(multipeek::MultiPeek<std::vec::IntoIter<Token>>); +struct Input(multipeek::MultiPeek<std::vec::IntoIter<(usize, Token)>>); impl Input { /// Map input.next() to return Results for use with the propagation operator fn next(&mut self) -> Result<Token> { - self.0.next().ok_or("end of input".into()) + self.0.next().map(|x| x.1).ok_or("end of input".into()) // FIXME } /// Check if the next character is an expected token, and if so, advance the iterator and return true - fn peek(&mut self, expected: Token) -> bool { - if self.0.peek() == Some(&expected) { + fn peek_eat(&mut self, expected: Token) -> bool { + if self.peek().is_some_and(|x| x == expected) { self.0.next(); true } else { @@ -28,13 +28,13 @@ impl Input { } /// Expose input.peek() (we don't want EOF to trigger an error when peeking) - fn peek_opt(&mut self) -> Option<&Token> { - self.0.peek() + fn peek(&mut self) -> Option<Token> { + self.0.peek().map(|x| x.1.clone()) } /// Expose input.peek_nth() - fn peek_nth(&mut self, n: usize) -> Option<&Token> { - self.0.peek_nth(n) + fn peek_nth(&mut self, n: usize) -> Option<Token> { + self.0.peek_nth(n).map(|x| x.1.clone()) } /// Asserts the next character to be a known token @@ -51,9 +51,13 @@ impl Input { } } +fn normalize(input: TokenStream) -> TokenStream { + todo!() +} + /// Convert a basic TokenStream into an AbstractSyntaxTree -pub fn astify(input: TokenStream, name: &str) -> Result<Expr> { - let mut input = Input(multipeek(input)); +pub fn parse(input: TokenStream, name: &str) -> Result<Expr> { + let mut input = Input(multipeek(normalize(input))); let body = parse_body(&mut input)?; if input.len() > 0 { return Err(format!("additional tokens remaining after the body!").into()); @@ -62,18 +66,18 @@ pub fn astify(input: TokenStream, name: &str) -> Result<Expr> { } /// Parse a series of Exprs, for ex. the body of a function. -/// Body ::= Expr | ('{' Expr (';' Expr)* '}') -fn parse_body(input: &mut Input) -> Result<Vec<Expr>> { +/// Body ::= Expr (';' Expr)* +fn parse_body(input: &mut Input) -> Result<Ast> { let mut res = Vec::new(); - if !input.peek(Sep(ScopeLeftBrace)) { + if !input.peek_eat(Sep(Colon)) && !input.peek_eat(Sep(Equals)) { res.push(parse_expr(input)?); return Ok(res); } - while !input.peek(Sep(ScopeRightBrace)) { + while !input.peek_eat(End) { res.push(parse_expr(input)?); // consume semicolons. there doesn't *have* to be a semicolon though. // this should probably be checked to be a semicolon or a right brace. - input.peek(Sep(Semicolon)); + input.peek_eat(Sep(Semicolon)); } Ok(res) } @@ -136,7 +140,7 @@ fn parse_var(input: &mut Input) -> Result<Expr> { let id = parse_pattern(input)?; let kind = parse_annotation(input)?; let mut value = None; - if input.peek(Sep(Equals)) { + if input.peek_eat(Sep(Equals)) { value = Some(Box::new(parse_expr(input)?)); } Ok(Expr::Binding(Var { id, kind, value })) @@ -153,7 +157,7 @@ fn parse_const(input: &mut Input, public: bool) -> Result<Expr> { /// Annotation ::= (':' Type)? fn parse_annotation(input: &mut Input) -> Result<Option<Type>> { - if input.peek(Sep(Colon)) { + if input.peek_eat(Sep(Colon)) { Ok(Some(parse_type(input)?)) } else { Ok(None) @@ -162,15 +166,14 @@ fn parse_annotation(input: &mut Input) -> Result<Option<Type>> { /// `Func ::= 'pub'? 'func' Ident ('[' Parameters ']')? ('(' Parameters ')')? Annotation '=' Body` fn parse_func(input: &mut Input, public: bool) -> Result<Expr> { - let effect = None; let id = parse_ident(input)?; let mut generics = Vec::new(); - if input.peek(Sep(GenericLeftBracket)) { + if input.peek_eat(Sep(GenericLeftBracket)) { generics = parse_parameters(input)?; input.then(Sep(GenericRightBracket))?; } let mut parameters = Vec::new(); - if input.peek(Sep(FuncLeftParen)) { // todo: rewrite to map over an input + if input.peek_eat(Sep(FuncLeftParen)) { // todo: rewrite to map over an input // let temp_parameters = parse_parameters(input)?; // if temp_parameters.last().is_none() { // return Err("expected a type annotation on the last function parameter".into()); @@ -183,7 +186,7 @@ fn parse_func(input: &mut Input, public: bool) -> Result<Expr> { } else { stack.push(id); } - while input.peek(Sep(Comma)) { + while input.peek_eat(Sep(Comma)) { let (id, kind) = parse_parameter(input)?; stack.push(id); if kind.is_some() { @@ -199,29 +202,29 @@ fn parse_func(input: &mut Input, public: bool) -> Result<Expr> { input.then(Sep(FuncRightParen))?; } let mut kind = Type::Void; - if input.peek(Sep(Colon)) { + if input.peek_eat(Sep(Colon)) { kind = parse_type(input)?; } input.then(Sep(Equals))?; let body = parse_body(input)?; - Ok(Expr::Binding(Func { public, effect, id, generics, parameters, kind, body })) + Ok(Expr::Binding(Func { public, id, generics, parameters, kind, body })) } /// `Macro ::= 'pub'? 'macro' Ident ('[' Parameters ']')? ('(' Parameters ')')? (':' Type) '=' Body` fn parse_macro(input: &mut Input, public: bool) -> Result<Expr> { let id = parse_ident(input)?; let mut generics = Vec::new(); - if input.peek(Sep(GenericLeftBracket)) { + if input.peek_eat(Sep(GenericLeftBracket)) { generics = parse_parameters(input)?; input.then(Sep(GenericRightBracket))?; } let mut parameters = Vec::new(); - if input.peek(Sep(FuncLeftParen)) { + if input.peek_eat(Sep(FuncLeftParen)) { parameters = parse_parameters(input)?; input.then(Sep(FuncRightParen))?; } let mut kind = None; - if input.peek(Sep(Colon)) { + if input.peek_eat(Sep(Colon)) { kind = Some(parse_type(input)?); } input.then(Sep(Equals))?; @@ -233,7 +236,7 @@ fn parse_macro(input: &mut Input, public: bool) -> Result<Expr> { fn parse_typedecl(input: &mut Input, public: bool) -> Result<Expr> { let id = parse_ident(input)?; let mut generics = Vec::new(); - if input.peek(Sep(GenericLeftBracket)) { + if input.peek_eat(Sep(GenericLeftBracket)) { generics = parse_parameters(input)?; input.then(Sep(GenericRightBracket))?; } @@ -246,7 +249,7 @@ fn parse_typedecl(input: &mut Input, public: bool) -> Result<Expr> { fn parse_parameter(input: &mut Input) -> Result<(Id, Option<Type>)> { let id = parse_ident(input)?; let mut kind = None; - if input.peek(Sep(Colon)) { + if input.peek_eat(Sep(Colon)) { kind = Some(parse_type(input)?); } Ok((id, kind)) @@ -256,7 +259,7 @@ fn parse_parameter(input: &mut Input) -> Result<(Id, Option<Type>)> { fn parse_parameters(input: &mut Input) -> Result<Vec<(Id, Option<Type>)>> { let mut res = Vec::new(); res.push(parse_parameter(input)?); - while input.peek(Sep(Comma)) { + while input.peek_eat(Sep(Comma)) { res.push(parse_parameter(input)?); } Ok(res) @@ -281,7 +284,7 @@ fn parse_block(input: &mut Input) -> Result<Expr> { let body = parse_body(input)?; Ok(Expr::Control(Block { id, body })) }, - Word(label) => { + Ident(label) => { input.then(Sep(Colon))?; let id = Some(label); let body = parse_body(input)?; @@ -327,12 +330,12 @@ fn parse_loop(input: &mut Input) -> Result<Expr> { fn parse_if(input: &mut Input) -> Result<Expr> { let mut branches = Vec::new(); branches.push(parse_cond_branch(input)?); - while input.peek(Key(Keyword::Elif)) { + while input.peek_eat(Key(Keyword::Elif)) { branches.push(parse_cond_branch(input)?); } - let mut else_body = None; - if input.peek(Key(Keyword::Else)) { - else_body = Some(parse_body(input)?); + let mut else_body = Vec::new(); + if input.peek_eat(Key(Keyword::Else)) { + else_body = parse_body(input)?; } Ok(Expr::Control(If { branches, else_body })) } @@ -341,13 +344,13 @@ fn parse_if(input: &mut Input) -> Result<Expr> { fn parse_when(input: &mut Input) -> Result<Expr> { let mut branches = Vec::new(); branches.push(parse_cond_branch(input)?); - while input.peek(Key(Keyword::Elif)) { + while input.peek_eat(Key(Keyword::Elif)) { branches.push(parse_cond_branch(input)?); } - let mut else_body = None; - if input.peek(Key(Keyword::Else)) { + let mut else_body = Vec::new(); + if input.peek_eat(Key(Keyword::Else)) { input.then(Sep(Colon))?; - else_body = Some(parse_body(input)?); + else_body = parse_body(input)?; } let mut body = Vec::new(); body.push(Expr::Control(If { branches, else_body })); @@ -367,20 +370,20 @@ fn parse_try(input: &mut Input) -> Result<Expr> { input.then(Sep(Colon))?; let body = parse_body(input)?; let mut catches = Vec::new(); - while input.peek(Key(Keyword::Catch)) { + while input.peek_eat(Key(Keyword::Catch)) { let mut exceptions = Vec::new(); exceptions.push(parse_catch_exception(input)?); - while input.peek(Sep(Comma)) { + while input.peek_eat(Sep(Comma)) { exceptions.push(parse_catch_exception(input)?); } input.then(Sep(Colon))?; let body = parse_body(input)?; catches.push(CatchBranch { exceptions, body }); } - let mut finally = None; - if input.peek(Key(Keyword::Finally)) { + let mut finally = Vec::new(); + if input.peek_eat(Key(Keyword::Finally)) { input.then(Sep(Colon))?; - finally = Some(parse_body(input)?); + finally = parse_body(input)?; } Ok(Expr::Control(Try { body, catches, finally })) } @@ -389,7 +392,7 @@ fn parse_try(input: &mut Input) -> Result<Expr> { fn parse_catch_exception(input: &mut Input) -> Result<(Id, Option<Id>)> { let id = parse_ident(input)?; let mut alias = None; - if input.peek(Key(Keyword::As)) { + if input.peek_eat(Key(Keyword::As)) { alias = Some(parse_ident(input)?); } Ok((id, alias)) @@ -399,14 +402,14 @@ fn parse_catch_exception(input: &mut Input) -> Result<(Id, Option<Id>)> { fn parse_match(input: &mut Input) -> Result<Expr> { let item = parse_pattern(input)?; // fixme let mut branches = Vec::new(); - while input.peek(Key(Keyword::Of)) { + while input.peek_eat(Key(Keyword::Of)) { let mut patterns = Vec::new(); patterns.push(parse_pattern(input)?); - while input.peek(Sep(Comma)) { + while input.peek_eat(Sep(Comma)) { patterns.push(parse_pattern(input)?); } let mut guard = None; - if input.peek(Key(Keyword::Where)) { + if input.peek_eat(Key(Keyword::Where)) { guard = Some(parse_expr(input)?) } input.then(Sep(Colon))?; @@ -437,11 +440,11 @@ fn parse_type(input: &mut Input) -> Result<Type> { Keyword::Interface => parse_interface(input), _ => return Err("invalid keyword present in type!".into()) }, - Word(id) => { + Ident(id) => { let mut generics = Vec::new(); - if input.peek(Sep(GenericLeftBracket)) { + if input.peek_eat(Sep(GenericLeftBracket)) { generics.push(parse_type(input)?); - while input.peek(Sep(Comma)) { + while input.peek_eat(Sep(Comma)) { generics.push(parse_type(input)?); } input.then(Sep(GenericRightBracket))?; @@ -455,9 +458,9 @@ fn parse_type(input: &mut Input) -> Result<Type> { /// `StructType ::= 'struct' ('[' Ident ':' Type (',' Ident ':' Type)* ']')?` fn parse_struct_type(input: &mut Input) -> Result<Type> { let mut res = Vec::new(); - if input.peek(Sep(GenericLeftBracket)) { + if input.peek_eat(Sep(GenericLeftBracket)) { res.push(parse_struct_field(input)?); - while input.peek(Sep(Comma)) { + while input.peek_eat(Sep(Comma)) { res.push(parse_struct_field(input)?); } input.then(Sep(GenericRightBracket))?; @@ -465,19 +468,19 @@ fn parse_struct_type(input: &mut Input) -> Result<Type> { Ok(Type::Struct(res)) } -fn parse_struct_field(input: &mut Input) -> Result<(Id, Box<Type>)> { +fn parse_struct_field(input: &mut Input) -> Result<(Id, Type)> { let id = parse_ident(input)?; input.then(Sep(Colon))?; - let kind = Box::new(parse_type(input)?); + let kind = parse_type(input)?; Ok((id, kind)) } /// `TupleType ::= 'tuple' ('[' (Ident ':')? Type (',' (Ident ':')? Type)* ']')?` fn parse_tuple_type(input: &mut Input) -> Result<Type> { let mut res = Vec::new(); - if input.peek(Sep(GenericLeftBracket)) { + if input.peek_eat(Sep(GenericLeftBracket)) { res.push(parse_tuple_field(input)?); - while input.peek(Sep(Comma)) { + while input.peek_eat(Sep(Comma)) { res.push(parse_tuple_field(input)?); } input.then(Sep(GenericRightBracket))?; @@ -486,23 +489,23 @@ fn parse_tuple_type(input: &mut Input) -> Result<Type> { } // annoyingly complex to parse. `TupleField ::= (Ident ':')? Type` -fn parse_tuple_field(input: &mut Input) -> Result<(Option<Id>, Box<Type>)> { - match input.peek_opt().clone() { - Some(Word(id)) if input.peek_nth(1) == Some(&Sep(Colon)) => { +fn parse_tuple_field(input: &mut Input) -> Result<(Option<Id>, Type)> { + match input.peek().clone() { + Some(Ident(id)) if input.peek_nth(1) == Some(Sep(Colon)) => { input.next()?; input.then(Sep(Colon))?; - Ok((Some(id.to_string()), Box::new(parse_type(input)?))) + Ok((Some(id.to_string()), parse_type(input)?)) }, - _ => Ok((None, Box::new(parse_type(input)?))) + _ => Ok((None, parse_type(input)?)) } } /// `EnumType ::= 'enum' ('[' Ident ('=' Pattern)? (Ident ('=' Pattern)?)* ']')?` fn parse_enum_type(input: &mut Input) -> Result<Type> { let mut res = Vec::new(); - if input.peek(Sep(GenericLeftBracket)) { + if input.peek_eat(Sep(GenericLeftBracket)) { res.push(parse_enum_variant(input)?); - while input.peek(Sep(Comma)) { + while input.peek_eat(Sep(Comma)) { res.push(parse_enum_variant(input)?); } input.then(Sep(GenericRightBracket))?; @@ -513,7 +516,7 @@ fn parse_enum_type(input: &mut Input) -> Result<Type> { fn parse_enum_variant(input: &mut Input) -> Result<(Id, Option<Pattern>)> { let id = parse_ident(input)?; let mut kind = None; - if input.peek(Sep(Equals)) { + if input.peek_eat(Sep(Equals)) { kind = Some(parse_pattern(input)?); } Ok((id, kind)) @@ -522,9 +525,9 @@ fn parse_enum_variant(input: &mut Input) -> Result<(Id, Option<Pattern>)> { /// `UnionType ::= 'union' ('[' Ident (':' Type)? (',' Ident (':' Type)?)* ']')?` fn parse_union_type(input: &mut Input) -> Result<Type> { let mut res = Vec::new(); - if input.peek(Sep(GenericLeftBracket)) { + if input.peek_eat(Sep(GenericLeftBracket)) { res.push(parse_union_variant(input)?); - while input.peek(Sep(Comma)) { + while input.peek_eat(Sep(Comma)) { res.push(parse_union_variant(input)?); } input.then(Sep(GenericRightBracket))?; @@ -532,11 +535,11 @@ fn parse_union_type(input: &mut Input) -> Result<Type> { Ok(Type::Union(res)) } -fn parse_union_variant(input: &mut Input) -> Result<(Id, Box<Type>)> { +fn parse_union_variant(input: &mut Input) -> Result<(Id, Type)> { let id = parse_ident(input)?; - let mut kind = Box::new(Type::Alias { id: "unit".to_string(), generics: Vec::new() }); - if input.peek(Sep(Colon)) { - kind = Box::new(parse_type(input)?); + let mut kind = Type::Alias { id: "unit".to_string(), generics: Vec::new() }; + if input.peek_eat(Sep(Colon)) { + kind = parse_type(input)?; } Ok((id, kind)) } @@ -544,9 +547,9 @@ fn parse_union_variant(input: &mut Input) -> Result<(Id, Box<Type>)> { /// `Interface ::= 'interface' ('[' Signature (',' Signature)* ']')?` fn parse_interface(input: &mut Input) -> Result<Type> { let mut res = Vec::new(); - if input.peek(Sep(GenericLeftBracket)) { + if input.peek_eat(Sep(GenericLeftBracket)) { res.push(parse_signature(input)?); - while input.peek(Sep(Comma)) { + while input.peek_eat(Sep(Comma)) { res.push(parse_signature(input)?); } input.then(Sep(GenericRightBracket))?; @@ -556,31 +559,30 @@ fn parse_interface(input: &mut Input) -> Result<Type> { /// `Signature ::= Ident ('[' Parameters ']')? ('(' Type (',' Type)* ')')? (':' Type)?` fn parse_signature(input: &mut Input) -> Result<Sig> { - let effect = None; let id = parse_ident(input)?; let mut generics = Vec::new(); - if input.peek(Sep(GenericLeftBracket)) { + if input.peek_eat(Sep(GenericLeftBracket)) { generics = parse_parameters(input)?; input.then(Sep(GenericRightBracket))?; } let mut parameters = Vec::new(); - if input.peek(Sep(FuncLeftParen)) { + if input.peek_eat(Sep(FuncLeftParen)) { parameters.push(parse_type(input)?); - if input.peek(Sep(Comma)) { + if input.peek_eat(Sep(Comma)) { parameters.push(parse_type(input)?); } input.then(Sep(FuncRightParen))?; } - let mut kind = None; - if input.peek(Sep(Colon)) { - kind = Some(parse_type(input)?); + let mut kind = Type::Void; + if input.peek_eat(Sep(Colon)) { + kind = parse_type(input)?; } - Ok(Sig { effect, id, generics, parameters, kind }) + Ok(Sig { id, generics, parameters, kind }) } /// `WrappedType ::= Type | ('[' Type ']')` fn parse_wrapped_type(input: &mut Input) -> Result<Type> { - if input.peek(Sep(GenericLeftBracket)) { + if input.peek_eat(Sep(GenericLeftBracket)) { let result = parse_type(input)?; input.then(Sep(GenericRightBracket))?; Ok(result) @@ -589,12 +591,60 @@ fn parse_wrapped_type(input: &mut Input) -> Result<Type> { } } -/// Pattern ::= Literal | Ident | '(' Pattern (',' Pattern)* ')' | Ident '(' Pattern (',' Pattern)* ')' -fn parse_pattern(input: &mut Input) -> Result<Pattern> { todo!() } +/// Pattern ::= Char | String | Number | Float | Ident | +/// '(' Pattern (',' Pattern)* ')' | Ident '(' Pattern (',' Pattern)* ')' +fn parse_pattern(input: &mut Input) -> Result<Pattern> { + // use Pattern::*; + match input.next()? { + Key(_) => todo!(), + Ident(id) => { + if input.peek() == Some(Sep(FuncLeftParen)) { + Ok(Pattern::Struct(todo!())) + } else { + Ok(Pattern::Ident(id)) + } + }, + Sep(FuncLeftParen) => { // fixme + parse_pattern(input)?; + while input.peek() == Some(Sep(Comma)) { + parse_pattern(input)?; + } + input.then(Sep(FuncRightParen))?; + todo!() + }, + Num(value) => Ok(Pattern::Number(todo!())), + Lit(val) => match val { + Literal::Char(val) => Ok(Pattern::Char(val.parse::<char>()?)), + SingleLineString(val) | MultiLineString(val) => Ok(Pattern::String(val)), + token => Err(format!("expected literal but found token {}", token).into()) + }, + Sep(_) => todo!(), + _ => todo!() + } +} + +// fine to not parse operators until here tbh +fn parse_operator(input: &mut Input) -> Result<Id> { + match input.next()? { + Key(word) => Ok(word.to_string()), + Sep(tok) => { + let mut buf = String::new(); + // buf.push(tok); + loop { + match input.peek() { + Some(Key(_)) => todo!(), + _ => break + } + } + Ok(buf) + }, + token => Err(format!("expected operator but found token {}", token).into()) + } +} fn parse_ident(input: &mut Input) -> Result<Id> { match input.next()? { - Word(id) => Ok(id), + Ident(id) => Ok(id), token => Err(format!("expected identifier but found token {}", token).into()) } } |