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()
println 42
println(42)
end

View File

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

View File

@ -9,11 +9,11 @@ fn getWorlds() -> List<World> = [
fn findWorldByColor(worlds: List<World>, 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

View File

@ -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);
}
}
}

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::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(

View File

@ -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<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(
d_string: &mut DString,
symbol_table: &mut SymbolTable,

View File

@ -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:

View File

@ -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*