Skip to content

Commit

Permalink
error reporting, bug fixes, and worked on self-hosted compiler
Browse files Browse the repository at this point in the history
  • Loading branch information
JonathanAldrich committed Dec 9, 2020
1 parent 7154e3a commit fb78d97
Show file tree
Hide file tree
Showing 22 changed files with 122 additions and 28 deletions.
7 changes: 7 additions & 0 deletions jsgen/gen.wyv
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// generates javascript from protobuf-based bytecode
module gen

// generates javascript in a string from protobuf bytecode (in a buffer)
def generate(bytecodeBuffer:Dyn):String
// placeholder for now
"console.log(\"executing now!\");"
12 changes: 12 additions & 0 deletions native/javascript/stdlib/support/bytecode.js
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,18 @@ exports.saveBytecode = function(path, bytecodeObject) {
fs.writeFileSync(path, bbuffer);
}

exports.encodeAndDecode = function(bytecodeObject) {
setRoot();
const Bytecode = root.lookupType('Bytecode');
var errMsg = Bytecode.verify(bytecodeObject);
if (errMsg)
throw Error(errMsg);
var bmsg = Bytecode.create(bytecodeObject);
var bbuffer = Bytecode.encode(bmsg).finish();
var newBytecode = Bytecode.decode(bbuffer);
return wrap(newBytecode);
}

