Skip to content

Commit

Permalink
feat(parser): support for assignment and recovery for local keyword.
Browse files Browse the repository at this point in the history
  • Loading branch information
rzvxa committed Mar 8, 2024
1 parent 0c77cf2 commit 5ce1342
Show file tree
Hide file tree
Showing 15 changed files with 178 additions and 17 deletions.
1 change: 1 addition & 0 deletions crates/fuse-ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,7 @@ pub struct BinaryOperator {
#[serializable]
#[derive(Debug, PartialEq)]
pub enum BinaryOperatorKind {
Assignment(Span),
LogicalOr(Span),
LogicalAnd(Span),
BitwiseOr(Span),
Expand Down
1 change: 1 addition & 0 deletions crates/fuse-parser/src/lexer/keyword.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ impl<'a> Lexer<'a> {
"n" => TokenKind::In,
}
'l' => {
"ocal" => TokenKind::Local,
"et" => TokenKind::Let,
}
'm' => {
Expand Down
2 changes: 2 additions & 0 deletions crates/fuse-parser/src/lexer/token_kind.rs
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ pub enum TokenKind {
Import,
In,
Let,
Local,
Match,
Mut,
Never,
Expand Down Expand Up @@ -207,6 +208,7 @@ impl TokenKind {
use Precedence::*;
use TokenKind::*;
match self {
Eq => Some(Assignment),
Or => Some(LogicalOr),
And => Some(LogicalAnd),
Pipe => Some(BitwiseOr),
Expand Down
15 changes: 14 additions & 1 deletion crates/fuse-parser/src/parsers/declarations.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
use crate::{lexer::TokenKind, Parser, ParserResult};
use fuse_ast::{Function, VariableDeclaration, VariableDeclarationKind};
use fuse_ast::{EnumDeclaration, Function, VariableDeclaration, VariableDeclarationKind};

impl<'a> Parser<'a> {
pub(crate) fn parse_variable_declaration(&mut self) -> ParserResult<VariableDeclaration> {
let decl_kind = match self.cur_kind() {
TokenKind::Let => VariableDeclarationKind::Let,
TokenKind::Const => VariableDeclarationKind::Const,
TokenKind::Global => VariableDeclarationKind::Global,
TokenKind::Local => {
self.push_error(Self::unexpected_error(self.cur_token()));
VariableDeclarationKind::Let
}
_ => return Err(Self::unexpected_error(self.cur_token())),
};

Expand All @@ -30,4 +34,13 @@ impl<'a> Parser<'a> {
pub(crate) fn parse_function_declaration(&mut self) -> ParserResult<Function> {
self.parse_function(true)
}

pub(crate) fn parse_enum_declaration(&mut self) -> ParserResult<EnumDeclaration> {
debug_assert!(self.at(TokenKind::Enum));
// Consume the enum keyword.
self.consume();

let identifier = self.parse_identifier()?;
todo!()
}
}
1 change: 1 addition & 0 deletions crates/fuse-parser/src/parsers/operators.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ impl<'a> Parser<'a> {
)
}
match_op! {
Eq => Assignment
Or => LogicalOr
And => LogicalAnd
Pipe => BitwiseOr
Expand Down
6 changes: 5 additions & 1 deletion crates/fuse-parser/src/parsers/statements.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ impl<'a> Parser<'a> {
match cur_kind {
TokenKind::Semicolon => ParserResult::Ok(self.parse_empty_statement()),

TokenKind::Const | TokenKind::Let | TokenKind::Global => self
TokenKind::Const | TokenKind::Let | TokenKind::Global | TokenKind::Local => self
.parse_variable_declaration()
.map(|decl| self.ast.variable_declaration_statement(decl)),

Expand All @@ -64,6 +64,10 @@ impl<'a> Parser<'a> {
}
}

TokenKind::Enum => self
.parse_enum_declaration()
.map(|decl| self.ast.enum_declaration_statement(decl)),

kind if kind.is_trivial() => {
unreachable!("All trivial tokens should be eaten by a `TokenReference`.")
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
---
source: crates/fuse-parser/tests/cases/mod.rs
expression: parsed.chunk
input_file: crates/fuse-parser/tests/cases/fail/variable-declaration-01/case.fuse
---
Some(Chunk(
span: Span(
start: 0,
end: 17,
),
body: Block(
statements: [
VariableDeclaration(VariableDeclaration(
span: Span(
start: 0,
end: 16,
),
kind: Let,
binding: BindingPattern(
kind: Identifier(BindingIdentifier(
span: Span(
start: 6,
end: 10,
),
atom: Atom("name"),
mutable: false,
)),
type_annotation: None,
optional: false,
),
expression: Some(NumberLiteral(NumberLiteral(
span: Span(
start: 13,
end: 16,
),
raw: Atom("123"),
value: 123.0,
kind: Decimal,
))),
)),
],
),
))
Original file line number Diff line number Diff line change
@@ -1,23 +1,23 @@
---
source: crates/fuse-parser/tests/cases/mod.rs
expression: parsed.errors
input_file: crates/fuse-parser/tests/cases/panic/variable-declaration-01/case.fuse
input_file: crates/fuse-parser/tests/cases/fail/variable-declaration-01/case.fuse
---
[
UnexpectedError(TokenReference(
token: Token(
span: Span(
start: 11,
end: 12,
start: 0,
end: 5,
),
kind: Eq,
kind: Local,
),
leading_trivia: [],
trailing_trivia: [
Token(
span: Span(
start: 12,
end: 13,
start: 5,
end: 6,
),
kind: Whitespace,
),
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
source: crates/fuse-parser/tests/cases/mod.rs
expression: tokens
input_file: crates/fuse-parser/tests/cases/panic/variable-declaration-01/case.fuse
input_file: crates/fuse-parser/tests/cases/fail/variable-declaration-01/case.fuse
---
[
TokenReference(
Expand All @@ -10,7 +10,7 @@ input_file: crates/fuse-parser/tests/cases/panic/variable-declaration-01/case.fu
start: 0,
end: 5,
),
kind: Identifier,
kind: Local,
),
leading_trivia: [],
trailing_trivia: [
Expand Down
2 changes: 1 addition & 1 deletion crates/fuse-parser/tests/cases/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ fn pass() {
}
}

// #[test]
#[test]
fn fail() {
let root = PathBuf::from(env!("CARGO_MANIFEST_DIR"));

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
---
source: crates/fuse-parser/tests/cases/mod.rs
expression: parsed.chunk
input_file: crates/fuse-parser/tests/cases/pass/variable-assignment-01/case.fuse
---
Some(Chunk(
span: Span(
start: 0,
end: 8,
),
body: Block(
statements: [
Expression(BinaryOperator(BinaryOperator(
kind: Assignment(Span(
start: 2,
end: 3,
)),
lhs: Identifier(Identifier(
span: Span(
start: 0,
end: 1,
),
name: Atom("x"),
)),
rhs: NumberLiteral(NumberLiteral(
span: Span(
start: 4,
end: 7,
),
raw: Atom("123"),
value: 123.0,
kind: Decimal,
)),
))),
],
),
))
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
x = 123
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
---
source: crates/fuse-parser/tests/cases/mod.rs
expression: tokens
input_file: crates/fuse-parser/tests/cases/pass/variable-assignment-01/case.fuse
---
[
TokenReference(
token: Token(
span: Span(
start: 0,
end: 1,
),
kind: Identifier,
),
leading_trivia: [],
trailing_trivia: [
Token(
span: Span(
start: 1,
end: 2,
),
kind: Whitespace,
),
],
),
TokenReference(
token: Token(
span: Span(
start: 2,
end: 3,
),
kind: Eq,
),
leading_trivia: [],
trailing_trivia: [
Token(
span: Span(
start: 3,
end: 4,
),
kind: Whitespace,
),
],
),
TokenReference(
token: Token(
span: Span(
start: 4,
end: 7,
),
kind: NumberLiteral,
),
leading_trivia: [],
trailing_trivia: [
Token(
span: Span(
start: 7,
end: 8,
),
kind: Whitespace,
),
],
),
]

0 comments on commit 5ce1342

Please sign in to comment.