From 7439ca554cc6a7c14770f3ac65f91dd79ba53ca1 Mon Sep 17 00:00:00 2001 From: Jesse Brault Date: Mon, 3 Nov 2025 14:42:41 -0600 Subject: [PATCH] Fixed spacing for suffix operators. Now calls require at least one of parentheses and/or closure. --- examples/array_return.dm | 4 +++ examples/forty_two.dm | 2 +- examples/op_prec.dm | 2 +- examples/worlds.dm | 4 +-- src/ast/mod.rs | 52 ++++++++++++++++++++++++++++++-- src/name_analysis/first_pass.rs | 1 - src/name_analysis/second_pass.rs | 45 +++++++++++++++------------ src/parser/ast.yaml | 11 ++----- src/parser/deimos.pest | 29 ++++++++++-------- 9 files changed, 104 insertions(+), 46 deletions(-) create mode 100644 examples/array_return.dm diff --git a/examples/array_return.dm b/examples/array_return.dm new file mode 100644 index 0000000..30dbb4b --- /dev/null +++ b/examples/array_return.dm @@ -0,0 +1,4 @@ +fn test() + println(42) + [0, 1, 2] +end \ No newline at end of file diff --git a/examples/forty_two.dm b/examples/forty_two.dm index 8fdb45b..844c4da 100644 --- a/examples/forty_two.dm +++ b/examples/forty_two.dm @@ -1,3 +1,3 @@ fn main() - println 42 + println(42) end \ No newline at end of file diff --git a/examples/op_prec.dm b/examples/op_prec.dm index 9f6a953..200f48a 100644 --- a/examples/op_prec.dm +++ b/examples/op_prec.dm @@ -1,4 +1,4 @@ fn main() let n = 1 + 2 * 3 + 4 - println n + println(n) end \ No newline at end of file diff --git a/examples/worlds.dm b/examples/worlds.dm index 86dec34..25c90d3 100644 --- a/examples/worlds.dm +++ b/examples/worlds.dm @@ -9,11 +9,11 @@ fn getWorlds() -> List = [ fn findWorldByColor(worlds: List, color: String) -> String worlds.find { it -> it.color == color } .map { it -> it.name } - .expect "No world has the given color ${color}" + .expect("No world has the given color ${color}") end fn main() let worlds = getWorlds() let blueWorld = findWorldByColor(worlds, 'Blue') - println "Hello, ${blueWorld}!" + println("Hello, ${blueWorld}!") end diff --git a/src/ast/mod.rs b/src/ast/mod.rs index 632ca3a..c0c2416 100644 --- a/src/ast/mod.rs +++ b/src/ast/mod.rs @@ -178,8 +178,8 @@ pub mod build { Rule::Function, " fn test() - println 42 - println 43 + println(42) + println(43) end ", ); @@ -196,6 +196,54 @@ pub mod build { assert_eq!(2, number_of_statements, "Ast: {}", fmt_ast(&function)); } + + #[test] + fn array_return_after_statement() { + let pair = parse( + Rule::Function, + " + fn test() + println(42) + [0, 1, 2] + end + ", + ); + let function = build_function(0, pair); + + let mut number_of_statements = 0; + + walk_depth_first(&function, &mut |node| { + if let AstNodeRef::Statement(stmt) = node { + number_of_statements += 1; + } + }); + + assert_eq!(2, number_of_statements); + } + + #[test] + fn array_return_after_bare_identifier() { + // The following should parse as two expression statements + let pair = parse( + Rule::Function, + " + fn test() + x + [0, 1, 2] + end + ", + ); + let function = build_function(0, pair); + + let mut number_of_statements = 0; + walk_depth_first(&function, &mut |node| { + if let AstNodeRef::Statement(stmt) = node { + number_of_statements += 1; + } + }); + + assert_eq!(2, number_of_statements); + } } } diff --git a/src/name_analysis/first_pass.rs b/src/name_analysis/first_pass.rs index f8f775e..31866a5 100644 --- a/src/name_analysis/first_pass.rs +++ b/src/name_analysis/first_pass.rs @@ -12,7 +12,6 @@ use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol} use crate::name_analysis::symbol_table::SymbolTable; use crate::name_analysis::util::{handle_insert_error, join_fqn_parts}; use std::cell::RefCell; -use std::process::id; use std::rc::Rc; pub fn na_p1_compilation_unit( diff --git a/src/name_analysis/second_pass.rs b/src/name_analysis/second_pass.rs index d5787a4..bcffad1 100644 --- a/src/name_analysis/second_pass.rs +++ b/src/name_analysis/second_pass.rs @@ -1,13 +1,4 @@ -use crate::ast::node::{ - AnySpaceSuffixOperator, AssignmentStatement, BacktickString, BoundSuffixOperator, Call, - CompilationUnit, ConcreteUseStatement, ConcreteUseStatementSuffix, DString, Expression, - ExpressionList, ExpressionStatement, Function, FunctionAliasBody, FunctionBlockBody, - FunctionBody, FunctionEqualsBody, GenericParameters, Identifier, IdentifierExpression, - IdentifierOrFqn, LValue, LValueSuffix, Literal, ModuleLevelDeclaration, - NoNewlineSuffixOperator, ObjectIndex, Parameter, Parameters, PlatformFunction, PrimitiveType, - ReturnType, StarUseStatement, Statement, SuffixExpression, SuffixOperator, TypeUse, TypedArray, - UseStatement, UseStatementIdentifier, UseStatementPrefix, VariableDeclaration, -}; +use crate::ast::node::{AnySpaceSuffixOperator, AssignmentStatement, BacktickString, BoundSuffixOperator, Call, Closure, ClosureParameters, CompilationUnit, ConcreteUseStatement, ConcreteUseStatementSuffix, DString, Expression, ExpressionList, ExpressionStatement, Function, FunctionAliasBody, FunctionBlockBody, FunctionBody, FunctionEqualsBody, GenericParameters, Identifier, IdentifierExpression, IdentifierOrFqn, LValue, LValueSuffix, Literal, ModuleLevelDeclaration, NoNewlineSuffixOperator, ObjectIndex, Parameter, Parameters, PlatformFunction, PrimitiveType, ReturnType, StarUseStatement, Statement, SuffixExpression, SuffixOperator, TypeUse, TypedArray, UseStatement, UseStatementIdentifier, UseStatementPrefix, VariableDeclaration}; use crate::diagnostic::DmDiagnostic; use crate::name_analysis::symbol::source_definition::SourceDefinition; use crate::name_analysis::symbol::variable_symbol::VariableSymbol; @@ -728,19 +719,14 @@ fn na_p2_call( na_p2_expression_list(expression_list, symbol_table, diagnostics); } if let Some(closure) = parentheses_call.closure_mut() { - todo!() + na_p2_closure(closure, symbol_table, diagnostics); } } - Call::NonParenthesesCall(non_parentheses_call) => { - if let Some(turbo_fish) = non_parentheses_call.turbo_fish_mut() { - todo!() - } - if let Some(expression_list) = non_parentheses_call.expression_list_mut() { - na_p2_expression_list(expression_list, symbol_table, diagnostics); - } - if let Some(closure) = non_parentheses_call.closure_mut() { + Call::ClosureOnlyCall(closure_only_call) => { + if let Some(turbo_fish) = closure_only_call.turbo_fish_mut() { todo!() } + na_p2_closure(closure_only_call.closure_mut(), symbol_table, diagnostics); } } } @@ -794,6 +780,27 @@ fn na_p2_literal( } } +fn na_p2_closure( + closure: &mut Closure, + symbol_table: &mut SymbolTable, + diagnostics: &mut Vec, +) { + na_p2_closure_parameters(closure.closure_parameters_mut(), symbol_table, diagnostics); + for statement in closure.statements_mut() { + na_p2_statement(statement, symbol_table, diagnostics); + } +} + +fn na_p2_closure_parameters( + closure_parameters: &mut ClosureParameters, + symbol_table: &mut SymbolTable, + diagnostics: &mut Vec, +) { + for closure_parameter in closure_parameters.parameters_mut() { + todo!() + } +} + fn na_p2_d_string( d_string: &mut DString, symbol_table: &mut SymbolTable, diff --git a/src/parser/ast.yaml b/src/parser/ast.yaml index 26891c6..375cab4 100644 --- a/src/parser/ast.yaml +++ b/src/parser/ast.yaml @@ -1229,7 +1229,7 @@ Call: tree_enum: rules: - ParenthesesCall - - NonParenthesesCall + - ClosureOnlyCall ParenthesesCall: struct: children: @@ -1242,18 +1242,13 @@ ParenthesesCall: - closure: member: optional: true -NonParenthesesCall: +ClosureOnlyCall: struct: children: - turbo_fish: member: optional: true - - expression_list: - member: - optional: true - - closure: - member: - optional: true + - closure TurboFish: struct: children: diff --git a/src/parser/deimos.pest b/src/parser/deimos.pest index 0abceac..d7da13a 100644 --- a/src/parser/deimos.pest +++ b/src/parser/deimos.pest @@ -260,7 +260,7 @@ FunctionTypeUse = { // Generic Arguments -GenericArguments = !{ +GenericArguments = { "<" ~ TypeUseList ~ ">" @@ -812,7 +812,7 @@ ParenthesizedExpression = { Call = { ParenthesesCall - | NonParenthesesCall + | ClosureOnlyCall } ParenthesesCall = { @@ -823,29 +823,34 @@ ParenthesesCall = { ~ Closure? } -NonParenthesesCall = ${ +ClosureOnlyCall = { TurboFish? - ~ ( " " | "\t" )* - ~ ( - Closure - | ExpressionList - | ExpressionList ~ ( " " | "\t" )* ~ Closure - ) + ~ Closure } -TurboFish = ${ +// NonParenthesesCall = ${ +// TurboFish? +// ~ ( " " | "\t" )* +// ~ ( +// Closure +// | ExpressionList +// | ExpressionList ~ ( " " | "\t" )* ~ Closure +// ) +// } + +TurboFish = { "::" ~ GenericArguments } -ExpressionList = !{ +ExpressionList = { Expression ~ ( "," ~ Expression )* } // Closure -Closure = !{ +Closure = { "{" ~ ( ClosureParameters? ~ "->" )? ~ Statement*