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.
135 lines
2.8 KiB
135 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)) |
|
)`
|
|
|