aboutsummaryrefslogtreecommitdiff
path: root/src/frontend/parse.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/frontend/parse.rs')
-rw-r--r--src/frontend/parse.rs218
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())
}
}