You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

74 lines
1.8 KiB
Go

package interpreter
import "golox/ast"
// callable is an interface for callables like functions and methods.
type callable interface {
arity() int
call(i *Interpreter, arguments []any) any
}
// nativeCallable is a struct that implements the callable interface.
type nativeCallable struct {
arityFn func() int
callFn func(interpreter *Interpreter, args []any) any
}
// newNativeCallable creates a new nativeCallable.
func newNativeCallable(arityFn func() int, callFn func(interpreter *Interpreter, args []any) any) *nativeCallable {
return &nativeCallable{
arityFn: arityFn,
callFn: callFn,
}
}
// arity returns the number of arguments the callable expects.
func (n *nativeCallable) arity() int {
return n.arityFn()
}
// call calls the callable with the given arguments.
func (n *nativeCallable) call(i *Interpreter, arguments []any) any {
return n.callFn(i, arguments)
}
// String returns a string representation of the callable.
func (n *nativeCallable) String() string {
return "<native fn>"
}
// function is a struct that implements the callable interface.
type function struct {
declaration *ast.FunctionStmt
}
// newFunction creates a new function.
func newFunction(declaration *ast.FunctionStmt) *function {
return &function{
declaration: declaration,
}
}
// arity returns the number of arguments the function expects.
func (f *function) arity() int {
return len(f.declaration.Params)
}
// call calls the function with the given arguments.
func (f *function) call(i *Interpreter, arguments []any) any {
env := newEnvironment(i.globals)
for i, param := range f.declaration.Params {
env.define(param.Lexeme, arguments[i])
}
i.executeBlock(f.declaration.Body, env)
return nil
}
// String returns a string representation of the function.
func (f *function) String() string {
return "<fn " + f.declaration.Name.Lexeme + ">"
}