Add importing, lists and objects, and add basic functions (global and on values)

This commit is contained in:
Neemek 2025-03-10 16:23:16 +01:00
parent 449f7cd815
commit 634a4a2b61
Signed by: neemek
GPG key ID: 28360A8951CD0E9B
11 changed files with 919 additions and 60 deletions

View file

@ -3,11 +3,44 @@
package main
import (
"errors"
"log"
"neemek.com/anglais/core"
"syscall/js"
)
type JsResolver struct {
jsResolver js.Value
}
func (r *JsResolver) Resolve(name string) (core.Node, error) {
jsv := r.jsResolver.Invoke(name)
if jsv.Type() == js.TypeUndefined {
return nil, errors.New("cannot find import with name " + name)
}
if jsv.Type() != js.TypeString {
return nil, errors.New("invalid value for source: " + jsv.String())
}
source := jsv.String()
l := core.NewLexer(source)
tokens, err := l.Tokenize()
if err != nil {
return nil, err
}
p := core.NewParser(tokens)
tree, err := p.Parse()
if err != nil {
return nil, err
}
return tree, nil
}
func jsError(err error) interface{} {
return jsErrorOfString(err.Error())
}
@ -22,6 +55,7 @@ func jsErrorOfString(err string) interface{} {
func run(this js.Value, args []js.Value) interface{} {
source := args[0].String()
outputHandler := args[1]
resolver := args[2]
log.Printf("got source: %s", source)
lexer := core.NewLexer(source)
@ -45,6 +79,16 @@ func run(this js.Value, args []js.Value) interface{} {
compiler := core.NewCompiler()
compiler.SetImportsResolver(&JsResolver{
resolver,
})
defer func() {
if err := recover(); err != nil {
log.Printf("panic recovered: %v", err)
}
}()
compiler.Compile(tree)
log.Printf("Compiled tree (into %i instructions)", len(compiler.Chunk.Bytecode))
@ -55,19 +99,19 @@ func run(this js.Value, args []js.Value) interface{} {
vm.SetGlobal("write", core.BuiltinFunctionValue{
Name: "write",
Parameters: []string{"value"},
F: func(v map[string]core.Value) core.Value {
F: func(vm *core.VM, this core.Value, v map[string]core.Value) (core.Value, error) {
log.Printf("Writing value: %s", v["value"].String())
outputHandler.Invoke(js.ValueOf(v["value"].String() + "\n"))
return nil
return nil, nil
},
})
vm.SetGlobal("print", core.BuiltinFunctionValue{
Name: "print",
Parameters: []string{"value"},
F: func(v map[string]core.Value) core.Value {
F: func(vm *core.VM, this core.Value, v map[string]core.Value) (core.Value, error) {
log.Printf("Printing value: %s", v["value"].String())
outputHandler.Invoke(js.ValueOf(v["value"].String()))
return nil
return nil, nil
},
})