mirror of
https://github.com/Open-Argon/argon-v3.git
synced 2025-12-06 08:56:07 +00:00
make wasm work
This commit is contained in:
@@ -2,6 +2,8 @@ package main
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/jwalton/go-supportscolor"
|
||||
)
|
||||
|
||||
type ArErr struct {
|
||||
@@ -19,5 +21,9 @@ func panicErr(err ArErr) {
|
||||
fmt.Println(" " + err.code)
|
||||
fmt.Println()
|
||||
}
|
||||
fmt.Printf("\x1b[%dm%s\x1b[0m", 91, fmt.Sprint(err.TYPE, ": ", err.message, "\n"))
|
||||
if supportscolor.Stdout().SupportsColor {
|
||||
fmt.Printf("\x1b[%dm%s\x1b[0m", 91, fmt.Sprint(err.TYPE, ": ", err.message, "\n"))
|
||||
} else {
|
||||
fmt.Println(fmt.Sprint(err.TYPE, ": ", err.message))
|
||||
}
|
||||
}
|
||||
|
||||
188
src/import.go
188
src/import.go
@@ -5,7 +5,6 @@ import (
|
||||
"errors"
|
||||
"log"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
var imported = make(map[string]ArObject)
|
||||
@@ -48,101 +47,108 @@ func readFile(path string) []UNPARSEcode {
|
||||
}
|
||||
|
||||
func importMod(realpath string, origin string, main bool) (ArObject, ArErr) {
|
||||
extention := filepath.Ext(realpath)
|
||||
path := realpath
|
||||
if extention == "" {
|
||||
path += ".ar"
|
||||
return ArObject{}, ArErr{
|
||||
TYPE: "Import Error",
|
||||
message: "importing in WASM is currently not supported",
|
||||
EXISTS: true,
|
||||
}
|
||||
ex, err := os.Getwd()
|
||||
if err != nil {
|
||||
return ArObject{}, ArErr{TYPE: "Import Error", message: "Could not get working directory", EXISTS: true}
|
||||
}
|
||||
exc, err := os.Executable()
|
||||
if err != nil {
|
||||
return ArObject{}, ArErr{TYPE: "Import Error", message: "Could not get executable", EXISTS: true}
|
||||
}
|
||||
executable := filepath.Dir(exc)
|
||||
isABS := filepath.IsAbs(path)
|
||||
var pathsToTest []string
|
||||
if isABS {
|
||||
pathsToTest = []string{
|
||||
filepath.Join(path),
|
||||
filepath.Join(realpath, "init.ar"),
|
||||
/*
|
||||
extention := filepath.Ext(realpath)
|
||||
path := realpath
|
||||
if extention == "" {
|
||||
path += ".ar"
|
||||
}
|
||||
} else {
|
||||
pathsToTest = []string{
|
||||
filepath.Join(origin, realpath, "init.ar"),
|
||||
filepath.Join(origin, path),
|
||||
filepath.Join(origin, "modules", path),
|
||||
filepath.Join(origin, "modules", realpath, "init.ar"),
|
||||
filepath.Join(ex, path),
|
||||
filepath.Join(ex, "modules", realpath, "init.ar"),
|
||||
filepath.Join(ex, "modules", path),
|
||||
filepath.Join(executable, "modules", realpath, "init.ar"),
|
||||
filepath.Join(executable, "modules", path),
|
||||
ex, err := os.Getwd()
|
||||
if err != nil {
|
||||
return ArObject{}, ArErr{TYPE: "Import Error", message: "Could not get working directory", EXISTS: true}
|
||||
}
|
||||
}
|
||||
|
||||
var p string
|
||||
var found bool
|
||||
for _, p = range pathsToTest {
|
||||
if FileExists(p) {
|
||||
found = true
|
||||
break
|
||||
exc, err := os.Executable()
|
||||
if err != nil {
|
||||
return ArObject{}, ArErr{TYPE: "Import Error", message: "Could not get executable", EXISTS: true}
|
||||
}
|
||||
executable := filepath.Dir(exc)
|
||||
isABS := filepath.IsAbs(path)
|
||||
var pathsToTest []string
|
||||
if isABS {
|
||||
pathsToTest = []string{
|
||||
filepath.Join(path),
|
||||
filepath.Join(realpath, "init.ar"),
|
||||
}
|
||||
} else {
|
||||
pathsToTest = []string{
|
||||
filepath.Join(origin, realpath, "init.ar"),
|
||||
filepath.Join(origin, path),
|
||||
filepath.Join(origin, "modules", path),
|
||||
filepath.Join(origin, "modules", realpath, "init.ar"),
|
||||
filepath.Join(ex, path),
|
||||
filepath.Join(ex, "modules", realpath, "init.ar"),
|
||||
filepath.Join(ex, "modules", path),
|
||||
filepath.Join(executable, "modules", realpath, "init.ar"),
|
||||
filepath.Join(executable, "modules", path),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if !found {
|
||||
return ArObject{}, ArErr{TYPE: "Import Error", message: "File does not exist: " + realpath, EXISTS: true}
|
||||
} else if importing[p] {
|
||||
return ArObject{}, ArErr{TYPE: "Import Error", message: "Circular import: " + realpath, EXISTS: true}
|
||||
} else if _, ok := imported[p]; ok {
|
||||
return imported[p], ArErr{}
|
||||
}
|
||||
importing[p] = true
|
||||
codelines := readFile(p)
|
||||
var p string
|
||||
var found bool
|
||||
for _, p = range pathsToTest {
|
||||
if FileExists(p) {
|
||||
found = true
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
translated, translationerr := translate(codelines)
|
||||
if translationerr.EXISTS {
|
||||
return ArObject{}, translationerr
|
||||
}
|
||||
ArgsArArray := []any{}
|
||||
withoutarfile := []string{}
|
||||
if len(Args) > 1 {
|
||||
withoutarfile = Args[1:]
|
||||
}
|
||||
for _, arg := range withoutarfile {
|
||||
ArgsArArray = append(ArgsArArray, arg)
|
||||
}
|
||||
global := newscope()
|
||||
localvars := Map(anymap{
|
||||
"program": Map(anymap{
|
||||
"args": ArArray(ArgsArArray),
|
||||
"origin": origin,
|
||||
"import": builtinFunc{"import", func(args ...any) (any, ArErr) {
|
||||
if len(args) != 1 {
|
||||
return nil, ArErr{"Import Error", "Invalid number of arguments", 0, realpath, "", true}
|
||||
}
|
||||
if _, ok := args[0].(string); !ok {
|
||||
return nil, ArErr{"Import Error", "Invalid argument type", 0, realpath, "", true}
|
||||
}
|
||||
return importMod(args[0].(string), filepath.Dir(p), false)
|
||||
}},
|
||||
"cwd": ex,
|
||||
"exc": exc,
|
||||
"file": Map(anymap{
|
||||
"name": filepath.Base(p),
|
||||
"path": p,
|
||||
if !found {
|
||||
return ArObject{}, ArErr{TYPE: "Import Error", message: "File does not exist: " + realpath, EXISTS: true}
|
||||
} else if importing[p] {
|
||||
return ArObject{}, ArErr{TYPE: "Import Error", message: "Circular import: " + realpath, EXISTS: true}
|
||||
} else if _, ok := imported[p]; ok {
|
||||
return imported[p], ArErr{}
|
||||
}
|
||||
importing[p] = true
|
||||
codelines := readFile(p)
|
||||
|
||||
translated, translationerr := translate(codelines)
|
||||
if translationerr.EXISTS {
|
||||
return ArObject{}, translationerr
|
||||
}
|
||||
ArgsArArray := []any{}
|
||||
withoutarfile := []string{}
|
||||
if len(Args) > 1 {
|
||||
withoutarfile = Args[1:]
|
||||
}
|
||||
for _, arg := range withoutarfile {
|
||||
ArgsArArray = append(ArgsArArray, arg)
|
||||
}
|
||||
global := newscope()
|
||||
localvars := Map(anymap{
|
||||
"program": Map(anymap{
|
||||
"args": ArArray(ArgsArArray),
|
||||
"origin": origin,
|
||||
"import": builtinFunc{"import", func(args ...any) (any, ArErr) {
|
||||
if len(args) != 1 {
|
||||
return nil, ArErr{"Import Error", "Invalid number of arguments", 0, realpath, "", true}
|
||||
}
|
||||
if _, ok := args[0].(string); !ok {
|
||||
return nil, ArErr{"Import Error", "Invalid argument type", 0, realpath, "", true}
|
||||
}
|
||||
return importMod(args[0].(string), filepath.Dir(p), false)
|
||||
}},
|
||||
"cwd": ex,
|
||||
"exc": exc,
|
||||
"file": Map(anymap{
|
||||
"name": filepath.Base(p),
|
||||
"path": p,
|
||||
}),
|
||||
"main": main,
|
||||
"scope": global,
|
||||
}),
|
||||
"main": main,
|
||||
"scope": global,
|
||||
}),
|
||||
})
|
||||
_, runimeErr := ThrowOnNonLoop(run(translated, stack{vars, localvars, global}))
|
||||
importing[p] = false
|
||||
if runimeErr.EXISTS {
|
||||
return ArObject{}, runimeErr
|
||||
}
|
||||
imported[p] = global
|
||||
return global, ArErr{}
|
||||
})
|
||||
_, runimeErr := ThrowOnNonLoop(run(translated, stack{vars, localvars, global}))
|
||||
importing[p] = false
|
||||
if runimeErr.EXISTS {
|
||||
return ArObject{}, runimeErr
|
||||
}
|
||||
imported[p] = global
|
||||
return global, ArErr{}
|
||||
*/
|
||||
}
|
||||
|
||||
31
src/main.go
31
src/main.go
@@ -2,6 +2,7 @@ package main
|
||||
|
||||
import (
|
||||
"os"
|
||||
"syscall/js"
|
||||
)
|
||||
|
||||
// args without the program path
|
||||
@@ -17,17 +18,21 @@ func newscope() ArObject {
|
||||
}
|
||||
|
||||
func main() {
|
||||
ex, e := os.Getwd()
|
||||
if e != nil {
|
||||
panic(e)
|
||||
}
|
||||
if len(Args) == 0 {
|
||||
shell()
|
||||
os.Exit(0)
|
||||
}
|
||||
_, err := importMod(Args[0], ex, true)
|
||||
if err.EXISTS {
|
||||
panicErr(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
c := make(chan ArObject)
|
||||
obj := js.Global().Get("Object").New()
|
||||
obj.Set("eval", js.FuncOf(func(this js.Value, args []js.Value) interface{} {
|
||||
code := ""
|
||||
if len(args) > 0 {
|
||||
code = args[0].String()
|
||||
}
|
||||
val, err := wasmRun(code)
|
||||
if err.EXISTS {
|
||||
panicErr(err)
|
||||
return js.Null()
|
||||
}
|
||||
|
||||
return js.ValueOf(argonToJsValid(val))
|
||||
}))
|
||||
js.Global().Set("Ar", obj)
|
||||
<-c
|
||||
}
|
||||
|
||||
@@ -44,6 +44,7 @@ func parseGenericImport(code UNPARSEcode, index int, codeline []UNPARSEcode) (Ar
|
||||
}
|
||||
|
||||
func runImport(importOBJ ArImport, stack stack, stacklevel int) (any, ArErr) {
|
||||
return nil, ArErr{"Import Error", "importing in WASM is currently not supported", importOBJ.line, importOBJ.path, importOBJ.code, true}
|
||||
val, err := runVal(importOBJ.filePath, stack, stacklevel+1)
|
||||
val = ArValidToAny(val)
|
||||
if err.EXISTS {
|
||||
|
||||
@@ -44,7 +44,6 @@ func translateVal(code UNPARSEcode, index int, codelines []UNPARSEcode, isLine i
|
||||
return parseGenericImport(code, index, codelines)
|
||||
}
|
||||
}
|
||||
|
||||
if isLine >= 1 {
|
||||
if isDoWrap(code) {
|
||||
return parseDoWrap(code, index, codelines)
|
||||
|
||||
71
src/wasm.go
Normal file
71
src/wasm.go
Normal file
@@ -0,0 +1,71 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"syscall/js"
|
||||
)
|
||||
|
||||
func argonToJsValid(argon any) any {
|
||||
switch x := argon.(type) {
|
||||
case number:
|
||||
f, _ := x.Float64()
|
||||
return f
|
||||
case ArObject:
|
||||
if x.TYPE == "array" {
|
||||
arr := js.Global().Get("Array").New()
|
||||
for i, v := range x.obj["__value__"].([]any) {
|
||||
arr.SetIndex(i, argonToJsValid(v))
|
||||
}
|
||||
return arr
|
||||
} else if x.TYPE == "string" {
|
||||
return x.obj["__value__"].(string)
|
||||
}
|
||||
|
||||
obj := js.Global().Get("Object").New()
|
||||
for k, v := range x.obj {
|
||||
obj.Set(anyToArgon(k, false, false, 3, 0, false, 0), argonToJsValid(v))
|
||||
}
|
||||
return obj
|
||||
case bool, string:
|
||||
return x
|
||||
default:
|
||||
return nil
|
||||
}
|
||||
}
|
||||
|
||||
func wasmRun(code string) (any, ArErr) {
|
||||
lines := strings.Split(code, "\n")
|
||||
codelines := []UNPARSEcode{}
|
||||
for i := 0; i < len(lines); i++ {
|
||||
codelines = append(codelines, UNPARSEcode{
|
||||
lines[i],
|
||||
lines[i],
|
||||
i + 1,
|
||||
"<wasm>",
|
||||
})
|
||||
}
|
||||
|
||||
translated, translationerr := translate(codelines)
|
||||
if translationerr.EXISTS {
|
||||
return nil, translationerr
|
||||
}
|
||||
global := newscope()
|
||||
localvars := Map(anymap{
|
||||
"program": Map(anymap{
|
||||
"args": []any{},
|
||||
"origin": "",
|
||||
"import": builtinFunc{"import", func(args ...any) (any, ArErr) {
|
||||
return nil, ArErr{"Import Error", "Cannot Import in WASM", 0, "<wasm>", "", true}
|
||||
}},
|
||||
"cwd": "",
|
||||
"exc": "",
|
||||
"file": Map(anymap{
|
||||
"name": "<wasm>",
|
||||
"path": "",
|
||||
}),
|
||||
"main": true,
|
||||
"scope": global,
|
||||
}),
|
||||
})
|
||||
return ThrowOnNonLoop(run(translated, stack{vars, localvars, global}))
|
||||
}
|
||||
Reference in New Issue
Block a user