Skip to content

Commit

Permalink
Merge branch '2.3.x'
Browse files Browse the repository at this point in the history
  • Loading branch information
odino committed Aug 14, 2020
2 parents 5e90b88 + 3a46a14 commit 66f0264
Show file tree
Hide file tree
Showing 14 changed files with 111 additions and 61 deletions.
2 changes: 1 addition & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
FROM golang:1.13
FROM golang:1.15

RUN apt-get update
RUN apt-get install bash make git curl jq -y
Expand Down
2 changes: 1 addition & 1 deletion VERSION
Original file line number Diff line number Diff line change
@@ -1 +1 @@
2.2.2
2.3.0
Binary file modified docs/abs.wasm
Binary file not shown.
26 changes: 9 additions & 17 deletions docs/playground.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,26 +13,18 @@ without having to download and install it in your system.
<script src="/wasm_exec.js"></script>

<script>
if (!WebAssembly.instantiateStreaming) {
// polyfill
WebAssembly.instantiateStreaming = async (resp, importObject) => {
const source = await (await resp).arrayBuffer();
return await WebAssembly.instantiate(source, importObject);
};
}

const go = new Go();

let mod, inst;

WebAssembly.instantiateStreaming(fetch("/abs.wasm"), go.importObject).then(
async result => {
mod = result.module;
inst = result.instance;
// document.getElementById("runButton").disabled = false;
await go.run(inst);
}
);
async function fetch_wasm_module() {
const response = await fetch("/abs.wasm");
const buffer = await response.arrayBuffer();
const obj = await WebAssembly.instantiate(buffer, go.importObject);
mod = obj.module;
inst = obj.instance;
await go.run(inst);
}
fetch_wasm_module()

function run() {
var editor = ace.edit("editor");
Expand Down
59 changes: 28 additions & 31 deletions docs/wasm_exec.js
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,10 @@
}

if (!global.fs && global.require) {
global.fs = require("fs");
const fs = require("fs");
if (Object.keys(fs) !== 0) {
global.fs = fs;
}
}

