module support
Some checks failed
Build / build (push) Successful in 10m22s
Test / build (push) Failing after 15m54s

This commit is contained in:
Chuck Smith
2024-03-26 16:49:38 -04:00
parent 6d234099d1
commit 110152a139
21 changed files with 541 additions and 100 deletions

View File

@@ -4,7 +4,11 @@ import (
"fmt"
"monkey/ast"
"monkey/builtins"
"monkey/lexer"
"monkey/object"
"monkey/parser"
"monkey/utils"
"os"
"strings"
)
@@ -40,6 +44,9 @@ func Eval(node ast.Node, env *object.Environment) object.Object {
case *ast.WhileExpression:
return evalWhileExpression(node, env)
case *ast.ImportExpression:
return evalImportExpression(node, env)
case *ast.ReturnStatement:
val := Eval(node.ReturnValue, env)
if isError(val) {
@@ -190,6 +197,22 @@ func Eval(node ast.Node, env *object.Environment) object.Object {
return nil
}
func evalImportExpression(ie *ast.ImportExpression, env *object.Environment) object.Object {
name := Eval(ie.Name, env)
if isError(name) {
return name
}
if s, ok := name.(*object.String); ok {
attrs := EvalModule(s.Value)
if isError(attrs) {
return attrs
}
return &object.Module{Name: s.Value, Attrs: attrs}
}
return newError("ImportError: invalid import path '%s'", name)
}
func evalWhileExpression(we *ast.WhileExpression, env *object.Environment) object.Object {
var result object.Object
@@ -208,9 +231,9 @@ func evalWhileExpression(we *ast.WhileExpression, env *object.Environment) objec
if result != nil {
return result
} else {
return NULL
}
return NULL
}
func evalProgram(program *ast.Program, env *object.Environment) object.Object {
@@ -485,6 +508,29 @@ func newError(format string, a ...interface{}) *object.Error {
return &object.Error{Message: fmt.Sprintf(format, a...)}
}
// EvalModule evaluates the named module and returns a *object.Module objec
func EvalModule(name string) object.Object {
filename := utils.FindModule(name)
b, err := os.ReadFile(filename)
if err != nil {
return newError("IOError: error reading module '%s': %s", name, err)
}
l := lexer.New(string(b))
p := parser.New(l)
module := p.ParseProgram()
if len(p.Errors()) != 0 {
return newError("ParseError: %s", p.Errors())
}
env := object.NewEnvironment()
Eval(module, env)
return env.ExportedHash()
}
func evalIdentifier(node *ast.Identifier, env *object.Environment) object.Object {
if val, ok := env.Get(node.Value); ok {
return val
@@ -557,11 +603,18 @@ func evalIndexExpression(left, index object.Object) object.Object {
return evalArrayIndexExpression(left, index)
case left.Type() == object.HASH_OBJ:
return evalHashIndexExpression(left, index)
case left.Type() == object.MODULE_OBJ:
return EvalModuleIndexExpression(left, index)
default:
return newError("index operator not supported: %s", left.Type())
}
}
func EvalModuleIndexExpression(module, index object.Object) object.Object {
moduleObject := module.(*object.Module)
return evalHashIndexExpression(moduleObject.Attrs, index)
}
func evalStringIndexExpression(str, index object.Object) object.Object {
stringObject := str.(*object.String)
idx := index.(*object.Integer).Value