Skip to content

Commit

Permalink
update grammar to v0.6.1
Browse files Browse the repository at this point in the history
  • Loading branch information
SpontanCombust committed Jan 19, 2024
1 parent 5ddbaf6 commit 965fc1e
Show file tree
Hide file tree
Showing 6 changed files with 147 additions and 66 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

70 changes: 39 additions & 31 deletions crates/analysis/src/jobs/syntax_analysis/syntax_error_visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ impl SyntaxErrorVisitor<'_> {
})
}

/// Returns true if the node is present, false otherwise
fn check_missing<T>(&mut self, n: SyntaxNode<'_, T>, expected: &str) -> bool {
if n.is_missing() {
self.missing_element(n.range(), expected.to_string());
Expand All @@ -35,6 +36,7 @@ impl SyntaxErrorVisitor<'_> {
}
}

/// Returns true if the identifier is present, false otherwise
fn check_identifier(&mut self, n: IdentifierNode) -> bool {
self.check_missing(n, "identifier")
}
Expand All @@ -49,11 +51,13 @@ impl SyntaxErrorVisitor<'_> {
self.check_errors(&n);
}

/// Returns true if the literal is present, false otherwise
fn check_literal_int(&mut self, n: LiteralIntNode) -> bool {
self.check_missing(n, "integer number")
}

fn check_literal_string(&mut self, n: LiteralStringNode) -> bool{
/// Returns true if the literal is present, false otherwise
fn check_literal_string(&mut self, n: LiteralStringNode) -> bool {
self.check_missing(n, "string")
}

Expand All @@ -67,6 +71,20 @@ impl SyntaxErrorVisitor<'_> {
}
}

/// Returns whether the definition contains no errors
fn check_function_def(&mut self, n: FunctionDefinitionNode) -> bool {
if self.check_missing(n.clone(), "{ or ;") {
if let FunctionDefinition::Some(block) = n.value() {
if block.has_errors() {
self.check_errors(&block);
return false;
}
}
}

true
}

fn check_errors<T>(&mut self, n: &SyntaxNode<'_, T>) -> bool {
let errors = n.errors();
if errors.is_empty() {
Expand Down Expand Up @@ -246,16 +264,15 @@ impl StatementVisitor for SyntaxErrorVisitor<'_> {
n.return_type().map(|n| self.check_type_annot(n));

self.check_errors(n);

if let Some(def) = n.definition() {
if def.has_errors() {
self.check_errors(&def);
return true;
}

if !self.check_function_def(n.definition()) {
return true;
}
}

false

//FIXME check for errors in params - maybe grammar should have a named node for the entirety of params? Apply this thinking to other repeating rules.
// false
true
}

fn visit_member_func_decl(&mut self, n: &MemberFunctionDeclarationNode) -> bool {
Expand All @@ -268,32 +285,30 @@ impl StatementVisitor for SyntaxErrorVisitor<'_> {

self.check_errors(n);

if let Some(def) = n.definition() {
if def.has_errors() {
self.check_errors(&def);
return true;
}
if !self.check_function_def(n.definition()) {
return true;
}
}

false

//FIXME check for errors in params
// false
true
}

fn visit_event_decl(&mut self, n: &EventDeclarationNode) -> bool {
if n.has_errors() {
self.check_identifier(n.name());

self.check_errors(n);

if let Some(def) = n.definition() {
if def.has_errors() {
self.check_errors(&def);
return true;
}

if !self.check_function_def(n.definition()) {
return true;
}
}

false

//FIXME check for errors in params
// false
true
}

fn visit_block_stmt(&mut self, n: &FunctionBlockNode) -> bool {
Expand Down Expand Up @@ -432,13 +447,6 @@ impl StatementVisitor for SyntaxErrorVisitor<'_> {
self.check_errors(n);
}
}

fn visit_nop_stmt(&mut self, n: &NopNode) {
self.diagnostics.push(Diagnostic {
range: n.range(),
body: InfoDiagnostic::TrailingSemicolon.into()
})
}
}

impl ExpressionVisitor for SyntaxErrorVisitor<'_> {
Expand Down
2 changes: 1 addition & 1 deletion crates/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ encoding_rs_io = "0.1"

[dependencies.tree-sitter-witcherscript]
git = "https://github.com/SpontanCombust/tree-sitter-witcherscript.git"
tag = "v0.5.0"
tag = "v0.6.1"
16 changes: 13 additions & 3 deletions crates/core/src/ast/expressions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -769,7 +769,7 @@ impl ExpressionTraversal for TernaryConditionalExpressionNode<'_> {



