[fine] Starting on lists, god help me

This commit is contained in:
John Doty 2024-01-17 15:58:48 -08:00
parent 106f2eb30f
commit 9ee8d39963
5 changed files with 190 additions and 35 deletions

View file

@ -139,6 +139,10 @@ pub enum TreeKind {
IfStatement,
Identifier,
ReturnType,
TypeParameterList,
TypeParameter,
ListConstructor,
ListConstructorElement,
}
pub struct Tree<'a> {
@ -566,11 +570,46 @@ fn return_type(p: &mut CParser) {
fn type_expr(p: &mut CParser) {
let m = p.start();
// TODO: Other kinds of type expressions probably!
p.expect(TokenKind::Identifier, "expected the identifier of a type");
if p.at(TokenKind::Less) {
type_parameter_list(p);
}
p.end(m, TreeKind::TypeExpression);
}
fn type_parameter_list(p: &mut CParser) {
assert!(p.at(TokenKind::Less));
let m = p.start();
p.expect(TokenKind::Less, "expected < to start type parameter list");
while !p.at(TokenKind::Greater) && !p.eof() {
if p.at(TokenKind::Identifier) {
type_parameter(p);
} else {
break;
}
}
p.expect(TokenKind::Greater, "expected > to end type parameter list");
p.end(m, TreeKind::TypeParameterList);
}
fn type_parameter(p: &mut CParser) {
assert!(p.at(TokenKind::Identifier));
let m = p.start();
type_expr(p);
if !p.at(TokenKind::Greater) {
p.expect(TokenKind::Comma, "expect a comma between type parameters");
}
p.end(m, TreeKind::TypeParameter);
}
fn block(p: &mut CParser) {
assert!(p.at(TokenKind::LeftBrace));
let m = p.start();
@ -758,6 +797,8 @@ fn prefix_expression(p: &mut CParser) -> MarkClosed {
TokenKind::Identifier => identifier(p),
TokenKind::LeftBracket => list_constructor(p),
_ => p.advance_with_error("expected an expression"),
}
}
@ -816,6 +857,39 @@ fn identifier(p: &mut CParser) -> MarkClosed {
p.end(m, TreeKind::Identifier)
}
fn list_constructor(p: &mut CParser) -> MarkClosed {
assert!(p.at(TokenKind::LeftBracket));
let m = p.start();
p.expect(
TokenKind::LeftBracket,
"expect a list constructor to start with [",
);
while !p.at(TokenKind::RightBracket) && !p.eof() {
list_constructor_element(p);
}
p.expect(
TokenKind::RightBracket,
"expected a ] to end the list constructor",
);
p.end(m, TreeKind::ListConstructor)
}
fn list_constructor_element(p: &mut CParser) {
let m = p.start();
expression(p);
if !p.at(TokenKind::RightBracket) {
p.expect(
TokenKind::Comma,
"expected a comma between list constructor elements",
);
}
p.end(m, TreeKind::ListConstructorElement);
}
#[cfg(test)]
mod tests {
use super::*;