exports.encodeExpr = function(exprObject) {
setRoot();
const Expression= root.lookupType('Expression');
Expand Down
14 changes: 14 additions & 0 deletions native/javascript/stdlib/support/exec.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
exports.execute = function(environment, code) {
console.log("executing " + code);
// environment is a linked list; traverse collecting value elements
// each element is a pair
const args = [];
// put the second part into an array
// build a let-binding based on the first part and FUNCTION_ARGS[currentIndex]
// prepend the let bindings to the code
const extendedCode = code;
const encapsulatedCode = new Function('FUNCTION_ARGS', extendedCode);
// TODO: implement all of the above, and then:
// run the extended code
encapsulatedCode(args)
}
15 changes: 15 additions & 0 deletions native/javascript/stdlib/support/stdio.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
const readline = require("readline");

exports.print = function(s) {
process.stdout.write("" + s);
}
Expand All @@ -15,3 +17,16 @@ exports.println = function(s) {
exports.flush = function(s) {
// NOP, node doesn't have flush
}

exports.onLine = function(cb) {
// invoke cb as a Wyvern function whenever input arrives from standard in
const rl = readline.createInterface({
input: process.stdin,
output: process.stdout,
terminal: false
});

rl.on('line', function (line) {
cb.apply(line)
});
}
12 changes: 6 additions & 6 deletions selfhost/binding.wyv
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import raw
import error
import lexUtil
import types
import typesUtil
import typecheck
import selfhost.raw
import selfhost.error
import selfhost.lexUtil
import selfhost.types
import selfhost.typesUtil
import selfhost.typecheck
import wyvern.collections.llist

type List = llist.LinkedList
Expand Down
2 changes: 1 addition & 1 deletion selfhost/bound.wyv
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module bound

import types
import selfhost.types
import wyvern.collections.llist
type List = llist.LinkedList
type Counter = types.Counter
Expand Down
2 changes: 2 additions & 0 deletions selfhost/bytecode.wyv
Original file line number Diff line number Diff line change
Expand Up @@ -167,3 +167,5 @@ def encodeExpr(e:Expr):Unit
def saveBytecode(path:String, b:Bytecode):Unit
bytecode.saveBytecode(path, b)

def encodeAndDecode(b:Bytecode):Unit
bytecode.encodeAndDecode(b)
2 changes: 1 addition & 1 deletion selfhost/error.wyv
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
module errors

import wyvern.exception
import Location
import selfhost.Location
import wyvern.String

type ErrorReportingException extends exception.Exception
Expand Down
17 changes: 17 additions & 0 deletions selfhost/exec.wyv
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
// executes Javascript
module def exec(javascript:JavaScript)

import javascript:stdlib.support.exec
import wyvern.collections.llist

type ArgPair
val name:String
val value:Dyn

def ArgPair(name:String, value:Dyn):ArgPair = new
val name:String = name
val value:Dyn = value

// executes a string of Javascript in a given environment, returning the result
def execute(environment: llist.LinkedList[ArgPair], code:String):Dyn
exec.execute(environment, code)
2 changes: 1 addition & 1 deletion selfhost/parsing.wyv
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import javaMetaDebug
import wyvern.ast
import metadata wyvern.collections.list
import javascript:stdlib.support.parsing
import lexing
import selfhost.lexing
import wyvern.util.matching.regexInternal
import java:wyvern.stdlib.support.StringHelper.utils

Expand Down
21 changes: 16 additions & 5 deletions selfhost/toBytecode.wyv
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
module def toBytecode(javascript:JavaScript, js:Dyn)

import types
import bytecode
import selfhost.types
import selfhost.bytecode
import wyvern.collections.llist
import error
import selfhost.error
type List = llist.LinkedList

val b = bytecode(javascript, js)
Expand Down Expand Up @@ -38,15 +38,26 @@ def toBytecodeExpr(e:types.Exp):b.Expr = match e:
i:types.Integer => b.IntLit(i.str)
u:types.UnitVal => b.IntLit("0")

def writeExpToFile(e:types.Statement, filename:String):Unit
def toFileBytecode(e:types.Statement):b.Bytecode
js.log("Converting expression to bytecode...\n")
val expBytecode = toBytecode(e)
//js.log(d.sequenceExpression.statements.get(0).declaration)
js.log("Creating top level bytecode...\n")
val fileBytecode = b.singletonBytecode(b.toplevel(expBytecode))
b.singletonBytecode(b.toplevel(expBytecode))

// takes the same thing as writeExpToFile
// encodes to protobuf bytes and decodes
// returns the same thing as b.loadBytecode
def encodeAndDecode(e:types.Statement): Dyn
val fileBytecode = toFileBytecode(e)
b.encodeAndDecode(fileBytecode)

def writeExpToFile(e:types.Statement, filename:String):Unit
val fileBytecode = toFileBytecode(e)
js.log("Actually saving...\n")
b.saveBytecode(filename, fileBytecode)


/*
// test code
val expr = b.StrLit("Hello")
Expand Down
7 changes: 4 additions & 3 deletions selfhost/typecheck.wyv
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
module typecheck

import types
import typesUtil
import error
import selfhost.types
import selfhost.typesUtil
import selfhost.error
import debug
import wyvern.option
import wyvern.collections.llist
import wyvern.pair
Expand Down
4 changes: 2 additions & 2 deletions selfhost/types.wyv
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
module types

import raw
import selfhost.raw
import wyvern.option
import wyvern.collections.llist
import error
import selfhost.error
type Option = option.Option
type List = llist.LinkedList

Expand Down
4 changes: 2 additions & 2 deletions selfhost/typesUtil.wyv
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ module typesUtil
import wyvern.option
import wyvern.collections.llist
import wyvern.pair
import error
import types
import selfhost.error
import selfhost.types
type Option = option.Option
type List = llist.LinkedList
type Binding = types.Binding
Expand Down
6 changes: 3 additions & 3 deletions selfhost/wyvernLexer.wyv
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
module def wyvernLexer(js:Dyn, regexUtils:Dyn)

import metadata lexing
import metadata selfhost.lexing
import wyvern.collections.llist
import wyvern.runtime
import lexUtil
import selfhost.lexUtil

type List = llist.LinkedList

Expand All @@ -26,6 +26,7 @@ def Token(t:String, value:String, line:Int, col:Int):Token = new

// note: this lexer will never actually see a logline (\n, \r, or \r\n). But we generate such tokens later on at line breaks

// This is the only state in the lexer. It gets reset on every call to the higher-level lex functions, so this state is mostly innoccuous; it's OK to use those higher-level functions in any single-threaded way, including creating multiple higher-level Lexers and interleaving their use. But note that the current design requires each instance of wyvernLexer to be used in a single-threaded manner. If you want multiple threads create multiple wyvernLexers.
val lowLevelLexer : lexing.Lexer = ~
WS: /[ \t]+/,
logline: {match: /\\r\\n|\\r|\\n/, lineBreaks: true},
Expand Down Expand Up @@ -311,7 +312,6 @@ resource type IncrementalLexer
/*
// TODO: revise to work with lineCont
def incrementalLexer():IncrementalLexer
// TODO: make all the state above local
new
var tokens : List[Dyn] = llist.Nil[Dyn]()
def addLine(input:String):option.Option[lexing.Lexer]
Expand Down
6 changes: 3 additions & 3 deletions selfhost/wyvernParser.wyv
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
module wyvernParser

import lexing
import metadata parsing
import raw
import selfhost.lexing
import metadata selfhost.parsing
import selfhost.raw
import wyvern.collections.llist
type List = llist.LinkedList

Expand Down
1 change: 1 addition & 0 deletions stdlib/formatstring.wyv
Original file line number Diff line number Diff line change
Expand Up @@ -71,6 +71,7 @@ def convStringAST(input : String, ctx : system.Context, floatPrecision : Int) :
if (ast.types.equals(ty, ast.types.boolean(), ctx))
option.Some[AST](ast.call(exp, "ifTrue", {ast.parseExpression("() => \"true\"", ctx), ast.parseExpression("() => \"false\"", ctx)}))
else
ast.reportError("Wyvern expressions inside format string must have type Int, String, Float, or Boolean")
option.None[AST]()


Expand Down
6 changes: 6 additions & 0 deletions stdlib/platform/javascript/asyncIn.wyv
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
module def asyncIn(javascript : JavaScript)

import javascript:stdlib.support.stdio

def onLine(callback : String -> Unit):Unit
stdio.onLine(callback)
2 changes: 2 additions & 0 deletions stdlib/wyvern/ast.wyv
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,8 @@ def formalArg(name : String, argType : Type) : FormalArg = ast.formalArg(name, a
// Utility Functions
def stripLeadingWhitespace(input : String, mustStrip : Boolean) : String = ast.stripLeadingWhitespace(input, mustStrip)

def reportError(msg : String) : Unit = ast.reportError(msg)

def genIdent() : String = ast.genIdent()

def getMetadataTypeReceiver(ctx : system.Context) : AST
Expand Down
2 changes: 2 additions & 0 deletions stdlib/wyvern/internal/ast.wyv
Original file line number Diff line number Diff line change
Expand Up @@ -159,6 +159,8 @@ val types = new

def stripLeadingWhitespace(input : String, mustStrip : Boolean) : String = utils.stripLeadingWhitespace(input, mustStrip)

def reportError(msg : String) : Unit = utils.reportError(msg)

def genIdent() : String = utils.genIdent()

def let(ident : String, bindingType : Type, bindingValue : AST, inExpr : AST) : AST = new
Expand Down
4 changes: 4 additions & 0 deletions tools/src/wyvern/stdlib/support/AST.java
Original file line number Diff line number Diff line change
Expand Up @@ -428,6 +428,10 @@ public String stripLeadingWhitespace(String input, boolean mustStrip) throws IOE
return result.toString();
}

public void reportError(String msg) {
ToolError.reportError(ErrorMessage.TSL_ERROR, new FileLocation("TSL", 1, 1), msg);
}

public String genIdent() {
return "ASTIDENT$" + Integer.toString(++identNum);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -205,7 +205,7 @@ private EffectSet decomposeEffectSet(EffectSet effects, Effect e, DecomposeType

@Override
public String toString() {
return effectSet == null ? "" : effectSet.toString().replace("[", "{").replace("]", "}");
return effectSet == null ? "" : effectSet.toString().replace("[", "{").replace("]", "}").replaceAll("MOD\\$", "");
}


Expand Down

0 comments on commit fb78d97

Please sign in to comment.