// Represents the anonymous $._expr node
// Represents the unnamed $._expr node
#[derive(Clone)]
pub enum Expression<'script> {
Nested(NestedExpressionNode<'script>),
Expand Down Expand Up @@ -836,7 +836,12 @@ impl<'script> ExpressionNode<'script> {
ParentExpressionNode::NODE_KIND => Expression::Parent(self.into()),
VirtualParentExpressionNode::NODE_KIND => Expression::VirtualParent(self.into()),
IdentifierNode::NODE_KIND => Expression::Identifier(self.into()),
LiteralNode::NODE_KIND => Expression::Literal(self.into()),
LiteralIntNode::NODE_KIND |
LiteralFloatNode::NODE_KIND |
LiteralBoolNode::NODE_KIND |
LiteralStringNode::NODE_KIND |
LiteralNameNode::NODE_KIND |
LiteralNullNode::NODE_KIND => Expression::Literal(self.into()),
_ => panic!("Unknown expression type: {}", self.tree_node.kind())
}
}
Expand Down Expand Up @@ -873,7 +878,12 @@ impl<'script> TryFrom<AnyNode<'script>> for ExpressionNode<'script> {
ParentExpressionNode::NODE_KIND |
VirtualParentExpressionNode::NODE_KIND |
IdentifierNode::NODE_KIND |
LiteralNode::NODE_KIND => Ok(value.into()),
LiteralIntNode::NODE_KIND |
LiteralFloatNode::NODE_KIND |
LiteralBoolNode::NODE_KIND |
LiteralStringNode::NODE_KIND |
LiteralNameNode::NODE_KIND |
LiteralNullNode::NODE_KIND => Ok(value.into()),
_ => Err(())
}
}
Expand Down
77 changes: 68 additions & 9 deletions crates/core/src/ast/functions.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,8 +21,8 @@ impl EventDeclarationNode<'_> {
self.field_children("params").map(|n| n.into())
}

pub fn definition(&self) -> Option<FunctionBlockNode> {
self.field_child("definition").map(|n| n.into())
pub fn definition(&self) -> FunctionDefinitionNode {
self.field_child("definition").unwrap().into()
}
}

Expand Down Expand Up @@ -52,7 +52,7 @@ impl StatementTraversal for EventDeclarationNode<'_> {
fn accept<V: StatementVisitor>(&self, visitor: &mut V) {
if visitor.visit_event_decl(self) {
self.params().for_each(|p| p.accept(visitor));
self.definition().map(|s| s.accept(visitor));
self.definition().accept(visitor);
}
visitor.exit_event_decl(self);
}
Expand Down Expand Up @@ -90,8 +90,8 @@ impl GlobalFunctionDeclarationNode<'_> {
self.field_child("return_type").map(|n| n.into())
}

pub fn definition(&self) -> Option<FunctionBlockNode> {
self.field_child("definition").map(|n| n.into())
pub fn definition(&self) -> FunctionDefinitionNode {
self.field_child("definition").unwrap().into()
}
}

Expand Down Expand Up @@ -124,7 +124,7 @@ impl StatementTraversal for GlobalFunctionDeclarationNode<'_> {
fn accept<V: StatementVisitor>(&self, visitor: &mut V) {
if visitor.visit_global_func_decl(self) {
self.params().for_each(|p| p.accept(visitor));
self.definition().map(|s| s.accept(visitor));
self.definition().accept(visitor);
}
visitor.exit_global_func_decl(self);
}
Expand Down Expand Up @@ -162,8 +162,8 @@ impl MemberFunctionDeclarationNode<'_> {
self.field_child("return_type").map(|n| n.into())
}

pub fn definition(&self) -> Option<FunctionBlockNode> {
self.field_child("definition").map(|n| n.into())
pub fn definition(&self) -> FunctionDefinitionNode {
self.field_child("definition").unwrap().into()
}
}

Expand Down Expand Up @@ -196,14 +196,72 @@ impl StatementTraversal for MemberFunctionDeclarationNode<'_> {
fn accept<V: StatementVisitor>(&self, visitor: &mut V) {
if visitor.visit_member_func_decl(self) {
self.params().for_each(|p| p.accept(visitor));
self.definition().map(|s| s.accept(visitor));
self.definition().accept(visitor);
}
visitor.exit_member_func_decl(self);
}
}



#[derive(Clone)]
pub enum FunctionDefinition<'script> {
Some(FunctionBlockNode<'script>),
None(NopNode<'script>)
}

impl Debug for FunctionDefinition<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Self::Some(n) => f.debug_tuple("Some").field(n).finish(),
Self::None(_) => f.debug_tuple("None").finish(),
}
}
}

pub type FunctionDefinitionNode<'script> = SyntaxNode<'script, FunctionDefinition<'script>>;

