Fixed to function without params can be called as myfunction() with empty parens

This commit is contained in:
Mattias Hansson 2025-11-21 10:59:51 +01:00
parent 834548d7b9
commit 040c03467b
3 changed files with 50 additions and 1 deletions

View file

@ -91,12 +91,15 @@ Calls a function with optional arguments.
**Syntax:** **Syntax:**
``` ```
<funcname>([<param1>,[<param2>,...]]) <funcname>
<funcname>()
<funcname>(<param1>[,<param2>,...])
``` ```
**Examples:** **Examples:**
``` ```
initialize initialize
initialize()
setColor(1,14) setColor(1,14)
drawSprite(xpos,ypos,@spriteData) drawSprite(xpos,ypos,@spriteData)
process("hello",42,myvar) process("hello",42,myvar)

View file

@ -246,6 +246,9 @@ func (fh *FunctionHandler) HandleFuncCall(line preproc.Line) ([]string, error) {
if len(params) == funcNameIdx+1 { if len(params) == funcNameIdx+1 {
// No arguments: funcname or CALL funcname // No arguments: funcname or CALL funcname
callArgs = []string{} 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 { } else if len(params) >= funcNameIdx+4 {
// funcname ( arg1 arg2 ) or CALL funcname ( arg1 arg2 ) // funcname ( arg1 arg2 ) or CALL funcname ( arg1 arg2 )
if params[funcNameIdx+1] != "(" || params[len(params)-1] != ")" { if params[funcNameIdx+1] != "(" || params[len(params)-1] != ")" {

View file

@ -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) { func TestEndFunction(t *testing.T) {
st := NewSymbolTable() st := NewSymbolTable()
ls := NewLabelStack("L") ls := NewLabelStack("L")