diff --git a/evaluator/evaluator.go b/evaluator/evaluator.go index 9f27000..514c4da 100644 --- a/evaluator/evaluator.go +++ b/evaluator/evaluator.go @@ -17,6 +17,7 @@ import ( // Eval evaluates the node and returns an object func Eval(node ast.Node, env *object.Environment) object.Object { + switch node := node.(type) { // Statements @@ -125,22 +126,26 @@ func Eval(node ast.Node, env *object.Environment) object.Object { case *ast.ImportExpression: return evalImportExpression(node, env) case *ast.CallExpression: - function := Eval(node.Callable, env) + return evalCallExpression(node, env) + } - if error.IsError(function) { - return function - } + return nil +} - arguments := evalExpressions(node.Arguments, env) +func evalCallExpression(node *ast.CallExpression, env *object.Environment) object.Object { + function := Eval(node.Callable, env) - if len(arguments) == 1 && error.IsError(arguments[0]) { - return arguments[0] - } + if error.IsError(function) { + return function + } + + arguments := evalExpressions(node.Arguments, env) - return applyFunction(node.Token, function, env, arguments) + if len(arguments) == 1 && error.IsError(arguments[0]) { + return arguments[0] } - return nil + return applyFunction(node.Token, function, env, arguments) } // EvalPackage evaluates the specified ghost file and returns an object. @@ -802,7 +807,34 @@ func evalMethodExpression(me *ast.MethodExpression, env *object.Environment) obj return args[0] } - return obj.CallMethod(me.Method.String(), args) + result := obj.CallMethod(me.Method.String(), args) + + if (! error.IsError(result)) { + return result + } + + err := result + + // We don't have a built in method, so do we have an invokable function? + switch obj.(type) { + case *object.Map: + // return evalMapIndexExpression(me.Token.Line, obj, &object.String{Value: me.Method.String()}) + key := &object.String{Value: me.Method.String()} + + mapObject := obj.(*object.Map) + + pair, ok := mapObject.Pairs[key.MapKey()] + + if !ok { + return value.NULL + } + + function := pair.Value + + return applyFunction(me.Token, function, env, args) + } + + return err } func applyFunction(tok token.Token, fn object.Object, env *object.Environment, arguments []object.Object) object.Object { diff --git a/examples/object.ghost b/examples/object.ghost index 2d0db1e..3080d54 100644 --- a/examples/object.ghost +++ b/examples/object.ghost @@ -1,19 +1,7 @@ -function Person(name, age) { - self := {} +self := {} - self.name := name - self.age := age - - self.greet := function() { - print("Hello, " + self.name + ".") - } - - // self.age := function() { - // print(self.name + " is " + self.age + " years old.") - // } - - return self +self.test := function() { + print("test!!!") } -person := Person("Kai", 31) -print(person.name) \ No newline at end of file +self.test() \ No newline at end of file diff --git a/parser/parser.go b/parser/parser.go index 7766357..d91cafc 100644 --- a/parser/parser.go +++ b/parser/parser.go @@ -725,10 +725,6 @@ func (p *Parser) parseAssignStatement() ast.Statement { p.nextToken() } - if fl, ok := statement.Value.(*ast.FunctionLiteral); ok { - fl.Name = statement.Name.Value - } - return statement } @@ -742,10 +738,6 @@ func (p *Parser) parseAssignStatement() ast.Statement { p.nextToken() } - if fl, ok := statement.Value.(*ast.FunctionLiteral); ok { - fl.Name = statement.Name.Value - } - return statement } } @@ -764,10 +756,6 @@ func (p *Parser) parseAssignStatement() ast.Statement { p.nextToken() } - if fl, ok := statement.Value.(*ast.FunctionLiteral); ok { - fl.Name = statement.Name.Value - } - return statement }