From 7380c8d43fece32ac7991cb6e6b64b0fc720281f Mon Sep 17 00:00:00 2001 From: Bozhidar Date: Tue, 20 Aug 2024 21:34:07 +0300 Subject: [PATCH] support arguments on class methods call --- interpreter/interpreter.go | 8 -------- parser/ast.go | 8 ++++---- parser/parser.go | 40 ++++++++++++++++++++++++++++++-------- 3 files changed, 36 insertions(+), 20 deletions(-) diff --git a/interpreter/interpreter.go b/interpreter/interpreter.go index 2aea35e..2e23ad0 100644 --- a/interpreter/interpreter.go +++ b/interpreter/interpreter.go @@ -731,14 +731,6 @@ func (interp *interpreter) newInstance(className string, args []Value) *ClassObj } classObject := class.(*ClassObject) - // Create a new instance of the class - //instance := &ClassObject{ - // Name: classObject.Name, - // Parent: nil, - // Methods: classObject.Methods, - // Fields: make(map[string]Value), - //} - // Initialize fields or invoke constructor if necessary // Check if the class has a constructor method //if constructor, ok := classObject.Methods["constructor"]; ok { diff --git a/parser/ast.go b/parser/ast.go index 53195d8..8844db9 100644 --- a/parser/ast.go +++ b/parser/ast.go @@ -314,10 +314,10 @@ func (e *PropertyAccess) Position() Position { return e.pos } // MethodCall represents a method call on an object, e.g., `$object->method(arg1, arg2)` type MethodCall struct { - pos Position // Position of the `->` operator in the source code - Object Expression // The object on which the method is being called - Method string // The name of the method being called - Arguments []string // Arguments passed to the method + pos Position // Position of the `->` operator in the source code + Object Expression // The object on which the method is being called + Method string // The name of the method being called + Arguments []Expression // Arguments passed to the method } func (e *MethodCall) expressionNode() {} diff --git a/parser/parser.go b/parser/parser.go index bb6f8e0..41d89d4 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -96,10 +96,39 @@ func (p *parser) statement() Statement { pos = p.pos p.expect(OBJECT_OPERATOR) + methodName := p.val p.expect(NAME) - args, _ := p.params() - expr = &MethodCall{pos, expr, p.val, args} + if p.tok == LPAREN { + pos := p.pos + p.next() + args := []Expression{} + gotComma := true + gotEllipsis := false + for p.tok != RPAREN && p.tok != EOF && !gotEllipsis { + if !gotComma { + p.error("expected , between arguments") + } + arg := p.expression() + args = append(args, arg) + if p.tok == ELLIPSIS { + gotEllipsis = true + p.next() + } + if p.tok == COMMA { + gotComma = true + p.next() + } else { + gotComma = false + } + } + if p.tok != RPAREN && gotEllipsis { + p.error("can only have ... after last argument") + } + p.expect(RPAREN) + + expr = &MethodCall{pos, expr, methodName, args} + } return &ExpressionStatement{pos, expr} @@ -235,8 +264,8 @@ func (p *parser) params() ([]string, bool) { if !gotComma { p.error("expected , between parameters") } - param := p.val p.expect(DOLLAR) + param := p.val p.expect(NAME) params = append(params, param) if p.tok == ELLIPSIS { @@ -358,11 +387,6 @@ func (p *parser) call() Expression { p.error("can only have ... after last argument") } p.expect(RPAREN) - //if p.tok == SEMI { - // p.expect(SEMI) - //} else { - // print(p.tok) - //} expr = &Call{pos, expr, args, gotEllipsis} } else if p.tok == LBRACKET {