2024-10-09 19:57:52 +03:00
|
|
|
package main
|
|
|
|
|
2024-10-12 00:09:25 +03:00
|
|
|
type Callable interface {
|
|
|
|
arity() int
|
|
|
|
call(i *Interpreter, args ...any) (ret any)
|
2024-10-09 19:57:52 +03:00
|
|
|
}
|
2024-10-09 23:36:18 +03:00
|
|
|
|
2024-10-12 00:09:25 +03:00
|
|
|
type Function struct {
|
|
|
|
definition *FunStmt
|
|
|
|
closure *Environment
|
|
|
|
}
|
2024-10-11 17:01:12 +03:00
|
|
|
|
2024-10-12 00:09:25 +03:00
|
|
|
func (f *Function) call(i *Interpreter, args ...any) (ret any) {
|
2024-10-11 17:01:12 +03:00
|
|
|
|
2024-10-12 00:09:25 +03:00
|
|
|
defer func() {
|
|
|
|
if err := recover(); err != nil {
|
|
|
|
re, ok := err.(Return)
|
2024-10-09 23:36:18 +03:00
|
|
|
|
2024-10-12 00:09:25 +03:00
|
|
|
if !ok {
|
|
|
|
panic(err)
|
2024-10-09 23:36:18 +03:00
|
|
|
}
|
|
|
|
|
2024-10-12 00:09:25 +03:00
|
|
|
ret = re.val
|
|
|
|
}
|
|
|
|
}()
|
2024-10-09 23:36:18 +03:00
|
|
|
|
2024-10-12 00:09:25 +03:00
|
|
|
env := newEnvironment(f.closure)
|
|
|
|
|
|
|
|
for idx, arg := range f.definition.args {
|
|
|
|
env.define(arg.lexeme, args[idx])
|
2024-10-09 23:36:18 +03:00
|
|
|
}
|
2024-10-12 00:09:25 +03:00
|
|
|
|
|
|
|
i.executeBlock(f.definition.body, env)
|
|
|
|
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (f *Function) arity() int {
|
|
|
|
return len(f.definition.args)
|
|
|
|
}
|
|
|
|
|
|
|
|
func newFunction(fun *FunStmt, env *Environment) Callable {
|
|
|
|
return &Function{fun, env}
|
2024-10-09 23:36:18 +03:00
|
|
|
}
|