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