Skip to content

Commit

Permalink
file loading in browser, handle compiled def references (Code.globals)
Browse files Browse the repository at this point in the history
  • Loading branch information
zot committed Apr 1, 2012
1 parent a64f45d commit 2110e65
Show file tree
Hide file tree
Showing 12 changed files with 261 additions and 153 deletions.
12 changes: 8 additions & 4 deletions browserRepl.cs
Expand Up @@ -6,8 +6,10 @@

lastLine = null
input = null
write = null

init = (inputField, output, defs)->
write = (line)-> defs.innerHTML += line
ReplCore.setWriter (line)-> output.innerHTML += line
ReplCore.setNext -> input.value = ''
ReplCore.setHandler (ast, result, a, c, r)->
Expand All @@ -22,6 +24,7 @@
input.select()

markupDef = (line)->
if line.match /^\s*#/ then line
if (match = line.match /^[^=]*(?=\s*=)/) then "<b>#{match[0]}</b>#{line.substring(match[0].length)}"
else line

Expand All @@ -32,10 +35,11 @@
reader = new FileReader()
reader.onerror = (evt)-> alert('error' + evt)
reader.onload = ->
LC.loadDefs(reader.result)
displayOutput()
displayResults(true)
result.innerHTML = ''
for line in reader.result.split('\n')
if line
write "#{markupDef line}\n"
ast = Lazp.compileLine line
if ast then [ast, result] = Lazp.evalLine line
reader.readAsText(files[0])
fileElement.value = null
input.select()
Expand Down
30 changes: 25 additions & 5 deletions browserRepl.js

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

66 changes: 35 additions & 31 deletions lazp.cs
Expand Up @@ -218,14 +218,16 @@ class CNil extends Cons
cons = (a, b)-> new Cons(a, b)

class Code
constructor: (@main, @subfuncs, @fcount, @mcount, @vars, @err)->
constructor: (@main, @subfuncs, @fcount, @mcount, @vars, @err, @global)->
@main = @main ? ''
@subfuncs = @subfuncs ? ''
@fcount = @fcount ? 0
@mcount = @mcount ? 0
@vars = @vars ? Nil
copyWith: (main, subfuncs, fcount, mcount, vars, err)->new Code(main ? @main, subfuncs ? @subfuncs, fcount ? @fcount, mcount ? @mcount, vars ? @vars, err ? @err)
@global = @global ? Nil
copyWith: (main, subfuncs, fcount, mcount, vars, err, global)->new Code(main ? @main, subfuncs ? @subfuncs, fcount ? @fcount, mcount ? @mcount, vars ? @vars, err ? @err, global ? @global)
addErr: (e)-> @copyWith(null, null, null, null, null, "#{@err}#{e}\n")
setGlobal: (v)-> @copyWith(null, null, null, null, null, null, v)
addVar: (v)-> @copyWith(null, null, null, null, cons(v, @vars), null)
setVars: (v)-> @copyWith(null, null, null, null, v, null)
resetMemo: -> @copyWith(null, null, null, 0)
Expand All @@ -238,10 +240,10 @@ class Code
if !@mcount then @unreffedValue(deref)
else @copyWith("(function(){var #{@memoNames()}; return #{@main}})", null, null, 0).reffedValue(deref)

dgen = (ast, lazy, name)->
dgen = (ast, lazy, name, globals)->
ast.lits = []
res = []
code = (gen ast, new Code(), ast.lits, (if name? then cons(name, Nil) else Nil), true).memo(!lazy)
code = (gen ast, new Code().setGlobal(cons(name, globals ? Nil)), ast.lits, Nil, true).memo(!lazy)
if code.err? then ast.err = code.err
else if code.subfuncs.length then ast.src = """
(function(){
Expand All @@ -250,6 +252,7 @@ class Code
})()
"""
else ast.src = if name? then "define('#{name}', #{code.main})" else "(#{code.main})"
ast.globals = code.global
ast

wrap = (ast, src)->
Expand All @@ -264,7 +267,7 @@ when _refId
if val.lambda then throw new Error("attempt to use lambda as a variable")
code = code.copyWith(nameSub val).reffedValue(deref)
if vars.find((v)-> v == val) then code.addVar(val)
else if global[nameSub(val)]? then code
else if global[nameSub(val)]? or code.global.find((v)-> v == val) then code
else code.addErr "Referenced free variable: #{val}, use lit, instead of ref."
when _litId
val = getLitVal ast
Expand Down Expand Up @@ -327,33 +330,31 @@ when _primId

