From 040c03467be636aab67964081c66611fc295c29d Mon Sep 17 00:00:00 2001 From: Mattias Hansson Date: Fri, 21 Nov 2025 10:59:51 +0100 Subject: [PATCH] Fixed to function without params can be called as myfunction() with empty parens --- commands.md | 5 +++- internal/compiler/funchandler.go | 3 ++ internal/compiler/funchandler_test.go | 43 +++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 1 deletion(-) diff --git a/commands.md b/commands.md index b7e2dd9..502e00f 100644 --- a/commands.md +++ b/commands.md @@ -91,12 +91,15 @@ Calls a function with optional arguments. **Syntax:** ``` -([,[,...]]) + +() +([,,...]) ``` **Examples:** ``` initialize +initialize() setColor(1,14) drawSprite(xpos,ypos,@spriteData) process("hello",42,myvar) diff --git a/internal/compiler/funchandler.go b/internal/compiler/funchandler.go index 70a2f23..40b935a 100644 --- a/internal/compiler/funchandler.go +++ b/internal/compiler/funchandler.go @@ -246,6 +246,9 @@ func (fh *FunctionHandler) HandleFuncCall(line preproc.Line) ([]string, error) { if len(params) == funcNameIdx+1 { // No arguments: funcname or CALL funcname callArgs = []string{} + } else if len(params) == funcNameIdx+3 && params[funcNameIdx+1] == "(" && params[funcNameIdx+2] == ")" { + // Empty parens: funcname() or CALL funcname() + callArgs = []string{} } else if len(params) >= funcNameIdx+4 { // funcname ( arg1 arg2 ) or CALL funcname ( arg1 arg2 ) if params[funcNameIdx+1] != "(" || params[len(params)-1] != ")" { diff --git a/internal/compiler/funchandler_test.go b/internal/compiler/funchandler_test.go index 03d11ac..ad27d9c 100644 --- a/internal/compiler/funchandler_test.go +++ b/internal/compiler/funchandler_test.go @@ -638,6 +638,49 @@ func TestHandleFuncCall_Errors(t *testing.T) { } } +func TestHandleFuncCall_EmptyParens(t *testing.T) { + st := NewSymbolTable() + ls := NewLabelStack("L") + csh := NewConstantStringHandler() + pragma := preproc.NewPragma() + fh := NewFunctionHandler(st, ls, csh, pragma) + + // Declare void function + fh.HandleFuncDecl(makeLine("FUNC init")) + + tests := []struct { + name string + line string + }{ + {"naked call", "init"}, + {"empty parens", "init()"}, + {"CALL keyword", "CALL init"}, + {"CALL with parens", "CALL init()"}, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + asm, err := fh.HandleFuncCall(makeLine(tt.line)) + if err != nil { + t.Fatalf("HandleFuncCall failed: %v", err) + } + + // Should have JSR instruction + foundJSR := false + for _, line := range asm { + if strings.Contains(line, "jsr init") { + foundJSR = true + break + } + } + + if !foundJSR { + t.Error("missing jsr instruction") + } + }) + } +} + func TestEndFunction(t *testing.T) { st := NewSymbolTable() ls := NewLabelStack("L")