const enosys = () => {
Expand Down Expand Up @@ -172,37 +175,19 @@
const storeValue = (addr, v) => {
const nanHead = 0x7FF80000;

if (typeof v === "number") {
if (typeof v === "number" && v !== 0) {
if (isNaN(v)) {
this.mem.setUint32(addr + 4, nanHead, true);
this.mem.setUint32(addr, 0, true);
return;
}
if (v === 0) {
this.mem.setUint32(addr + 4, nanHead, true);
this.mem.setUint32(addr, 1, true);
return;
}
this.mem.setFloat64(addr, v, true);
return;
}

switch (v) {
case undefined:
this.mem.setFloat64(addr, 0, true);
return;
case null:
this.mem.setUint32(addr + 4, nanHead, true);
this.mem.setUint32(addr, 2, true);
return;
case true:
this.mem.setUint32(addr + 4, nanHead, true);
this.mem.setUint32(addr, 3, true);
return;
case false:
this.mem.setUint32(addr + 4, nanHead, true);
this.mem.setUint32(addr, 4, true);
return;
if (v === undefined) {
this.mem.setFloat64(addr, 0, true);
return;
}

let id = this._ids.get(v);
Expand All @@ -216,8 +201,13 @@
this._ids.set(v, id);
}
this._goRefCounts[id]++;
let typeFlag = 1;
let typeFlag = 0;
switch (typeof v) {
case "object":
if (v !== null) {
typeFlag = 1;
}
break;
case "string":
typeFlag = 2;
break;
Expand Down Expand Up @@ -440,14 +430,14 @@

// func valueInstanceOf(v ref, t ref) bool
"syscall/js.valueInstanceOf": (sp) => {
this.mem.setUint8(sp + 24, loadValue(sp + 8) instanceof loadValue(sp + 16));
this.mem.setUint8(sp + 24, (loadValue(sp + 8) instanceof loadValue(sp + 16)) ? 1 : 0);
},

// func copyBytesToGo(dst []byte, src ref) (int, bool)
"syscall/js.copyBytesToGo": (sp) => {
const dst = loadSlice(sp + 8);
const src = loadValue(sp + 32);
if (!(src instanceof Uint8Array)) {
if (!(src instanceof Uint8Array || src instanceof Uint8ClampedArray)) {
this.mem.setUint8(sp + 48, 0);
return;
}
Expand All @@ -461,7 +451,7 @@
"syscall/js.copyBytesToJS": (sp) => {
const dst = loadValue(sp + 8);
const src = loadSlice(sp + 16);
if (!(dst instanceof Uint8Array)) {
if (!(dst instanceof Uint8Array || dst instanceof Uint8ClampedArray)) {
this.mem.setUint8(sp + 48, 0);
return;
}
Expand Down Expand Up @@ -490,10 +480,17 @@
global,
this,
];
this._goRefCounts = []; // number of references that Go has to a JS value, indexed by reference id
this._ids = new Map(); // mapping from JS values to reference ids
this._idPool = []; // unused ids that have been garbage collected
this.exited = false; // whether the Go program has exited
this._goRefCounts = new Array(this._values.length).fill(Infinity); // number of references that Go has to a JS value, indexed by reference id
this._ids = new Map([ // mapping from JS values to reference ids
[0, 1],
[null, 2],
[true, 3],
[false, 4],
[global, 5],
[this, 6],
]);
this._idPool = []; // unused ids that have been garbage collected
this.exited = false; // whether the Go program has exited

// Pass command line arguments and environment variables to WebAssembly by writing them to the linear memory.
let offset = 4096;
Expand Down
14 changes: 8 additions & 6 deletions lexer/lexer.go
Original file line number Diff line number Diff line change
Expand Up @@ -138,9 +138,10 @@ func (l *Lexer) NextToken() token.Token {
}
case '/':
if l.peekChar() == '/' {
tok.Type = token.COMMENT
tok.Position = l.position
tok.Literal = l.readLine()
// comment chunk - skip it
_ = l.readLine()
l.readChar()
return l.NextToken()
} else if l.peekChar() == '=' {
tok.Type = token.COMP_SLASH
tok.Position = l.position
Expand All @@ -150,9 +151,10 @@ func (l *Lexer) NextToken() token.Token {
tok = l.newToken(token.SLASH)
}
case '#':
tok.Type = token.COMMENT
tok.Position = l.position
tok.Literal = l.readLine()
// comment chunk - skip it
_ = l.readLine()
l.readChar()
return l.NextToken()
case '&':
if l.peekChar() == '&' {
tok.Type = token.AND
Expand Down
2 changes: 0 additions & 2 deletions lexer/lexer_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -286,8 +286,6 @@ f hello(x, y) {
{token.IDENT, "a"},
{token.DOT, "."},
{token.IDENT, "prop"},
{token.COMMENT, "# Comment"},
{token.COMMENT, "// Comment"},
{token.IDENT, "hello"},
{token.COMMAND, "command; command"},
{token.COMMAND, "command2; command2"},
Expand Down
10 changes: 10 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import (

"github.com/abs-lang/abs/install"
"github.com/abs-lang/abs/repl"
"github.com/abs-lang/abs/util"
)

// Version of the ABS interpreter
Expand All @@ -19,6 +20,15 @@ func main() {
return
}

if len(args) == 2 && args[1] == "--check-update" {
if newver, update := util.UpdateAvailable(Version); update {
fmt.Printf("Update available: %s (your version is %s)\n", newver, Version)
os.Exit(1)
} else {
return
}
}

if len(args) == 3 && args[1] == "get" {
install.Install(args[2])
return
Expand Down
1 change: 0 additions & 1 deletion parser/parser.go
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,6 @@ func New(l *lexer.Lexer) *Parser {
p.registerPrefix(token.LBRACKET, p.ParseArrayLiteral)
p.registerPrefix(token.LBRACE, p.ParseHashLiteral)
p.registerPrefix(token.COMMAND, p.parseCommand)
p.registerPrefix(token.COMMENT, p.parseComment)
p.registerPrefix(token.BREAK, p.parseBreak)
p.registerPrefix(token.CONTINUE, p.parseContinue)
p.registerPrefix(token.CURRENT_ARGS, p.parseCurrentArgsLiteral)
Expand Down
9 changes: 9 additions & 0 deletions repl/repl.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
package repl

import (
"crypto/rand"
"fmt"
"io"
"io/ioutil"
"math/big"
"os"
"os/user"
"path/filepath"
Expand Down Expand Up @@ -228,6 +230,13 @@ func BeginRepl(args []string, version string) {
panic(err)
}
fmt.Printf("Hello %s, welcome to the ABS (%s) programming language!\n", user.Username, version)
// check for new version about 10% of the time,
// to avoid too many hangups
if r, e := rand.Int(rand.Reader, big.NewInt(100)); e == nil && r.Int64() < 10 {
if newver, update := util.UpdateAvailable(version); update {
fmt.Printf("*** Update available: %s (your version is %s) ***\n", newver, version)
}
}
fmt.Printf("Type 'quit' when you're done, 'help' if you get lost!\n")
Start(os.Stdin, os.Stdout)
} else {
Expand Down
4 changes: 3 additions & 1 deletion scripts/release.abs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@
# "netbsd/386",
# "netbsd/amd64",
# "netbsd/arm"
#
# dropped by Go
# "darwin/386",

platforms = [
"linux/386",
Expand All @@ -41,7 +44,6 @@ platforms = [
"windows/amd64",
"windows/386",
"darwin/amd64",
"darwin/386",
"js/wasm"
]

Expand Down
1 change: 0 additions & 1 deletion token/token.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ const (
IDENT = "IDENT" // add, foobar, x, y, ...
NUMBER = "NUMBER" // 1343456, 1.23456
STRING = "STRING" // "foobar"
COMMENT = "#" // # Comment
AT = "@" // @ At symbol
NULL = "NULL" // # null
CURRENT_ARGS = "..." // # ... function args
Expand Down
30 changes: 30 additions & 0 deletions util/check_update.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
package util

import (
"io/ioutil"
"net/http"
"strings"
)

const verUrl = "https://raw.githubusercontent.com/abs-lang/abs/master/VERSION"

// Returns latest version, plus "new version available?" bool
func UpdateAvailable(version string) (string, bool) {
resp, err := http.Get(verUrl)
if err != nil {
return version, false
}
defer resp.Body.Close()

body, err := ioutil.ReadAll(resp.Body)
if err != nil {
return version, false
}

latest := strings.TrimSpace(string(body))
if version != latest {
return latest, true
}

return version, false
}
12 changes: 12 additions & 0 deletions util/check_update_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
package util

import (
"testing"
)

func TestUpdateAvailable(t *testing.T) {
_, outdated := UpdateAvailable("1.0")
if !outdated {
t.Fatalf("expected 1.0 to be outdated")
}
}

0 comments on commit 66f0264

Please sign in to comment.