github.com/mattn/anko@v0.1.10/misc/wasm/anko.go (about) 1 // +build js,wasm 2 3 package main 4 5 import ( 6 "fmt" 7 "html" 8 "strings" 9 "syscall/js" 10 11 "github.com/mattn/anko/core" 12 "github.com/mattn/anko/packages" 13 "github.com/mattn/anko/parser" 14 "github.com/mattn/anko/vm" 15 ) 16 17 var ( 18 result = js.Global.Get("document").Call("getElementById", "result") 19 input = js.Global.Get("document").Call("getElementById", "input") 20 ) 21 22 func writeCommand(s string) { 23 result.Set("innerHTML", result.Get("innerHTML").String()+"<p class='command'>"+html.EscapeString(s)+"</p>") 24 result.Set("scrollTop", result.Get("scrollHeight").Int()) 25 } 26 27 func writeStdout(s string) { 28 result.Set("innerHTML", result.Get("innerHTML").String()+"<p class='stdout'>"+html.EscapeString(s)+"</p>") 29 result.Set("scrollTop", result.Get("scrollHeight").Int()) 30 } 31 32 func writeStderr(s string) { 33 result.Set("innerHTML", result.Get("innerHTML").String()+"<p class='stderr'>"+html.EscapeString(s)+"</p>") 34 result.Set("scrollTop", result.Get("scrollHeight").Int()) 35 } 36 37 func main() { 38 env := vm.NewEnv() 39 core.Import(env) 40 packages.DefineImport(env) 41 42 env.Define("print", func(a ...interface{}) { 43 writeStdout(fmt.Sprint(a...)) 44 }) 45 env.Define("printf", func(a string, b ...interface{}) { 46 writeStdout(fmt.Sprintf(a, b...)) 47 }) 48 49 var following bool 50 var source string 51 52 parser.EnableErrorVerbose() 53 54 ch := make(chan string) 55 56 input.Call("addEventListener", "keypress", js.NewCallback(func(args []js.Value) { 57 e := args[0] 58 if e.Get("keyCode").Int() != 13 { 59 return 60 } 61 s := e.Get("target").Get("value").String() 62 e.Get("target").Set("value", "") 63 writeCommand(s) 64 ch <- s 65 })) 66 input.Set("disabled", false) 67 result.Set("innerHTML", "") 68 69 go func() { 70 for { 71 text, ok := <-ch 72 if !ok { 73 break 74 } 75 source += text 76 if source == "" { 77 continue 78 } 79 if source == "quit()" { 80 break 81 } 82 83 stmts, err := parser.ParseSrc(source) 84 85 if e, ok := err.(*parser.Error); ok { 86 es := e.Error() 87 if strings.HasPrefix(es, "syntax error: unexpected") { 88 if strings.HasPrefix(es, "syntax error: unexpected $end,") { 89 following = true 90 continue 91 } 92 } else { 93 if e.Pos.Column == len(source) && !e.Fatal { 94 writeStderr(e.Error()) 95 following = true 96 continue 97 } 98 if e.Error() == "unexpected EOF" { 99 following = true 100 continue 101 } 102 } 103 } 104 105 following = false 106 source = "" 107 var v interface{} 108 109 if err == nil { 110 v, err = vm.Run(stmts, env) 111 } 112 if err != nil { 113 if e, ok := err.(*vm.Error); ok { 114 writeStderr(fmt.Sprintf("%d:%d %s\n", e.Pos.Line, e.Pos.Column, err)) 115 } else if e, ok := err.(*parser.Error); ok { 116 writeStderr(fmt.Sprintf("%d:%d %s\n", e.Pos.Line, e.Pos.Column, err)) 117 } else { 118 writeStderr(err.Error()) 119 } 120 continue 121 } 122 123 writeStdout(fmt.Sprintf("%#v\n", v)) 124 } 125 }() 126 127 select {} 128 129 }