Add functions
parent
41bf68b685
commit
7da761a4de
@ -1 +1 @@
|
||||
ef159c739c079a54bc5f6af10e2ea025
|
||||
8ad203c83fd99fe71ecaa9da9795cc32
|
||||
|
||||
@ -0,0 +1,73 @@
|
||||
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 + ">"
|
||||
}
|
||||
@ -0,0 +1,13 @@
|
||||
var t1 = clock();
|
||||
|
||||
fun sayHi(first, last) {
|
||||
print "Hi, " + first + " " + last + "!";
|
||||
}
|
||||
|
||||
sayHi("Dear", "Reader");
|
||||
|
||||
var t2 = clock();
|
||||
|
||||
print t1;
|
||||
print t2;
|
||||
print t1 - t2;
|
||||
Loading…
Reference in New Issue