You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
136 lines
2.8 KiB
136 lines
2.8 KiB
package main
|
|
|
|
import (
|
|
"flag"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"log"
|
|
"os"
|
|
|
|
"github.com/facebookgo/flagenv"
|
|
)
|
|
|
|
var _ = func() error { log.SetFlags(log.LstdFlags | log.Llongfile); return nil }()
|
|
|
|
var (
|
|
program = flag.String("p", "", "h program to compile/run")
|
|
outFname = flag.String("o", "", "if specified, write the webassembly binary created by -p here")
|
|
watFname = flag.String("o-wat", "", "if specified, write the uncompiled webassembly created by -p here")
|
|
port = flag.String("port", "", "HTTP port to listen on")
|
|
sockpath = flag.String("sockpath", "", "Unix domain socket to listen on")
|
|
writeTao = flag.Bool("koan", false, "if true, print the h koan and then exit")
|
|
writeVersion = flag.Bool("v", false, "if true, print the version of h and then exit")
|
|
)
|
|
|
|
const koan = `And Jesus said unto the theologians, "Who do you say that I am?"
|
|
|
|
They replied: "You are the eschatological manifestation of the ground of our
|
|
being, the kerygma of which we find the ultimate meaning in our interpersonal
|
|
relationships."
|
|
|
|
And Jesus said "...What?"
|
|
|
|
Some time passed and one of them spoke "h".
|
|
|
|
Jesus was enlightened.`
|
|
|
|
func tao() {
|
|
fmt.Println(koan)
|
|
os.Exit(0)
|
|
}
|
|
|
|
func oneOff() error {
|
|
log.Println("compiling...")
|
|
comp, err := compile(*program)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
log.Println("running...")
|
|
er, err := run(comp.Binary)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
log.Println("success!")
|
|
|
|
log.Printf("gas used:\t%d", er.GasUsed)
|
|
log.Printf("exec time:\t%s", er.ExecTime)
|
|
log.Println("output:")
|
|
fmt.Print(er.Output)
|
|
|
|
if *outFname != "" {
|
|
err := ioutil.WriteFile(*outFname, comp.Binary, 0666)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
log.Printf("wrote %d bytes to %s", len(comp.Binary), *outFname)
|
|
}
|
|
|
|
if *watFname != "" {
|
|
err := ioutil.WriteFile(*watFname, []byte(comp.WebAssemblyText), 0666)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
log.Printf("write %d bytes of source to %s", len(comp.WebAssemblyText), *watFname)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
func main() {
|
|
flagenv.Parse()
|
|
flag.Parse()
|
|
|
|
if *writeVersion {
|
|
dumpVersion()
|
|
}
|
|
|
|
if *writeTao {
|
|
tao()
|
|
}
|
|
|
|
if *program != "" {
|
|
err := oneOff()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return
|
|
}
|
|
|
|
if *port != "" || *sockpath != "" {
|
|
err := doHTTP()
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
return
|
|
}
|
|
}
|
|
|
|
const wasmTemplate = `(module
|
|
(import "h" "h" (func $h (param i32)))
|
|
(func $h_main
|
|
(local i32 i32 i32)
|
|
(local.set 0 (i32.const 10))
|
|
(local.set 1 (i32.const 104))
|
|
(local.set 2 (i32.const 39))
|
|
{{ range . -}}
|
|
{{ if eq . 32 -}}
|
|
(call $h (get_local 0))
|
|
{{ end -}}
|
|
{{ if eq . 104 -}}
|
|
(call $h (get_local 1))
|
|
{{ end -}}
|
|
{{ if eq . 39 -}}
|
|
(call $h (get_local 2))
|
|
{{ end -}}
|
|
{{ end -}}
|
|
(call $h (get_local 0))
|
|
)
|
|
(export "h" (func $h_main))
|
|
)`
|