Skip to content

Commit

Permalink
di: enable to define native modules
Browse files Browse the repository at this point in the history
  • Loading branch information
Syuparn committed Jun 10, 2023
1 parent 88d6677 commit 4987d72
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 7 deletions.
27 changes: 23 additions & 4 deletions di/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"path/filepath"
"strings"

"github.com/Syuparn/pangaea/native"
"github.com/Syuparn/pangaea/object"
"github.com/Syuparn/pangaea/parser"
"github.com/Syuparn/pangaea/props/modules"
Expand Down Expand Up @@ -141,11 +142,29 @@ func readSourceFile(env *object.Env, importPath string) (io.Reader, string, *obj
}

func injectStandardModule(env *object.Env, importPath string) object.PanObject {
m, ok := modules.Modules[importPath]
if !ok {
return object.NewFileNotFoundErr(fmt.Sprintf("module %q is not defined", importPath))
// find built-in
if m, ok := modules.Modules[importPath]; ok {
modules.InjectTo(env, m())
return env.Items()
}

// find native otherwise
return injectNativeStandardModule(env, importPath)
}

func injectNativeStandardModule(env *object.Env, importPath string) object.PanObject {
filePath := fmt.Sprintf("modules/%s.pangaea", importPath)

fp, err := native.FS.Open(filePath)
if err != nil {
return object.NewFileNotFoundErr(fmt.Sprintf("failed to read native module %q: %s", importPath, err))
}
defer fp.Close()

result := eval(parser.NewReader(fp, importPath), env)
if result.Type() == object.ErrType {
return result
}

modules.InjectTo(env, m())
return env.Items()
}
14 changes: 12 additions & 2 deletions di/import_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,12 @@ func TestEvalKernelImport(t *testing.T) {
object.GetSymHash("message"): {Key: object.NewPanStr("message"), Value: object.NewPanStr("This is a dummy module.")},
}),
},
{
`import("dummy_native")`,
object.PanObjInstancePtr(&map[object.SymHash]object.Pair{
object.GetSymHash("message"): {Key: object.NewPanStr("message"), Value: object.NewPanStr("This is a dummy module.")},
}),
},
}

for _, tt := range tests {
Expand Down Expand Up @@ -88,7 +94,7 @@ func TestEvalKernelImportError(t *testing.T) {
},
{
`import("notfound")`,
object.NewFileNotFoundErr("module \"notfound\" is not defined"),
object.NewFileNotFoundErr("failed to read native module \"notfound\": open modules/notfound.pangaea: file does not exist"),
},
}

Expand Down Expand Up @@ -137,6 +143,10 @@ func TestEvalKernelInvite(t *testing.T) {
`invite!("dummy"); message`,
object.NewPanStr("This is a dummy module."),
},
{
`invite!("dummy_native"); message`,
object.NewPanStr("This is a dummy module."),
},
}

for _, tt := range tests {
Expand Down Expand Up @@ -174,7 +184,7 @@ func TestEvalKernelInviteError(t *testing.T) {
},
{
`invite!("notfound")`,
object.NewFileNotFoundErr("module \"notfound\" is not defined"),
object.NewFileNotFoundErr("failed to read native module \"notfound\": open modules/notfound.pangaea: file does not exist"),
},
}

Expand Down
3 changes: 2 additions & 1 deletion native/fs.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,5 +7,6 @@ import (
// FS exports current directory file system.
// NOTE: FS must not be declared in di package because
// path root of unittest differs from runtime one!
//go:embed *.pangaea testdata/*.pangaea
//
//go:embed *.pangaea testdata/*.pangaea modules/*.pangaea
var FS embed.FS
1 change: 1 addition & 0 deletions native/modules/dummy_native.pangaea
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
message := "This is a dummy module."

0 comments on commit 4987d72

Please sign in to comment.