varaq-interpreter-go/main.go

104 lines
1.8 KiB
Go

//go:build js && wasm
// +build js,wasm
package main
import (
"bufio"
"bytes"
"fmt"
"io/ioutil"
"os"
"runtime"
"syscall/js"
"varaq/varaq"
)
func main() {
if runtime.GOARCH == "wasm" {
done := make(chan struct{}, 0)
js.Global().Set("varaq", js.FuncOf(jsInterpret))
fmt.Println("varaq WASM init, Qa'pla!")
<-done
} else {
argsCount := len(os.Args[1:])
if argsCount >= 1 {
runFile(os.Args[1])
} else {
repl()
}
os.Exit(0)
}
}
func repl() {
scanner := bufio.NewScanner(os.Stdin)
for fmt.Print("> "); scanner.Scan(); fmt.Print("> ") {
line := scanner.Text()
if len(line) == 0 {
return
}
err := interpret(line)
if err != nil {
fmt.Printf("%v\n", err)
}
}
}
func runFile(path string) {
code, err := ioutil.ReadFile(path) // the file is inside the local directory
if err != nil {
fmt.Printf("%v\n", err)
os.Exit(65)
}
err = interpret(string(code))
if err != nil {
fmt.Printf("%v\n", err)
os.Exit(65)
}
}
func interpret(src string) error {
tokens, err := varaq.Tokenize(src)
if err != nil {
return fmt.Errorf("%v", err)
}
code := varaq.Parse(tokens)
err = varaq.Interpret(code, os.Args[1:], os.Stdout)
if err != nil {
fmt.Printf("%v\n", err)
return err
}
return nil
}
func jsInterpret(this js.Value, args []js.Value) interface{} {
if len(args) < 1 {
return js.ValueOf("no input")
}
input := args[0].String()
tokens, err := varaq.Tokenize(input)
if err != nil {
return js.ValueOf(fmt.Errorf("%v", err))
}
code := varaq.Parse(tokens)
buf := bytes.NewBufferString("")
strings := make([]string, len(args[1:]))
for i, jsVal := range args[1:] {
strings[i] = jsVal.String()
}
err = varaq.Interpret(code, strings, buf)
if err != nil {
return js.ValueOf(fmt.Errorf("%v", err))
}
return js.ValueOf(buf.String())
}