Skip to content

Commit

Permalink
Refactor syntax-gen.
Browse files Browse the repository at this point in the history
commit-id:b1bb85ba
  • Loading branch information
orizi committed Oct 8, 2024
1 parent db58380 commit 957613f
Show file tree
Hide file tree
Showing 2 changed files with 358 additions and 497 deletions.
74 changes: 20 additions & 54 deletions crates/cairo-lang-syntax-codegen/src/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,70 +64,44 @@ fn generate_kinds_code() -> rust::Tokens {
$("// Autogenerated file. To regenerate, please run `cargo run --bin generate-syntax`.\n")
use core::fmt;
};
let mut kinds = rust::Tokens::new();
let mut token_kinds = rust::Tokens::new();
let mut keyword_token_kinds = rust::Tokens::new();
let mut terminal_kinds = rust::Tokens::new();
let mut keyword_terminal_kinds = rust::Tokens::new();

// SyntaxKind.
for Node { name, kind } in spec.iter() {
match kind {
NodeKind::Enum { .. } => {}
_ => {
kinds.extend(quote! {
$name,
});
}
}
}

for Node { name, kind } in spec.into_iter() {
match kind {
NodeKind::Token { is_keyword } => {
append_rust_token(&mut token_kinds, &name);
if is_keyword {
append_rust_token(&mut keyword_token_kinds, &name);
}
}
NodeKind::Terminal { is_keyword, .. } => {
append_rust_token(&mut terminal_kinds, &name);
if is_keyword {
append_rust_token(&mut keyword_terminal_kinds, &name);
}
}
_ => {}
}
}
let kinds = name_tokens(&spec, |k| !matches!(k, NodeKind::Enum { .. }));
let token_kinds = name_tokens(&spec, |k| matches!(k, NodeKind::Token { .. }));
let keyword_token_kinds =
name_tokens(&spec, |k| matches!(k, NodeKind::Token { is_keyword } if *is_keyword));
let terminal_kinds = name_tokens(&spec, |k| matches!(k, NodeKind::Terminal { .. }));
let keyword_terminal_kinds =
name_tokens(&spec, |k| matches!(k, NodeKind::Terminal { is_keyword, .. } if *is_keyword));

tokens.extend(quote! {
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)]
pub enum SyntaxKind {
$kinds
$(for t in kinds => $t,)
}
impl SyntaxKind {
pub fn is_token(&self) -> bool {
matches!(
*self,
$token_kinds
$(for t in token_kinds join ( | ) => SyntaxKind::$t)
)
}
pub fn is_terminal(&self) -> bool {
matches!(
*self,
$terminal_kinds
$(for t in terminal_kinds join ( | ) => SyntaxKind::$t)
)
}
pub fn is_keyword_token(&self) -> bool {
matches!(
*self,
$keyword_token_kinds
$(for t in keyword_token_kinds join ( | ) => SyntaxKind::$t)
)
}
pub fn is_keyword_terminal(&self) -> bool {
matches!(
*self,
$keyword_terminal_kinds
$(for t in keyword_terminal_kinds join ( | ) => SyntaxKind::$t)
)
}
}
Expand All @@ -140,6 +114,11 @@ fn generate_kinds_code() -> rust::Tokens {
tokens
}

/// Returns an iterator to the names of the tokens matching `predicate`.
fn name_tokens(spec: &[Node], predicate: impl Fn(&NodeKind) -> bool) -> impl Iterator<Item = &str> {
spec.iter().filter(move |n| predicate(&n.kind)).map(|n| n.name.as_str())
}

fn generate_key_fields_code() -> rust::Tokens {
let spec = get_spec();
let mut arms = rust::Tokens::new();
Expand Down Expand Up @@ -504,14 +483,10 @@ fn gen_enum_code(
node.stable_ptr().untyped()
}
}
impl $(&name){
// Checks if a kind of a variant of $(&name).
#[allow(clippy::match_like_matches_macro)]
impl $(&name) {
$("/// Checks if a kind of a variant of [")$(&name)$("].\n")
pub fn is_variant(kind: SyntaxKind) -> bool {
match kind {
$(for v in &variants => SyntaxKind::$(&v.kind) => true,)
_ => false,
}
matches!(kind, $(for v in &variants join (|) => SyntaxKind::$(&v.kind)))
}
}
}
Expand Down Expand Up @@ -745,12 +720,3 @@ fn gen_struct_code(name: String, members: Vec<Member>, is_terminal: bool) -> rus
}
}
}

/// Appends the given rust token to the given list
fn append_rust_token(list: &mut rust::Tokens, name: &str) {
if list.is_empty() {
list.append(format!("SyntaxKind::{name}"));
} else {
list.append(format!("| SyntaxKind::{name}"));
}
}
Loading

0 comments on commit 957613f

Please sign in to comment.