getNthBody = (ast, n)-> if n == 1 then ast else getNthBody(getLambdaBody(ast), n - 1)

compileLine = (line)->
compileLine = (line, globals)->
if line.match commentPat then line = ''
if true
def = line.match linePat
expr = (if def then def[3] else line).trim()
if expr
nm = if def and def[1] then def[1].trim().split(/\s+/) else null
ast = null
if nm
astsByName[nm[0]] = 1
if def then defineToken(nm[0], def[2])
ast = parse(prefix(nm, 1, expr, []))
bod = ast
if nm.length > 1
bod = getNthBody(ast, nm.length)
addAst(ast)
if getAstType(bod) == _lambdaId
bod.type = nm[0]
ast.dataType = nm[0]
nameAst(nm[0], ast)
dgen(ast, false, nm[0])
if nm.length == 1 then nameAst(nm[0], ast)
else
ast = parse(expr)
dgen(ast)
ast
else console.log("comment: #{line}")
def = line.match linePat
expr = (if def then def[3] else line).trim()
if expr
nm = if def and def[1] then def[1].trim().split(/\s+/) else null
ast = null
if nm
astsByName[nm[0]] = 1
if def then defineToken(nm[0], def[2])
ast = parse(prefix(nm, 1, expr, []))
bod = ast
if nm.length > 1
bod = getNthBody(ast, nm.length)
addAst(ast)
if getAstType(bod) == _lambdaId
bod.type = nm[0]
ast.dataType = nm[0]
nameAst(nm[0], ast)
dgen(ast, false, nm[0], globals)
if nm.length == 1 then nameAst(nm[0], ast)
else
ast = parse(expr)
dgen(ast, null, null, globals)
ast

evalLine = (line)->
ast = compileLine line
Expand Down Expand Up @@ -454,3 +455,6 @@ when _primId
root.define = define
root.getAstType = getAstType
root.getType = getType
root.linePat = linePat
root.Nil = Nil
root.cons = cons
83 changes: 47 additions & 36 deletions lazp.js
Expand Up @@ -461,29 +461,35 @@ misrepresented as being the original software.

Code = (function() {

function Code(main, subfuncs, fcount, mcount, vars, err) {
var _ref, _ref2, _ref3, _ref4, _ref5;
function Code(main, subfuncs, fcount, mcount, vars, err, global) {
var _ref, _ref2, _ref3, _ref4, _ref5, _ref6;
this.main = main;
this.subfuncs = subfuncs;
this.fcount = fcount;
this.mcount = mcount;
this.vars = vars;
this.err = err;
this.global = global;
this.main = (_ref = this.main) != null ? _ref : '';
this.subfuncs = (_ref2 = this.subfuncs) != null ? _ref2 : '';
this.fcount = (_ref3 = this.fcount) != null ? _ref3 : 0;
this.mcount = (_ref4 = this.mcount) != null ? _ref4 : 0;
this.vars = (_ref5 = this.vars) != null ? _ref5 : Nil;
this.global = (_ref6 = this.global) != null ? _ref6 : Nil;
}

Code.prototype.copyWith = function copyWith(main, subfuncs, fcount, mcount, vars, err) {
return new Code(main != null ? main : this.main, subfuncs != null ? subfuncs : this.subfuncs, fcount != null ? fcount : this.fcount, mcount != null ? mcount : this.mcount, vars != null ? vars : this.vars, err != null ? err : this.err);
Code.prototype.copyWith = function copyWith(main, subfuncs, fcount, mcount, vars, err, global) {
return new Code(main != null ? main : this.main, subfuncs != null ? subfuncs : this.subfuncs, fcount != null ? fcount : this.fcount, mcount != null ? mcount : this.mcount, vars != null ? vars : this.vars, err != null ? err : this.err, global != null ? global : this.global);
};

Code.prototype.addErr = function addErr(e) {
return this.copyWith(null, null, null, null, null, "" + this.err + e + "\n");
};

Code.prototype.setGlobal = function setGlobal(v) {
return this.copyWith(null, null, null, null, null, null, v);
};

Code.prototype.addVar = function addVar(v) {
return this.copyWith(null, null, null, null, cons(v, this.vars), null);
};
Expand Down Expand Up @@ -548,18 +554,19 @@ misrepresented as being the original software.

})();

dgen = function dgen(ast, lazy, name) {
dgen = function dgen(ast, lazy, name, globals) {
var code, res;
ast.lits = [];
res = [];
code = (gen(ast, new Code(), ast.lits, (name != null ? cons(name, Nil) : Nil), true)).memo(!lazy);
code = (gen(ast, new Code().setGlobal(cons(name, globals != null ? globals : Nil)), ast.lits, Nil, true)).memo(!lazy);
if (code.err != null) {
ast.err = code.err;
} else if (code.subfuncs.length) {
ast.src = "(function(){\n " + code.subfuncs + "\n return " + (name != null ? "define('" + name + "', " + code.main + ")" : code.main) + "\n})()";
} else {
ast.src = name != null ? "define('" + name + "', " + code.main + ")" : "(" + code.main + ")";
}
ast.globals = code.global;
return ast;
};

Expand All @@ -584,7 +591,9 @@ misrepresented as being the original software.
return v === val;
})) {
return code.addVar(val);
} else if (global[nameSub(val)] != null) {
} else if ((global[nameSub(val)] != null) || code.global.find(function(v) {
return v === val;
})) {
return code;
} else {
return code.addErr("Referenced free variable: " + val + ", use lit, instead of ref.");
Expand Down Expand Up @@ -689,39 +698,35 @@ misrepresented as being the original software.
}
};