impl<'script> FunctionDefinitionNode<'script> {
pub fn value(self) -> FunctionDefinition<'script> {
match self.tree_node.kind() {
FunctionBlockNode::NODE_KIND => FunctionDefinition::Some(self.into()),
NopNode::NODE_KIND => FunctionDefinition::None(self.into()),
_ => panic!("Unknown function definition node: {}", self.tree_node.kind())
}
}
}

impl Debug for FunctionDefinitionNode<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_maybe_alternate(&self.clone().value())
}
}

impl<'script> TryFrom<AnyNode<'script>> for FunctionDefinitionNode<'script> {
type Error = ();

fn try_from(value: AnyNode<'script>) -> Result<Self, Self::Error> {
if !value.tree_node.is_named() {
return Err(());
}

match value.tree_node.kind() {
FunctionBlockNode::NODE_KIND |
NopNode::NODE_KIND => Ok(value.into()),
_ => Err(())
}
}
}

impl StatementTraversal for FunctionDefinitionNode<'_> {
fn accept<V: StatementVisitor>(&self, visitor: &mut V) {
if let FunctionDefinition::Some(block) = self.clone().value() {
block.accept(visitor);
}
}
}



#[derive(Debug, Clone)]
pub struct FunctionParameterGroup;
Expand Down Expand Up @@ -407,6 +465,7 @@ impl<'script> TryFrom<AnyNode<'script>> for FunctionBlockNode<'script> {

impl StatementTraversal for FunctionBlockNode<'_> {
fn accept<V: StatementVisitor>(&self, visitor: &mut V) {
visitor.visit_block_stmt(self);
self.statements().for_each(|s| s.accept(visitor));
}
}
Expand Down
44 changes: 24 additions & 20 deletions crates/core/src/tokens/literals.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ impl<'script> TryFrom<AnyNode<'script>> for LiteralNullNode<'script> {
}


// Represents the unnamed $._literal node
#[derive(Clone, PartialEq)]
pub enum Literal<'script> {
Int(LiteralIntNode<'script>),
Expand All @@ -272,39 +273,42 @@ impl Debug for Literal<'_> {

pub type LiteralNode<'script> = SyntaxNode<'script, Literal<'script>>;

impl NamedSyntaxNode for LiteralNode<'_> {
const NODE_KIND: &'static str = "literal";
}

impl LiteralNode<'_> {
pub fn value(&self) -> Literal<'_> {
let child = self.first_child(true).unwrap();
match child.tree_node.kind() {
LiteralIntNode::NODE_KIND => Literal::Int(child.into()),
LiteralFloatNode::NODE_KIND => Literal::Float(child.into()),
LiteralBoolNode::NODE_KIND => Literal::Bool(child.into()),
LiteralStringNode::NODE_KIND => Literal::String(child.into()),
LiteralNameNode::NODE_KIND => Literal::Name(child.into()),
LiteralNullNode::NODE_KIND => Literal::Null(child.into()),
_ => panic!("Unknown literal type: {}", child.tree_node.kind())
impl<'script> LiteralNode<'script> {
pub fn value(self) -> Literal<'script> {
match self.tree_node.kind() {
LiteralIntNode::NODE_KIND => Literal::Int(self.into()),
LiteralFloatNode::NODE_KIND => Literal::Float(self.into()),
LiteralBoolNode::NODE_KIND => Literal::Bool(self.into()),
LiteralStringNode::NODE_KIND => Literal::String(self.into()),
LiteralNameNode::NODE_KIND => Literal::Name(self.into()),
LiteralNullNode::NODE_KIND => Literal::Null(self.into()),
_ => panic!("Unknown literal type: {}", self.tree_node.kind())
}
}
}

impl Debug for LiteralNode<'_> {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
f.debug_maybe_alternate(&self.value())
f.debug_maybe_alternate(&self.clone().value())
}
}

impl<'script> TryFrom<AnyNode<'script>> for LiteralNode<'script> {
type Error = ();

fn try_from(value: AnyNode<'script>) -> Result<Self, Self::Error> {
if value.tree_node.kind() == Self::NODE_KIND {
Ok(value.into())
} else {
Err(())
if !value.tree_node.is_named() {
return Err(());
}

match value.tree_node.kind() {
LiteralIntNode::NODE_KIND |
LiteralFloatNode::NODE_KIND |
LiteralBoolNode::NODE_KIND |
LiteralStringNode::NODE_KIND |
LiteralNameNode::NODE_KIND |
LiteralNullNode::NODE_KIND => Ok(value.into()),
_ => Err(())
}
}
}
Expand Down

0 comments on commit 965fc1e

Please sign in to comment.