commit
43e83607c0
9 changed files with 943 additions and 0 deletions
@ -0,0 +1,21 @@
|
||||
FROM xena/go:1.13.3 AS build |
||||
WORKDIR /hlang |
||||
COPY . . |
||||
RUN GOBIN=/usr/local/bin go install . |
||||
|
||||
FROM xena/alpine AS wasm |
||||
WORKDIR /wabt |
||||
RUN apk --no-cache add build-base cmake git python \ |
||||
&& git clone --recursive https://github.com/WebAssembly/wabt /wabt \ |
||||
&& mkdir build \ |
||||
&& cd build \ |
||||
&& cmake .. \ |
||||
&& make && make install |
||||
RUN ldd $(which wat2wasm) |
||||
|
||||
FROM xena/alpine |
||||
COPY --from=wasm /usr/local/bin/wat2wasm /usr/local/bin/wat2wasm |
||||
COPY --from=build /usr/local/bin/hlang /usr/local/bin/hlang |
||||
ENV PORT 5000 |
||||
RUN apk --no-cache add libstdc++ |
||||
CMD /usr/local/bin/hlang |
@ -0,0 +1,12 @@
|
||||
Copyright (c) 2019 Christine Dodrill <[email protected]> |
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any |
||||
purpose with or without fee is hereby granted. |
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH |
||||
REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY |
||||
AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, |
||||
INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM |
||||
LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR |
||||
OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR |
||||
PERFORMANCE OF THIS SOFTWARE. |
@ -0,0 +1,105 @@
|
||||
package main |
||||
|
||||
import ( |
||||
"bytes" |
||||
"context" |
||||
"io/ioutil" |
||||
"os" |
||||
"os/exec" |
||||
"path/filepath" |
||||
"strings" |
||||
"text/template" |
||||
"time" |
||||
|
||||
"github.com/eaburns/peggy/peg" |
||||
"within.website/x/h" |
||||
) |
||||
|
||||
var ( |
||||
wat2wasmLoc string |
||||
wasmTemplateObj *template.Template |
||||
) |
||||
|
||||
func init() { |
||||
loc, err := exec.LookPath("wat2wasm") |
||||
if err != nil { |
||||
panic(err) |
||||
} |
||||
|
||||
wat2wasmLoc = loc |
||||
wasmTemplateObj = template.Must(template.New("h.wast").Parse(wasmTemplate)) |
||||
} |
||||
|
||||
// CompiledProgram is a fully parsed and compiled h program.
|
||||
type CompiledProgram struct { |
||||
Source string `json:"src"` |
||||
WebAssemblyText string `json:"wat"` |
||||
Binary []byte `json:"bin"` |
||||
AST string `json:"ast"` |
||||
} |
||||
|
||||
func compile(source string) (*CompiledProgram, error) { |
||||
tree, err := h.Parse(source) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
var sb strings.Builder |
||||
err = peg.PrettyWrite(&sb, tree) |
||||
|
||||
result := CompiledProgram{ |
||||
Source: source, |
||||
AST: sb.String(), |
||||
} |
||||
|
||||
dir, err := ioutil.TempDir("", "h") |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
defer os.RemoveAll(dir) |
||||
|
||||
fout, err := os.Create(filepath.Join(dir, "h.wast")) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
buf := bytes.NewBuffer(nil) |
||||
|
||||
err = wasmTemplateObj.Execute(buf, []byte(tree.Text)) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
result.WebAssemblyText = buf.String() |
||||
_, err = fout.WriteString(result.WebAssemblyText) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
fname := fout.Name() |
||||
|
||||
err = fout.Close() |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
ctx, cancel := context.WithTimeout(context.Background(), time.Second) |
||||
defer cancel() |
||||
|
||||
cmd := exec.CommandContext(ctx, wat2wasmLoc, fname, "-o", filepath.Join(dir, "h.wasm")) |
||||
cmd.Dir = dir |
||||
|
||||
err = cmd.Run() |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
data, err := ioutil.ReadFile(filepath.Join(dir, "h.wasm")) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
result.Binary = data |
||||
|
||||
return &result, nil |
||||
} |
@ -0,0 +1,14 @@
|
||||
module tulpa.dev/cadey/hlang |
||||
|
||||
go 1.13 |
||||
|
||||
replace github.com/go-interpreter/wagon v0.0.0 => github.com/perlin-network/wagon v0.3.1-0.20180825141017-f8cb99b55a39 |
||||
|
||||
require ( |
||||
github.com/eaburns/peggy v1.0.1 |
||||
github.com/facebookgo/flagenv v0.0.0-20160425205200-fcd59fca7456 |
||||
github.com/perlin-network/life v0.0.0-20191010061010-fa85cafea8ac |
||||
github.com/rs/cors v1.7.0 |
||||
within.website/ln v0.7.0 |
||||
within.website/x v1.1.8 |
||||
) |
@ -0,0 +1,148 @@
|
||||
bou.ke/monkey v1.0.1/go.mod h1:FgHuK96Rv2Nlf+0u1OOVDpCMdsWyOFmeeketDHE7LIg= |
||||
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= |
||||
git.xeserv.us/xena/jvozba v0.0.0-20190616002803-f274e24d1e52/go.mod h1:lPdeNnexyxX+GQt62HV9UypJDg9enMwadWLXazGUUuc= |
||||
github.com/McKael/madon/v2 v2.0.0-20180929094633-c679abc985d6/go.mod h1:mvlJhxZCchfiasx3XvN3hBu5RekGwTDm09dKlSM/dQQ= |
||||
github.com/Yawning/bulb v0.0.0-20170405033506-85d80d893c3d/go.mod h1:v1YQIDSfaeRRehor57unRn66SBtmgAzxfsCpKIV998I= |
||||
github.com/aclements/go-moremath v0.0.0-20190506201756-286cc0be6f75/go.mod h1:idZL3yvz4kzx1dsBOAC+oYv6L92P1oFEhUXUB1A/lwQ= |
||||
github.com/birkelund/boltdbcache v1.0.0/go.mod h1:WgJWF40tV+4K0Q7MxAPbWEIkgs4AVUB7EyKVds0EgfQ= |
||||
github.com/bwmarrin/discordgo v0.19.0/go.mod h1:O9S4p+ofTFwB02em7jkpkV8M3R0/PUVOwN61zSZ0r4Q= |
||||
github.com/celrenheit/sandflake v0.0.0-20190410195419-50a943690bc2 h1:/BpnZPo/sk1vPlt62dLya5KCn7PN9ZBDrpTGlQzgUZI= |
||||
github.com/celrenheit/sandflake v0.0.0-20190410195419-50a943690bc2/go.mod h1:7L8gY0+4GYeBc9TvqVuDUq7tXuM6Sj7llnt7HkVwWlQ= |
||||
github.com/codahale/hdrhistogram v0.0.0-20161010025455-3a0bb77429bd/go.mod h1:sE/e/2PUdi/liOCUjSTXgM1o87ZssimdTWN964YiIeI= |
||||
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= |
||||
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= |
||||
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= |
||||
github.com/dgryski/go-failure v0.0.0-20151001134759-4963dbd58fd0/go.mod h1:vVcpVd0tzL5XdRrkHax1asNJsHVpgA0cd9fHPHU5a/w= |
||||
github.com/dgryski/go-onlinestats v0.0.0-20170612111826-1c7d19468768/go.mod h1:alfmlCqcg4uw9jaoIU1nOp9RFdJLMuu8P07BCEgpgoo= |
||||
github.com/disintegration/imaging v1.6.0/go.mod h1:xuIt+sRxDFrHS0drzXUlCJthkJ8k7lkkUojDSR247MQ= |
||||
github.com/eaburns/peggy v0.0.0-20180405011029-d685ddd3cbcb/go.mod h1:5tfPwI6ukiK3W5vJzkj5MBQKHHY9Gcy2y6k1FC/23Xk= |
||||
github.com/eaburns/peggy v0.0.0-20190420135231-b61cdde6efe6/go.mod h1:5tfPwI6ukiK3W5vJzkj5MBQKHHY9Gcy2y6k1FC/23Xk= |
||||
github.com/eaburns/peggy v1.0.1 h1:13lzoWg0eTeVouHrqFxO3ZL/XT8YlVk8YBAe/IO9VAQ= |
||||
github.com/eaburns/peggy v1.0.1/go.mod h1:X2pbl0EV5erfnK8kSGwo0lBCgMGokvR1E6KerAoDKXg= |
||||
github.com/eaburns/pretty v0.0.0-20170305202417-362524b72369/go.mod h1:iW/TU1T4mA4w2KzqNbBCjacPFdJ9PfGvNSxr8ajT/iM= |
||||
github.com/eaburns/pretty v0.0.0-20190404101635-2e1d2550ef0b/go.mod h1:iW/TU1T4mA4w2KzqNbBCjacPFdJ9PfGvNSxr8ajT/iM= |
||||
github.com/eaburns/pretty v1.0.0/go.mod h1:retcK8A0KEgdmb0nuxhvyxixwCmEPO7SKlK0IJhjg8A= |
||||
github.com/edsrzf/mmap-go v1.0.0/go.mod h1:YO35OhQPt3KJa3ryjFM5Bs14WD66h8eGKpfaBNrHW5M= |
||||
github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51 h1:0JZ+dUmQeA8IIVUMzysrX4/AKuQwWhV2dYQuPZdvdSQ= |
||||
github.com/facebookgo/ensure v0.0.0-20160127193407-b4ab57deab51/go.mod h1:Yg+htXGokKKdzcwhuNDwVvN+uBxDGXJ7G/VN1d8fa64= |
||||
github.com/facebookgo/flagenv v0.0.0-20160425205200-fcd59fca7456 h1:CkmB2l68uhvRlwOTPrwnuitSxi/S3Cg4L5QYOcL9MBc= |
||||
github.com/facebookgo/flagenv v0.0.0-20160425205200-fcd59fca7456/go.mod h1:zFhibDvPDWmtk4dAQ05sRobtyoffEHygEt3wSNuAzz8= |
||||
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052 h1:JWuenKqqX8nojtoVVWjGfOF9635RETekkoH6Cc9SX0A= |
||||
github.com/facebookgo/stack v0.0.0-20160209184415-751773369052/go.mod h1:UbMTZqLaRiH3MsBH8va0n7s1pQYcu3uTb8G4tygF4Zg= |
||||
github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870 h1:E2s37DuLxFhQDg5gKsWoLBOB0n+ZW8s599zru8FJ2/Y= |
||||
github.com/facebookgo/subset v0.0.0-20150612182917-8dac2c3c4870/go.mod h1:5tD+neXqOorC30/tWg0LCSkrqj/AR6gu8yY8/fpw1q0= |
||||
github.com/fogleman/gg v1.3.0/go.mod h1:R/bRT+9gY/C5z7JzPU0zXsXHKM4/ayA+zqcVNZzPa1k= |
||||
github.com/fogleman/primitive v0.0.0-20190214200932-673f57e7b1b5/go.mod h1:Tm6t8LbdhSCXNfpjTwoL1mdjCnyKHkMyf6PqQXo7Or8= |
||||
github.com/garyburd/redigo v1.6.0/go.mod h1:NR3MbYisc3/PwhQ00EMzDiPmrwpPxAn5GI05/YaO1SY= |
||||
github.com/go-interpreter/wagon v0.6.0 h1:BBxDxjiJiHgw9EdkYXAWs8NHhwnazZ5P2EWBW5hFNWw= |
||||
github.com/go-interpreter/wagon v0.6.0/go.mod h1:5+b/MBYkclRZngKF5s6qrgWxSLgE9F5dFdO1hAueZLc= |
||||
github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGwJL78qG/PmXZO1EjYhfJinVAhrmmHX6Z8B9k= |
||||
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= |
||||
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U= |
||||
github.com/google/go-github v17.0.0+incompatible/go.mod h1:zLgOLi98H3fifZn+44m+umXrS52loVEgC2AApnigrVQ= |
||||
github.com/google/go-querystring v1.0.0/go.mod h1:odCYkC5MyYFN7vkCjXpyrEuKhc/BUO6wN/zVPAxq5ck= |
||||
github.com/google/uuid v1.0.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= |
||||
github.com/google/uuid v1.1.1/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= |
||||
github.com/gorilla/websocket v1.4.0/go.mod h1:E7qHFY5m1UJ88s3WnNqhKjPHQ0heANvMoAMk2YaljkQ= |
||||
github.com/gregjones/httpcache v0.0.0-20190212212710-3befbb6ad0cc/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= |
||||
github.com/hullerob/go.farbfeld v0.0.0-20181222022525-3661193c725f/go.mod h1:mQEoc766DxPTAwQ54neWTK/lFqIeSO7OU6bqZsceglw= |
||||
github.com/jaytaylor/html2text v0.0.0-20190408195923-01ec452cbe43/go.mod h1:CVKlgaMiht+LXvHG173ujK6JUhZXKb2u/BQtjPDIvyk= |
||||
github.com/joeshaw/envdecode v0.0.0-20180312135643-c9e015854467/go.mod h1:Q+alOFAXgW5SrcfMPt/G4B2oN+qEcQRJjkn/f4mKL04= |
||||
github.com/joho/godotenv v1.3.0 h1:Zjp+RcGpHhGlrMbJzXTrZZPrWj+1vfm90La1wgB6Bhc= |
||||
github.com/joho/godotenv v1.3.0/go.mod h1:7hK45KPybAkOC6peb+G5yklZfMxEjkZhHbwpqxOKXbg= |
||||
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51/go.mod h1:CzGEWj7cYgsdH8dAjBGEr58BoE7ScuLd+fwFZ44+/x8= |
||||
github.com/klauspost/cpuid v1.2.1/go.mod h1:Pj4uuM528wm8OyEC2QMXAi2YiTZ96dNQPGgoMS4s3ek= |
||||
github.com/klauspost/reedsolomon v1.9.2/go.mod h1:CwCi+NUr9pqSVktrkN+Ondf06rkhYZ/pcNv7fu+8Un4= |
||||
github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= |
||||
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= |
||||
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= |
||||
github.com/mattn/go-runewidth v0.0.3/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= |
||||
github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= |
||||
github.com/miekg/dns v1.1.15/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= |
||||
github.com/mmikulicic/stringlist v1.0.0/go.mod h1:19Brp+Rld8TLwZ2oCHvTE3xDhCMr0jSCWwzcc9ejZgQ= |
||||
github.com/mndrix/golog v0.0.0-20170330170653-a28e2a269775/go.mod h1:Q4YHYl483MNk6wwg3g8YsINpKe5S2UzUJCRSRlFaSU0= |
||||
github.com/mndrix/ps v0.0.0-20170330174427-18e65badd6ab/go.mod h1:dHgTaDInzkAqJv67VaX1IkK449M2UoBY68CZeI/bNCU= |
||||
github.com/olekukonko/tablewriter v0.0.1/go.mod h1:vsDQFd/mU46D+Z4whnwzcISnGGzXWMclvtLoiIKAKIo= |
||||
github.com/otiai10/copy v1.0.1/go.mod h1:8bMCJrAqOtN/d9oyh5HR7HhLQMvcGMpGdwRDYsfOCHc= |
||||
github.com/otiai10/curr v0.0.0-20150429015615-9b4961190c95/go.mod h1:9qAhocn7zKJG+0mI8eUu6xqkFDYS2kb2saOteoSB3cE= |
||||
github.com/otiai10/curr v0.0.0-20190513014714-f5a3d24e5776/go.mod h1:3HNVkVOU7vZeFXocWuvtcS0XSFLcf2XUSDHkq9t1jU4= |
||||
github.com/otiai10/mint v1.2.3/go.mod h1:YnfyPNhBvnY8bW4SGQHCs/aAFhkgySlMZbrF5U0bOVw= |
||||
github.com/otiai10/mint v1.2.4/go.mod h1:d+b7n/0R3tdyUYYylALXpWQ/kTN+QobSq/4SRGBkR3M= |
||||
github.com/pborman/uuid v1.2.0/go.mod h1:X/NO0urCmaxf9VXbdlT7C2Yzkj2IKimNn4k+gtPdI/k= |
||||
github.com/perlin-network/life v0.0.0-20190625155037-103174020946/go.mod h1:z/EH0mO9zbeuTT5NX4u2VqVSG8y2vDQXz6iDKxikW2I= |
||||
github.com/perlin-network/life v0.0.0-20191010061010-fa85cafea8ac h1:JzeusmLSGyrRwaLEcZVCxskqNUUB1EyFswfh8ziRsto= |
||||
github.com/perlin-network/life v0.0.0-20191010061010-fa85cafea8ac/go.mod h1:tyABMoiJ4j//85N+bm67pYxi9nY3qKLydAFVzdsrLLY= |
||||
github.com/perlin-network/wagon v0.3.1-0.20180825141017-f8cb99b55a39/go.mod h1:zHOMvbitcZek8oshsMO5VpyBjWjV9X8cn8WTZwdebpM= |
||||
github.com/peterh/liner v1.1.0/go.mod h1:CRroGNssyjTd/qIG2FyxByd2S8JEAZXBl4qUrZf8GS0= |
||||
github.com/phayes/freeport v0.0.0-20180830031419-95f893ade6f2/go.mod h1:iIss55rKnNBTvrwdmkUpLnDpZoAHvWaiq5+iMmen4AE= |
||||
github.com/pkg/errors v0.8.0/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= |
||||
github.com/pkg/errors v0.8.1 h1:iURUrRGxPUNPdy5/HRSm+Yj6okJ6UtLINN0Q9M4+h3I= |
||||
github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0= |
||||
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= |
||||
github.com/rs/cors v1.6.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= |
||||
github.com/rs/cors v1.7.0 h1:+88SsELBHx5r+hZ8TCkggzSstaWNbDvThkVK8H6f9ik= |
||||
github.com/rs/cors v1.7.0/go.mod h1:gFx+x8UowdsKA9AchylcLynDq+nNFfI8FkUZdN/jGCU= |
||||
github.com/sendgrid/rest v2.4.1+incompatible/go.mod h1:kXX7q3jZtJXK5c5qK83bSGMdV6tsOE70KbHoqJls4lE= |
||||
github.com/ssor/bom v0.0.0-20170718123548-6386211fdfcf/go.mod h1:RJID2RhlZKId02nZ62WenDCkgHFerpIOmW0iT7GKmXM= |
||||
github.com/streamrail/concurrent-map v0.0.0-20160823150647-8bf1e9bacbf6/go.mod h1:yqDD2twFAqxvvH5gtpwwgLsj5L1kbNwtoPoDOwBzXcs= |
||||
github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= |
||||
github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= |
||||
github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= |
||||
github.com/sycamoreone/orc v0.0.0-20150204213357-1627eaec2699/go.mod h1:SZJ3/DVrJnKZPTTwCb38i9XZQU0T1yDm7oulSUO87a8= |
||||
github.com/templexxx/cpufeat v0.0.0-20180724012125-cef66df7f161/go.mod h1:wM7WEvslTq+iOEAMDLSzhVuOt5BRZ05WirO+b09GHQU= |
||||
github.com/templexxx/xor v0.0.0-20181023030647-4e92f724b73b/go.mod h1:5XA7W9S6mni3h5uvOC75dA3m9CCCaS83lltmc0ukdi4= |
||||
github.com/tjfoc/gmsm v1.0.1/go.mod h1:XxO4hdhhrzAd+G4CjDqaOkd0hUzmtPR/d3EiBBMn/wc= |
||||
github.com/tmc/scp v0.0.0-20170824174625-f7b48647feef/go.mod h1:WLFStEdnJXpjK8kd4qKLwQKX/1vrDzp5BcDyiZJBHJM= |
||||
github.com/twitchyliquid64/golang-asm v0.0.0-20190126203739-365674df15fc/go.mod h1:NoCfSFWosfqMqmmD7hApkirIK9ozpHjxRnRxs1l413A= |
||||
github.com/velour/chat v0.0.0-20180713122344-fd1d1606cb89/go.mod h1:ejwOYCjnDMyO5LXFXRARQJGBZ6xQJZ3rgAHE5drSuMM= |
||||
github.com/vmihailenco/msgpack v4.0.4+incompatible h1:dSLoQfGFAo3F6OoNhwUmLwVgaUXK79GlxNBwueZn0xI= |
||||
github.com/vmihailenco/msgpack v4.0.4+incompatible/go.mod h1:fy3FlTQTDXWkZ7Bh6AcGMlsjHatGryHQYUTf1ShIgkk= |
||||
github.com/xlzd/gotp v0.0.0-20181030022105-c8557ba2c119/go.mod h1:/nuTSlK+okRfR/vnIPqR89fFKonnWPiZymN5ydRJkX8= |
||||
github.com/xtaci/kcp-go v5.4.2+incompatible/go.mod h1:bN6vIwHQbfHaHtFpEssmWsN45a+AZwO7eyRCmEIbtvE= |
||||
github.com/xtaci/lossyconn v0.0.0-20190602105132-8df528c0c9ae/go.mod h1:gXtu8J62kEgmN++bm9BVICuT/e8yiLI2KFobd/TRFsE= |
||||
github.com/xtaci/smux v1.3.3/go.mod h1:f+nYm6SpuHMy/SH0zpbvAFHT1QoMcgLOsWcFip5KfPw= |
||||
github.com/yawning/bulb v0.0.0-20170405033506-85d80d893c3d/go.mod h1:2ickkGiASLFhjpaFnwRS1qr2yaY7EgGk73v+DIOL5Bo= |
||||
go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= |
||||
go4.org v0.0.0-20190313082347-94abd6928b1d h1:JkRdGP3zvTtTbabWSAC6n67ka30y7gOzWAah4XYJSfw= |
||||
go4.org v0.0.0-20190313082347-94abd6928b1d/go.mod h1:MkTOUMDaeVYJUOUsaDXIhWPZYa1yOyC1qaOBpL57BhE= |
||||
golang.org/x/crypto v0.0.0-20181030102418-4d3f4d9ffa16/go.mod h1:6SG95UA2DQfeDnfUPMdvaQW0Q7yPrPDi9nlGo2tz2b4= |
||||
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= |
||||
golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= |
||||
golang.org/x/crypto v0.0.0-20190513172903-22d7a77e9e5f/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= |
||||
golang.org/x/exp/errors v0.0.0-20190510132918-efd6b22b2522/go.mod h1:YgqsNsAu4fTvlab/7uiYK9LJrCIzKg/NiZUIH1/ayqo= |
||||
golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs= |
||||
golang.org/x/image v0.0.0-20190523035834-f03afa92d3ff/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= |
||||
golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= |
||||
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= |
||||
golang.org/x/net v0.0.0-20180811021610-c39426892332/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= |
||||
golang.org/x/net v0.0.0-20180926154720-4dfa2610cdf3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= |
||||
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= |
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= |
||||
golang.org/x/net v0.0.0-20190522155817-f3200d17e092 h1:4QSRKanuywn15aTZvI/mIDEgPQpswuFndXpOj3rKEco= |
||||
golang.org/x/net v0.0.0-20190522155817-f3200d17e092/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks= |
||||
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= |
||||
golang.org/x/oauth2 v0.0.0-20190523182746-aaccbc9213b0/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= |
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= |
||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= |
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= |
||||
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= |
||||
golang.org/x/sys v0.0.0-20190219203350-90b0e4468f99/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= |
||||
golang.org/x/sys v0.0.0-20190306220234-b354f8bf4d9e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= |
||||
golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
||||
golang.org/x/sys v0.0.0-20190602015325-4c4f7f33c9ed/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= |
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= |
||||
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk= |
||||
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= |
||||
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= |
||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= |
||||
google.golang.org/appengine v1.6.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= |
||||
gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= |
||||
gopkg.in/tucnak/telebot.v2 v2.0.0-20190415090633-8c1c512262f2/go.mod h1:+//wyPtHTeW2kfyEBwB05Hqnxev7AGrsLIyylSH++KU= |
||||
within.website/confyg v0.4.0 h1:FklkpJyMLYBxECCI4RS4R2c/x7PblOvbX0qBjk8Wkjs= |
||||
within.website/confyg v0.4.0/go.mod h1:KD5rDgkE3B+vbDiH/usiuK+CfiOkCiuD87NEF3/budk= |
||||
within.website/johaus v1.1.0/go.mod h1:0RBs2TucQ3CZQiVoqNj9Wch7mtZY05uvNO14v0lKcM4= |
||||
within.website/ln v0.6.0/go.mod h1:ifURKqsCJekcsdUE+hyCdcuhQqQ+9v9DfA++ZqYxZFE= |
||||
within.website/ln v0.7.0 h1:cZUc53cZF/+hWuEAv1VbqlYJ5czuPFHKfH0hLKmlIUA= |
||||
within.website/ln v0.7.0/go.mod h1:ifURKqsCJekcsdUE+hyCdcuhQqQ+9v9DfA++ZqYxZFE= |
||||
within.website/x v1.1.8 h1:OSiR9OQo+nRf17tiZV559bgKFB7x6xfcjPj9vVcJxVo= |
||||
within.website/x v1.1.8/go.mod h1:L6lqE0SSvN7RMnVFMuKsArOEzuRkT1R2HKYJgu/un7Q= |
@ -0,0 +1,423 @@
|
||||
package main |
||||
|
||||
import ( |
||||
"encoding/json" |
||||
"flag" |
||||
"fmt" |
||||
"io/ioutil" |
||||
"net/http" |
||||
|
||||
"github.com/rs/cors" |
||||
"within.website/ln/ex" |
||||
) |
||||
|
||||
var ( |
||||
maxBytes = flag.Int64("max-playground-bytes", 75, "how many bytes of data should users be allowed to post to the playground?") |
||||
) |
||||
|
||||
func doHTTP() error { |
||||
http.Handle("/", doTemplate(indexTemplate)) |
||||
http.Handle("/docs", doTemplate(docsTemplate)) |
||||
http.Handle("/faq", doTemplate(faqTemplate)) |
||||
http.Handle("/play", doTemplate(playgroundTemplate)) |
||||
http.HandleFunc("/api/playground", runPlayground) |
||||
|
||||
return http.ListenAndServe(":"+*port, ex.HTTPLog(cors.Default().Handler(http.DefaultServeMux))) |
||||
} |
||||
|
||||
func httpError(w http.ResponseWriter, err error, code int) { |
||||
w.Header().Set("Content-Type", "application/json") |
||||
w.WriteHeader(code) |
||||
json.NewEncoder(w).Encode(struct { |
||||
Error string `json:"err"` |
||||
}{ |
||||
Error: err.Error(), |
||||
}) |
||||
} |
||||
|
||||
func runPlayground(w http.ResponseWriter, r *http.Request) { |
||||
if r.Method != http.MethodPost { |
||||
http.NotFound(w, r) |
||||
return |
||||
} |
||||
|
||||
rc := http.MaxBytesReader(w, r.Body, *maxBytes) |
||||
defer rc.Close() |
||||
|
||||
data, err := ioutil.ReadAll(rc) |
||||
if err != nil { |
||||
httpError(w, err, http.StatusBadGateway) |
||||
return |
||||
} |
||||
|
||||
comp, err := compile(string(data)) |
||||
if err != nil { |
||||
httpError(w, fmt.Errorf("compliation error: %v", err), http.StatusBadRequest) |
||||
return |
||||
} |
||||
|
||||
er, err := run(comp.Binary) |
||||
if err != nil { |
||||
httpError(w, fmt.Errorf("runtime error: %v", err), http.StatusInternalServerError) |
||||
return |
||||
} |
||||
|
||||
w.Header().Set("Content-Type", "application/json") |
||||
json.NewEncoder(w).Encode(struct { |
||||
Program *CompiledProgram `json:"prog"` |
||||
Results *ExecResult `json:"res"` |
||||
}{ |
||||
Program: comp, |
||||
Results: er, |
||||
}) |
||||
} |
||||
|
||||
func doTemplate(body string) http.Handler { |
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { |
||||
w.Header().Set("Content-Type", "text/html") |
||||
fmt.Fprintln(w, body) |
||||
}) |
||||
} |
||||
|
||||
const indexTemplate = `<html> |
||||
<head> |
||||
<title>The h Programming Language</title> |
||||
<link rel="stylesheet" href="https://within.website/static/gruvbox.css"> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
||||
</head> |
||||
<body> |
||||
<main> |
||||
<nav> |
||||
<a href="/">The h Programming Language</a> - |
||||
<a href="/docs">Docs</a> - |
||||
<a href="/play">Playground</a> - |
||||
<a href="/faq">FAQ</a> |
||||
</nav> |
||||
|
||||
<h1>The h Programming Language</h1> |
||||
|
||||
<p><big>A simple, fast, open-source, complete and safe language for developing modern software for the web</big></p> |
||||
|
||||
<hr /> |
||||
|
||||
<h2>Example Program</h2> |
||||
|
||||
<code><pre>h</pre></code> |
||||
|
||||
<p>Outputs:</p> |
||||
|
||||
<code><pre>h</pre></code> |
||||
|
||||
<hr /> |
||||
|
||||
<h2>Fast Compilation</h2> |
||||
|
||||
<p>h compiles hundreds of characters of source per second. I didn't really test how fast it is, but when I was testing it the speed was fast enough that I didn't care to profile it.</p> |
||||
|
||||
<hr /> |
||||
|
||||
<h2>Safety</h2> |
||||
|
||||
<p>h is completely memory safe with no garbage collector or heap allocations. It does not allow memory leaks to happen, nor do any programs in h have the possibility to allocate memory.</p> |
||||
|
||||
<ul> |
||||
<li>No null</li> |
||||
<li>Completely deterministic behavior</li> |
||||
<li>No mutable state</li> |
||||
<li>No persistence</li> |
||||
<li>All functions are pure functions</li> |
||||
<li>No sandboxing required</li> |
||||
</ul> |
||||
|
||||
<hr /> |
||||
|
||||
<h2>Zero* Dependencies</h2> |
||||
|
||||
<p>h generates <a href="http://webassembly.org">WebAssembly</a>, so every binary produced by the compiler is completely dependency free save a single system call: <code>h.h</code>. This allows for modern, future-proof code that will work on all platforms.</p> |
||||
|
||||
<hr /> |
||||
|
||||
<h2>Simple</h2> |
||||
|
||||
<p>h has a <a href="https://github.com/Xe/x/blob/master/h/h.peg">simple grammar</a> that gzips to 117 bytes. Creating a runtime environment for h is so trivial just about anyone can do it.</p> |
||||
|
||||
<hr /> |
||||
|
||||
<h2>Platform Support</h2> |
||||
|
||||
<p>h supports the following platforms:</p> |
||||
|
||||
<ul> |
||||
<li>Google Chrome</li> |
||||
<li>Electron</li> |
||||
<li>Chromium Embedded Framework</li> |
||||
<li>Microsoft Edge</li> |
||||
<li>Olin</li> |
||||
</ul> |
||||
|
||||
<hr /> |
||||
|
||||
<h2>International Out of the Box</h2> |
||||
|
||||
<p>h supports multiple written and spoken languages with true contextual awareness. It not only supports the Latin <code>h</code> as input, it also accepts the <a href="http://lojban.org">Lojbanic</a> <code>'</code> as well. This allows for full 100% internationalization into Lojban should your project needs require it.</p> |
||||
|
||||
<hr /> |
||||
|
||||
<h2>Testimonials</h2> |
||||
|
||||
<p>Not convinced? Take the word of people we probably didn't pay for their opinion.</p> |
||||
|
||||
<ul> |
||||
<li>I don't see the point of this.</li> |
||||
<li>This solves all my problems. All of them. Just not in the way I expected it to.</li> |
||||
<li>Yes.</li> |
||||
<li>Perfect.</li> |
||||
<li>h is the backbone of my startup.</li> |
||||
</ul> |
||||
|
||||
<hr /> |
||||
|
||||
<h2>Open-Source</h2> |
||||
|
||||
<p>The h compiler and default runtime are <a href="https://github.com/Xe/x/tree/master/cmd/h">open-source</a> free software sent out into the <a href="https://creativecommons.org/choose/zero/">Public Domain</a>. You can use h for any purpose at all with no limitations or restrictions.</p> |
||||
|
||||
<hr /> |
||||
|
||||
<footer> |
||||
<center><p><i>From <a href="https://christine.website">Within</a></i></p></center> |
||||
</footer> |
||||
</main> |
||||
</body> |
||||
</html>` |
||||
|
||||
const docsTemplate = `<html> |
||||
<head> |
||||
<title>The h Programming Language - Docs</title> |
||||
<link rel="stylesheet" href="https://within.website/static/gruvbox.css"> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
||||
</head> |
||||
<body> |
||||
<main> |
||||
<nav> |
||||
<a href="/">The h Programming Language</a> - |
||||
<a href="/docs">Docs</a> - |
||||
<a href="/play">Playground</a> - |
||||
<a href="/faq">FAQ</a> |
||||
</nav> |
||||
|
||||
<h1>Documentation</h1> |
||||
|
||||
<p><big id="comingsoon">Coming soon...</big></p> |
||||
<script> |
||||
Date.prototype.addDays = function(days) { |
||||
var date = new Date(this.valueOf()); |
||||
date.setDate(date.getDate() + days); |
||||
return date; |
||||
} |
||||
|
||||
let date = new Date(); |
||||
date = date.addDays(1); |
||||
document.getElementById("comingsoon").innerHTML = "Coming " + date.toDateString(); |
||||
</script> |
||||
|
||||
<hr /> |
||||
|
||||
<footer> |
||||
<center><p><i>From <a href="https://christine.website">Within</a></i></p></center> |
||||
</footer> |
||||
</main> |
||||
</body> |
||||
</html>` |
||||
|
||||
const faqTemplate = `<html> |
||||
<head> |
||||
<title>The h Programming Language - FAQ</title> |
||||
<link rel="stylesheet" href="https://within.website/static/gruvbox.css"> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
||||
</head> |
||||
<body> |
||||
<main> |
||||
<nav> |
||||
<a href="/">The h Programming Language</a> - |
||||
<a href="/docs">Docs</a> - |
||||
<a href="/play">Playground</a> - |
||||
<a href="/faq">FAQ</a> |
||||
</nav> |
||||
|
||||
<h1>Frequently Asked Questions</h1> |
||||
|
||||
<h2>What are the instructions of h?</h2> |
||||
|
||||
<p>h supports the following instructions:</p> |
||||
<ul> |
||||
<li><code>h</code></li> |
||||
<li><code>'</code></li> |
||||
</ul> |
||||
|
||||
<p>All valid h instructions must be separated by a space (<code>\0x20</code> or the spacebar on your computer). No other forms of whitespace are permitted. Any other characters will render your program <a href="http://jbovlaste.lojban.org/dict/gentoldra">gentoldra</a>.</p> |
||||
|
||||
<h2>How do I install and use h?</h2> |
||||
|
||||
<p>With any computer running <a href="https://golang.org">Go</a> 1.11 or higher:</p> |
||||
|
||||
<code><pre>go get -u -v within.website/x/cmd/h</pre></code> |
||||
|
||||
Usage is simple: |
||||
|
||||
<code><pre>Usage of h: |
||||
-config string |
||||
configuration file, if set (see flagconfyg(4)) |
||||
-koan |
||||
if true, print the h koan and then exit |
||||
-license |
||||
show software licenses? |
||||
-manpage |
||||
generate a manpage template? |
||||
-max-playground-bytes int |
||||
how many bytes of data should users be allowed to |
||||
post to the playground? (default 75) |
||||
-o string |
||||
if specified, write the webassembly binary created |
||||
by -p here |
||||
-o-wat string |
||||
if specified, write the uncompiled webassembly |
||||
created by -p here |
||||
-p string |
||||
h program to compile/run |
||||
-port string |
||||
HTTP port to listen on |
||||
-v if true, print the version of h and then exit</pre></code> |
||||
|
||||
<h2>What version is h?</h2> |
||||
|
||||
<p>Version 1.0, this will hopefully be the only release.</p> |
||||
|
||||
<h2>What is the h koan?</h2> |
||||
|
||||
<p>And Jesus said unto the theologians, "Who do you say that I am?"</p> |
||||
|
||||
<p>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."</p> |
||||
|
||||
<p>And Jesus said "...What?"</p> |
||||
|
||||
<p>Some time passed and one of them spoke "h".</p> |
||||
|
||||
<p>Jesus was enlightened.</p> |
||||
|
||||
<h2>Why?</h2> |
||||
|
||||
<p>That's a good question. The following blogposts may help you understand this more:</p> |
||||
|
||||
<ul> |
||||
<li><a href="https://christine.website/blog/the-origin-of-h-2015-12-14">The Origin of h</a></li> |
||||
<li><a href="https://christine.website/blog/formal-grammar-of-h-2019-05-19">A Formal Grammar of h</a></li> |
||||
</ul> |
||||
|
||||
<h2>Who wrote h?</h2> |
||||
|
||||
<p><a href="https://christine.website">Within</a></p> |
||||
|
||||
<hr /> |
||||
|
||||
<footer> |
||||
<center><p><i>From <a href="https://christine.website">Within</a></i></p></center> |
||||
</footer> |
||||
</main> |
||||
</body> |
||||
</html>` |
||||
|
||||
const playgroundTemplate = `<html> |
||||
<head> |
||||
<title>The h Programming Language - Playground</title> |
||||
<link rel="stylesheet" href="https://within.website/static/gruvbox.css"> |
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" /> |
||||
</head> |
||||
<body> |
||||
<main> |
||||
<nav> |
||||
<a href="/">The h Programming Language</a> - |
||||
<a href="/docs">Docs</a> - |
||||
<a href="/play">Playground</a> - |
||||
<a href="/faq">FAQ</a> |
||||
</nav> |
||||
|
||||
<h1>Playground</h1> |
||||
|
||||
<p><small>Unfortunately, Javascript is required to use this page, sorry.</small></p> |
||||
|
||||
<h2>Program</h2> |
||||
|
||||
<input id="program" type="text" value="h" /> |
||||
|
||||
<input onClick="runProgram()" type="button" value="Run"> |
||||
<p id="status"></p> |
||||
|
||||
<h3>Output</h3> |
||||
|
||||
<code><pre id="output"></pre></code> |
||||
|
||||
<h4>WebAssembly Text Format</h4> |
||||
|
||||
<code><pre id="wat_box"></pre></code> |
||||
|
||||
<p>Gas used: <span id="gas_used"></span></p> |
||||
<p>Execution time (nanoseconds): <span id="exec_time"></span></p> |
||||
|
||||
<h4>AST</h4> |
||||
|
||||
<code><pre id="ast_box"></pre></code> |
||||
|
||||
<script> |
||||
function runProgram() { |
||||
const programData = document.getElementById("program").value; |
||||
const output = document.getElementById("output"); |
||||
const watBox = document.getElementById("wat_box"); |
||||
const astBox = document.getElementById("ast_box"); |
||||
const gasUsed = document.getElementById("gas_used"); |
||||
const execTime = document.getElementById("exec_time"); |
||||
const status = document.getElementById("status"); |
||||
|
||||
status.innerHTML = "submitting to the server..."; |
||||
|
||||
postData("/api/playground", programData) |
||||
.then(function(data) { |
||||
if (data.err != null) { |
||||
status.innerHTML = data.err; |
||||
return; |
||||
} |
||||
|
||||
status.innerHTML = "success"; |
||||
watBox.innerHTML = data.prog.wat; |
||||
astBox.innerHTML = data.prog.ast; |
||||
output.innerHTML = data.res.out; |
||||
gasUsed.innerHTML = data.res.gas; |
||||
execTime.innerHTML = data.res.exec_duration; |
||||
}) |
||||
.catch(function(error) { |
||||
console.log(error); |
||||
status.innerHTML = error + ". Please try again later?"; |
||||
}); |
||||
} |
||||
|
||||
function postData(url = "", data = "h") { |
||||
return fetch(url, { |
||||
method: "POST", |
||||
mode: "cors", |
||||
cache: "no-cache", |
||||
headers: { |
||||
"Content-Type": "text/plain", |
||||
}, |
||||
referrer: "no-referrer", |
||||
body: data, |
||||
}).then(response => response.json()); |
||||
} |
||||
</script> |
||||
|
||||
<hr /> |
||||
|
||||
<footer> |
||||
<center><p><i>From <a href="https://christine.website">Within</a></i></p></center> |
||||
</footer> |
||||
</main> |
||||
</body> |
||||
</html>` |
@ -0,0 +1,134 @@
|
||||
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") |
||||
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 != "" { |
||||
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)) |
||||
)` |
@ -0,0 +1,73 @@
|
||||
package main |
||||
|
||||
import ( |
||||
"errors" |
||||
"time" |
||||
|
||||
"github.com/perlin-network/life/compiler" |
||||
"github.com/perlin-network/life/exec" |
||||
) |
||||
|
||||
type Process struct { |
||||
Output []byte |
||||
} |
||||
|
||||
// ResolveGlobal does nothing, currently.
|
||||
func (p *Process) ResolveGlobal(module, field string) int64 { return 0 } |
||||
|
||||
// ResolveFunc resolves h's ABI and importable function.
|
||||
func (p *Process) ResolveFunc(module, field string) exec.FunctionImport { |
||||
switch module { |
||||
case "h": |
||||
switch field { |
||||
case "h": |
||||
return func(vm *exec.VirtualMachine) int64 { |
||||
frame := vm.GetCurrentFrame() |
||||
data := frame.Locals[0] |
||||
p.Output = append(p.Output, byte(data)) |
||||
|
||||
return 0 |
||||
} |
||||
|
||||
default: |
||||
panic("impossible state") |
||||
} |
||||
|
||||
default: |
||||
panic("impossible state") |
||||
} |
||||
} |
||||
|
||||
type ExecResult struct { |
||||
Output string `json:"out"` |
||||
GasUsed uint64 `json:"gas"` |
||||
ExecTime time.Duration `json:"exec_duration"` |
||||
} |
||||
|
||||
func run(bin []byte) (*ExecResult, error) { |
||||
p := &Process{} |
||||
|
||||
var cfg exec.VMConfig |
||||
gp := &compiler.SimpleGasPolicy{GasPerInstruction: 1} |
||||
vm, err := exec.NewVirtualMachine(bin, cfg, p, gp) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
mainFunc, ok := vm.GetFunctionExport("h") |
||||
if !ok { |
||||
return nil, errors.New("impossible state: no h function exposed") |
||||
} |
||||
|
||||
t0 := time.Now() |
||||
_, err = vm.Run(mainFunc) |
||||
if err != nil { |
||||
return nil, err |
||||
} |
||||
|
||||
return &ExecResult{ |
||||
Output: string(p.Output), |
||||
GasUsed: vm.Gas, |
||||
ExecTime: time.Since(t0), |
||||
}, nil |
||||
} |
Loading…
Reference in new issue