compileLine = function compileLine(line) {
compileLine = function compileLine(line, globals) {
var ast, bod, def, expr, nm;
if (line.match(commentPat)) line = '';
if (true) {
def = line.match(linePat);
expr = (def ? def[3] : line).trim();
if (expr) {
nm = def && def[1] ? def[1].trim().split(/\s+/) : null;
ast = null;
if (nm) {
astsByName[nm[0]] = 1;
if (def) defineToken(nm[0], def[2]);
ast = parse(prefix(nm, 1, expr, []));
bod = ast;
if (nm.length > 1) {
bod = getNthBody(ast, nm.length);
addAst(ast);
}
if (getAstType(bod) === _lambdaId) {
bod.type = nm[0];
ast.dataType = nm[0];
}
nameAst(nm[0], ast);
dgen(ast, false, nm[0]);
if (nm.length === 1) nameAst(nm[0], ast);
} else {
ast = parse(expr);
dgen(ast);
def = line.match(linePat);
expr = (def ? def[3] : line).trim();
if (expr) {
nm = def && def[1] ? def[1].trim().split(/\s+/) : null;
ast = null;
if (nm) {
astsByName[nm[0]] = 1;
if (def) defineToken(nm[0], def[2]);
ast = parse(prefix(nm, 1, expr, []));
bod = ast;
if (nm.length > 1) {
bod = getNthBody(ast, nm.length);
addAst(ast);
}
return ast;
if (getAstType(bod) === _lambdaId) {
bod.type = nm[0];
ast.dataType = nm[0];
}
nameAst(nm[0], ast);
dgen(ast, false, nm[0], globals);
if (nm.length === 1) nameAst(nm[0], ast);
} else {
ast = parse(expr);
dgen(ast, null, null, globals);
}
} else {
return console.log("comment: " + line);
return ast;
}
};

Expand Down Expand Up @@ -879,4 +884,10 @@ misrepresented as being the original software.

root.getType = getType;

root.linePat = linePat;

root.Nil = Nil;

root.cons = cons;

}).call(this);
17 changes: 3 additions & 14 deletions repl.cs
Expand Up @@ -57,26 +57,15 @@
stream = FS.createReadStream(file)
stream.on('data', (data)-> contents += data)
stream.on('end', ()->
generateCode(file, contents, !root.quiet)
out = Core.generateCode(file, contents, !root.quiet)
stream = FS.createWriteStream("#{Path.basename file, '.laz'}.js")
stream.end(out, 'utf8')
Core.next())
stream.on('error', (ex)->
console.log("Exception reading file: ", ex.stack)
Core.next())


generateCode = (file, contents, loud)->
if loud then console.log("Compiling #{file}:\n")
out = 'if (typeof require !== "undefined" && require !== null) {Lazp = require("./lazp")};\nsetId = Lazp.setId;\nsetType = Lazp.setType;\nsetDataType = Lazp.setDataType;\ndefine = Lazp.define;\n'
for line, i in contents.split('\n')
if line
ast = L.compileLine line
if ast
ast.src = "//AST: #{L.astPrint(ast)}\n#{ast.src}"
src = if ast.lazpName then ast.src else "console.log(String(#{ast.src}))"
out += "#{src};\n"
stream = FS.createWriteStream("#{Path.basename file, '.laz'}.js")
stream.end(out, 'utf8')

Core.setHelp help
Core.setCompiler compile
Core.setWriter (str)-> process.stdout.write(str)
Expand Down

0 comments on commit 2110e65

Please sign in to comment.