Skip to content

Commit

Permalink
Turn SyntaxKind into a wrapper 🎉
Browse files Browse the repository at this point in the history
Having SyntaxKind be a unit-only enum repeating all the fields of
TokenKind and adding some SyntaxConstructs on top was not ergonomic

Now, SyntaxKind holds either a TokenKind or a SyntaxConstruct, which
hold what you would expect.

Removes the full coverage test as it is no longer needed

Some dependencies have been migrated to other crates:
num-derive and num-traits have been phased out in favour of num_enum
  • Loading branch information
LucasFA committed May 11, 2023
1 parent 977946e commit 8316ea9
Show file tree
Hide file tree
Showing 11 changed files with 134 additions and 237 deletions.
59 changes: 36 additions & 23 deletions crates/ast/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#![warn(clippy::pedantic)]

use syntax::{SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken};

use syntax::{SyntaxConstruct, SyntaxElement, SyntaxKind, SyntaxNode, SyntaxToken, TokenKind};
pub mod validation;

pub trait TypedSyntaxNode {
Expand All @@ -21,16 +20,17 @@ mod macros {
where
Self: Sized,
{
if node.kind() == SyntaxKind::$struct_name {
if let SyntaxKind::SyntaxConstruct(SyntaxConstruct::$struct_name) = node.kind()
{
Some(Self(node))
} else {
None
}
}
}
const _: () = {
// Simply a check that struct_name is a variant of SyntaxKind
const _: SyntaxKind = SyntaxKind::$struct_name;
// Simply a check that struct_name is a variant of SyntaxConstruct
const _: SyntaxConstruct = SyntaxConstruct::$struct_name;
};
};
}
Expand Down Expand Up @@ -58,7 +58,7 @@ impl Root {
#[must_use]
pub fn get_variable_references(&self) -> Vec<VariableRef> {
fn inner_get_variable_references(node: SyntaxNode) -> Vec<VariableRef> {
if node.kind() == SyntaxKind::VariableRef {
if node.kind() == SyntaxConstruct::VariableRef.into() {
vec![VariableRef::cast(node).unwrap()]
} else {
node.children()
Expand All @@ -75,11 +75,11 @@ impl VariableDef {
self.0
.children_with_tokens()
.filter_map(SyntaxElement::into_node)
.find(|node| node.kind() == SyntaxKind::VariableRef)
.find(|node| node.kind() == SyntaxConstruct::VariableRef.into())
.unwrap()
.children_with_tokens()
.filter_map(SyntaxElement::into_token)
.find(|token| token.kind() == SyntaxKind::Identifier)
.find(|token| token.kind() == TokenKind::Identifier.into())
}

pub fn value(&self) -> Option<Expr> {
Expand All @@ -90,14 +90,21 @@ impl VariableDef {
impl Expr {
#[must_use]
pub fn cast(node: SyntaxNode) -> Option<Self> {
let result = match node.kind() {
SyntaxKind::InfixExpr => Self::BinaryExpr(BinaryExpr(node)),
SyntaxKind::Literal => Self::Literal(Literal(node)),
SyntaxKind::ParenExpr => Self::ParenExpr(ParenExpr(node)),
SyntaxKind::PrefixExpr => Self::UnaryExpr(UnaryExpr(node)),
SyntaxKind::VariableRef => Self::VariableRef(VariableRef(node)),
_ => return None,
};
let result;
if let SyntaxKind::SyntaxConstruct(inner) = node.kind() {
result = match inner {
SyntaxConstruct::InfixExpr => Self::BinaryExpr(BinaryExpr(node)),
SyntaxConstruct::Literal => Self::Literal(Literal(node)),
SyntaxConstruct::ParenExpr => Self::ParenExpr(ParenExpr(node)),
SyntaxConstruct::PrefixExpr => Self::UnaryExpr(UnaryExpr(node)),
SyntaxConstruct::VariableRef => Self::VariableRef(VariableRef(node)),
SyntaxConstruct::Error => return None,
SyntaxConstruct::Root => unreachable!(),
SyntaxConstruct::VariableDef => unreachable!(),
};
} else {
return None;
}

Some(result)
}
Expand All @@ -117,10 +124,14 @@ impl BinaryExpr {
.children_with_tokens()
.filter_map(SyntaxElement::into_token)
.find(|token| {
matches!(
token.kind(),
SyntaxKind::Plus | SyntaxKind::Minus | SyntaxKind::Asterisk | SyntaxKind::Slash,
)
if let SyntaxKind::LexToken(inner) = token.kind() {
matches!(
inner,
TokenKind::Plus | TokenKind::Minus | TokenKind::Asterisk | TokenKind::Slash,
)
} else {
false
}
})
}
}
Expand All @@ -134,7 +145,7 @@ impl UnaryExpr {
self.0
.children_with_tokens()
.filter_map(SyntaxElement::into_token)
.find(|token| token.kind() == SyntaxKind::Minus)
.find(|token| token.kind() == TokenKind::Minus.into())
}
}

Expand All @@ -152,7 +163,7 @@ impl Literal {

#[must_use]
pub fn cast(node: SyntaxNode) -> Option<Self> {
if node.kind() == SyntaxKind::Literal {
if node.kind() == SyntaxConstruct::Literal.into() {
Some(Self(node))
} else {
None
Expand All @@ -177,7 +188,9 @@ impl Stmt {
#[must_use]
pub fn cast(node: SyntaxNode) -> Option<Self> {
let result = match node.kind() {
SyntaxKind::VariableDef => Self::VariableDef(VariableDef(node)),
SyntaxKind::SyntaxConstruct(SyntaxConstruct::VariableDef) => {
Self::VariableDef(VariableDef(node))
}
_ => Self::Expr(Expr::cast(node)?),
};

Expand Down
12 changes: 6 additions & 6 deletions crates/hir/src/database.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::{BinaryOp, Expr, Stmt, UnaryOp};
use la_arena::Arena;
use syntax::SyntaxKind;
use syntax::{SyntaxKind, TokenKind};

#[derive(Debug, PartialEq, Default)]
pub struct Database {
Expand Down Expand Up @@ -42,10 +42,10 @@ impl Database {

fn lower_binary(&mut self, ast: ast::BinaryExpr) -> Expr {
let op = match ast.op().unwrap().kind() {
SyntaxKind::Plus => BinaryOp::Add,
SyntaxKind::Minus => BinaryOp::Sub,
SyntaxKind::Asterisk => BinaryOp::Mul,
SyntaxKind::Slash => BinaryOp::Div,
SyntaxKind::LexToken(TokenKind::Plus) => BinaryOp::Add,
SyntaxKind::LexToken(TokenKind::Minus) => BinaryOp::Sub,
SyntaxKind::LexToken(TokenKind::Asterisk) => BinaryOp::Mul,
SyntaxKind::LexToken(TokenKind::Slash) => BinaryOp::Div,
_ => unreachable!(),
};

Expand All @@ -61,7 +61,7 @@ impl Database {

fn lower_unary(&mut self, ast: ast::UnaryExpr) -> Expr {
let op = match ast.op().unwrap().kind() {
SyntaxKind::Minus => UnaryOp::Neg,
SyntaxKind::LexToken(TokenKind::Minus) => UnaryOp::Neg,
_ => unreachable!(),
};

Expand Down
4 changes: 2 additions & 2 deletions crates/lexer/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,5 +11,5 @@ logos = "0.12.1"
text-size = "1.1.0"
strum = "0.24.1"
strum_macros = "0.24.3"
num-derive = "0.3.3"
num-traits = "0.2.15"
num_enum = "0.6.1"
num_enum_derive = "0.6.1"
13 changes: 7 additions & 6 deletions crates/lexer/src/token_kind.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use logos::Logos;
use num_derive::{FromPrimitive, ToPrimitive};
use num_enum::{IntoPrimitive, TryFromPrimitive};
use std::fmt;
use strum_macros::EnumIter;
use strum_macros::EnumCount;

/// The kind of a token produced by the lexer.
/// It is called this for consistency with Rowan, the parsing library.
Expand All @@ -15,13 +15,14 @@ use strum_macros::EnumIter;
PartialOrd,
Ord,
Hash,
EnumIter,
ToPrimitive,
FromPrimitive,
IntoPrimitive,
TryFromPrimitive,
EnumCount,
)]
#[repr(u16)]
#[cfg_attr(test, derive(strum_macros::EnumIter))]
// #[logos(subpattern close_block_comment = r##"(#|%)\}"##)]
// #[logos(subpattern open_block_comment = r##"(#|%)\{"##)]
#[repr(u8)]
pub enum TokenKind {
// This would be ideal for block comments, but logos doesn't support non-greedy regexes
// #[regex(r##"(#|%)\{\s*\n(.|\n)*?(#|%)\}"##)]
Expand Down
3 changes: 2 additions & 1 deletion crates/parser/src/grammar.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ mod stmt;
use crate::parser::marker::CompletedMarker;
use crate::parser::Parser;
use lexer::TokenKind;
use syntax::SyntaxConstruct;
use syntax::SyntaxKind;

pub(crate) fn root(p: &mut Parser) -> CompletedMarker {
Expand All @@ -12,5 +13,5 @@ pub(crate) fn root(p: &mut Parser) -> CompletedMarker {
stmt::stmt(p);
}

m.complete(p, SyntaxKind::Root)
m.complete(p, SyntaxKind::SyntaxConstruct(SyntaxConstruct::Root))
}
12 changes: 6 additions & 6 deletions crates/parser/src/grammar/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use crate::parser::marker::CompletedMarker;
use crate::parser::Parser;
use lexer::TokenKind;
use syntax::SyntaxKind;
use syntax::SyntaxConstruct;

enum BinaryOp {
Add,
Expand Down Expand Up @@ -43,15 +43,15 @@ fn literal(p: &mut Parser) -> CompletedMarker {

let m = p.start();
p.bump();
m.complete(p, SyntaxKind::Literal)
m.complete(p, SyntaxConstruct::Literal.into())
}

fn variable_ref(p: &mut Parser) -> CompletedMarker {
assert!(p.at(TokenKind::Identifier));

let m = p.start();
p.bump();
m.complete(p, SyntaxKind::VariableRef)
m.complete(p, SyntaxConstruct::VariableRef.into())
}

fn prefix_expr(p: &mut Parser) -> CompletedMarker {
Expand All @@ -67,7 +67,7 @@ fn prefix_expr(p: &mut Parser) -> CompletedMarker {

expr_binding_power(p, right_binding_power);

m.complete(p, SyntaxKind::PrefixExpr)
m.complete(p, SyntaxConstruct::PrefixExpr.into())
}

fn paren_expr(p: &mut Parser) -> CompletedMarker {
Expand All @@ -80,7 +80,7 @@ fn paren_expr(p: &mut Parser) -> CompletedMarker {

p.expect(TokenKind::RParen);

m.complete(p, SyntaxKind::ParenExpr)
m.complete(p, SyntaxConstruct::ParenExpr.into())
}

fn lhs(p: &mut Parser) -> Option<CompletedMarker> {
Expand Down Expand Up @@ -136,7 +136,7 @@ fn expr_binding_power(p: &mut Parser, minimum_binding_power: u8) -> Option<Compl
let m = lhs.precede(p);

let parsed_rhs = expr_binding_power(p, right_binding_power).is_some();
lhs = m.complete(p, SyntaxKind::InfixExpr);
lhs = m.complete(p, SyntaxConstruct::InfixExpr.into());

if !parsed_rhs {
break;
Expand Down
16 changes: 10 additions & 6 deletions crates/parser/src/grammar/stmt.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use super::{expr, CompletedMarker, Parser, SyntaxKind, TokenKind};
use syntax::SyntaxConstruct;

use super::{expr, CompletedMarker, Parser, TokenKind};

pub(super) fn stmt(p: &mut Parser) -> Option<CompletedMarker> {
if p.at(TokenKind::Identifier) {
Expand All @@ -14,23 +16,25 @@ fn handle_variable(p: &mut Parser) -> CompletedMarker {
p.bump();

if p.at(TokenKind::Equals) {
let var_def = lhs.complete(p, SyntaxKind::VariableRef).precede(p);
let var_def = lhs
.complete(p, SyntaxConstruct::VariableRef.into())
.precede(p);
p.bump();
expr::expr(p);
return var_def.complete(p, SyntaxKind::VariableDef);
return var_def.complete(p, SyntaxConstruct::VariableDef.into());
}

if p.at_end() {
return lhs.complete(p, SyntaxKind::VariableRef);
return lhs.complete(p, SyntaxConstruct::VariableRef.into());
}

let lhs = lhs.complete(p, SyntaxKind::VariableRef);
let lhs = lhs.complete(p, SyntaxConstruct::VariableRef.into());
let m = lhs.precede(p);
// get what it is and then
p.bump();
expr::expr(p);

m.complete(p, SyntaxKind::InfixExpr)
m.complete(p, SyntaxConstruct::InfixExpr.into())
}

#[cfg(test)]
Expand Down
4 changes: 2 additions & 2 deletions crates/parser/src/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::source::Source;
use lexer::{Token, TokenKind};
use marker::Marker;
use std::mem;
use syntax::SyntaxKind;
use syntax::SyntaxConstruct;

const RECOVERY_SET: [TokenKind; 0] = [];

Expand Down Expand Up @@ -84,7 +84,7 @@ impl<'t, 'input> Parser<'t, 'input> {
if !self.at_set(&RECOVERY_SET) && !self.at_end() {
let m = self.start();
self.bump();
m.complete(self, SyntaxKind::Error);
m.complete(self, SyntaxConstruct::Error.into());
}
}

Expand Down
4 changes: 2 additions & 2 deletions crates/syntax/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ publish = false

[dependencies]
lexer = {path = "../lexer"}
num-derive = "0.3.3"
num-traits = "0.2.15"
rowan = "0.15.11"
strum = "0.24.1"
strum_macros = "0.24.3"
num_enum = "0.6.1"
static_assertions = "1.1.0"
Loading

0 comments on commit 8316ea9

Please sign in to comment.