initial commit

This commit is contained in:
Cadey Ratio 2019-11-28 17:39:35 +00:00
commit 43e83607c0
9 changed files with 943 additions and 0 deletions

21
Dockerfile Normal file
View File

@ -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

12
LICENSE Normal file
View File

@ -0,0 +1,12 @@
Copyright (c) 2019 Christine Dodrill <me@christine.website>
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.

105
compile.go Normal file
View File

@ -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
}

14
go.mod Normal file
View File

@ -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
)

148
go.sum Normal file
View File

@ -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=

423
http.go Normal file
View File

@ -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>`

134
main.go Normal file
View File

@ -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))
)`

73
run.go Normal file
View File

@ -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
}

13
version.go Normal file
View File

@ -0,0 +1,13 @@
package main
import (
"fmt"
"os"
)
const version = "1.0.0"
func dumpVersion() {
fmt.Println("h programming language version", version)
os.Exit(0)
}