Fixed spacing for suffix operators. Now calls require at least one of parentheses and/or closure.

This commit is contained in:
Jesse Brault 2025-11-03 14:42:41 -06:00
parent 51c39f5f34
commit 7439ca554c
9 changed files with 104 additions and 46 deletions

4
examples/array_return.dm Normal file
View File

@ -0,0 +1,4 @@
fn test()
println(42)
[0, 1, 2]
end

View File

@ -1,3 +1,3 @@
fn main() fn main()
println 42 println(42)
end end

View File

@ -1,4 +1,4 @@
fn main() fn main()
let n = 1 + 2 * 3 + 4 let n = 1 + 2 * 3 + 4
println n println(n)
end end

View File

@ -9,11 +9,11 @@ fn getWorlds() -> List<World> = [
fn findWorldByColor(worlds: List<World>, color: String) -> String fn findWorldByColor(worlds: List<World>, color: String) -> String
worlds.find { it -> it.color == color } worlds.find { it -> it.color == color }
.map { it -> it.name } .map { it -> it.name }
.expect "No world has the given color ${color}" .expect("No world has the given color ${color}")
end end
fn main() fn main()
let worlds = getWorlds() let worlds = getWorlds()
let blueWorld = findWorldByColor(worlds, 'Blue') let blueWorld = findWorldByColor(worlds, 'Blue')
println "Hello, ${blueWorld}!" println("Hello, ${blueWorld}!")
end end

View File

@ -178,8 +178,8 @@ pub mod build {
Rule::Function, Rule::Function,
" "
fn test() fn test()
println 42 println(42)
println 43 println(43)
end end
", ",
); );
@ -196,6 +196,54 @@ pub mod build {
assert_eq!(2, number_of_statements, "Ast: {}", fmt_ast(&function)); 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);
}
} }
} }

View File

@ -12,7 +12,6 @@ use crate::name_analysis::symbol::use_symbol::{ConcreteUseSymbol, StarUseSymbol}
use crate::name_analysis::symbol_table::SymbolTable; use crate::name_analysis::symbol_table::SymbolTable;
use crate::name_analysis::util::{handle_insert_error, join_fqn_parts}; use crate::name_analysis::util::{handle_insert_error, join_fqn_parts};
use std::cell::RefCell; use std::cell::RefCell;
use std::process::id;
use std::rc::Rc; use std::rc::Rc;
pub fn na_p1_compilation_unit( pub fn na_p1_compilation_unit(

View File

@ -1,13 +1,4 @@
use crate::ast::node::{ 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};
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::diagnostic::DmDiagnostic; use crate::diagnostic::DmDiagnostic;
use crate::name_analysis::symbol::source_definition::SourceDefinition; use crate::name_analysis::symbol::source_definition::SourceDefinition;
use crate::name_analysis::symbol::variable_symbol::VariableSymbol; 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); na_p2_expression_list(expression_list, symbol_table, diagnostics);
} }
if let Some(closure) = parentheses_call.closure_mut() { if let Some(closure) = parentheses_call.closure_mut() {
na_p2_closure(closure, symbol_table, diagnostics);
}
}
Call::ClosureOnlyCall(closure_only_call) => {
if let Some(turbo_fish) = closure_only_call.turbo_fish_mut() {
todo!() todo!()
} }
} na_p2_closure(closure_only_call.closure_mut(), 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() {
todo!()
}
} }
} }
} }
@ -794,6 +780,27 @@ fn na_p2_literal(
} }
} }
fn na_p2_closure(
closure: &mut Closure,
symbol_table: &mut SymbolTable,
diagnostics: &mut Vec<DmDiagnostic>,
) {
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<DmDiagnostic>,
) {
for closure_parameter in closure_parameters.parameters_mut() {
todo!()
}
}
fn na_p2_d_string( fn na_p2_d_string(
d_string: &mut DString, d_string: &mut DString,
symbol_table: &mut SymbolTable, symbol_table: &mut SymbolTable,

View File

@ -1229,7 +1229,7 @@ Call:
tree_enum: tree_enum:
rules: rules:
- ParenthesesCall - ParenthesesCall
- NonParenthesesCall - ClosureOnlyCall
ParenthesesCall: ParenthesesCall:
struct: struct:
children: children:
@ -1242,18 +1242,13 @@ ParenthesesCall:
- closure: - closure:
member: member:
optional: true optional: true
NonParenthesesCall: ClosureOnlyCall:
struct: struct:
children: children:
- turbo_fish: - turbo_fish:
member: member:
optional: true optional: true
- expression_list: - closure
member:
optional: true
- closure:
member:
optional: true
TurboFish: TurboFish:
struct: struct:
children: children:

View File

@ -260,7 +260,7 @@ FunctionTypeUse = {
// Generic Arguments // Generic Arguments
GenericArguments = !{ GenericArguments = {
"<" "<"
~ TypeUseList ~ TypeUseList
~ ">" ~ ">"
@ -812,7 +812,7 @@ ParenthesizedExpression = {
Call = { Call = {
ParenthesesCall ParenthesesCall
| NonParenthesesCall | ClosureOnlyCall
} }
ParenthesesCall = { ParenthesesCall = {
@ -823,29 +823,34 @@ ParenthesesCall = {
~ Closure? ~ Closure?
} }
NonParenthesesCall = ${ ClosureOnlyCall = {
TurboFish? TurboFish?
~ ( " " | "\t" )* ~ Closure
~ (
Closure
| ExpressionList
| ExpressionList ~ ( " " | "\t" )* ~ Closure
)
} }
TurboFish = ${ // NonParenthesesCall = ${
// TurboFish?
// ~ ( " " | "\t" )*
// ~ (
// Closure
// | ExpressionList
// | ExpressionList ~ ( " " | "\t" )* ~ Closure
// )
// }
TurboFish = {
"::" "::"
~ GenericArguments ~ GenericArguments
} }
ExpressionList = !{ ExpressionList = {
Expression Expression
~ ( "," ~ Expression )* ~ ( "," ~ Expression )*
} }
// Closure // Closure
Closure = !{ Closure = {
"{" "{"
~ ( ClosureParameters? ~ "->" )? ~ ( ClosureParameters? ~ "->" )?
~ Statement* ~ Statement*