Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
started on auto-rebuilding
  • Loading branch information
zot committed Apr 30, 2012
1 parent cfe87b9 commit b083ff4
Show file tree
Hide file tree
Showing 9 changed files with 118 additions and 66 deletions.
1 change: 1 addition & 0 deletions TODO.html
Expand Up @@ -19,6 +19,7 @@ <h1>TODO</h1>
<li>notebook style interface
<ul>
<li>collapse auto exprs</li>
<li>command completion</li>
<li>"save output as testcase" -- snapshot input and output as strings and record them as a testcase comment</li>
<li>highlighting fixes
<ul>
Expand Down
1 change: 1 addition & 0 deletions TODO.md
Expand Up @@ -2,6 +2,7 @@
# TODO
* notebook style interface
* collapse auto exprs
* command completion
* "save output as testcase" -- snapshot input and output as strings and record them as a testcase comment
* highlighting fixes
* defs don't work
Expand Down
4 changes: 3 additions & 1 deletion leisure.cs
Expand Up @@ -115,10 +115,12 @@ class CNil extends Cons

global.leisureGetFuncs = -> ll

global.noredefs = true

define = (name, func) ->
nm = nameSub(name)
func.leisureName = name
if ctx[nm]? then throw new Error("[DEF] Attempt to redefine definition: #{name}")
if global.noredefs and ctx[nm]? then throw new Error("[DEF] Attempt to redefine definition: #{name}")
f = -> func
ctx[nm] = ctx.leisureFuncs[nm] = f
(evalFunc 'leisureAddFunc')(name)
Expand Down
4 changes: 3 additions & 1 deletion leisure.js
Expand Up @@ -242,11 +242,13 @@ misrepresented as being the original software.
return ll;
};

global.noredefs = true;

define = function define(name, func) {
var f, nm;
nm = nameSub(name);
func.leisureName = name;
if (ctx[nm] != null) {
if (global.noredefs && (ctx[nm] != null)) {
throw new Error("[DEF] Attempt to redefine definition: " + name);
}
f = function f() {
Expand Down
73 changes: 46 additions & 27 deletions notebook.cs
Expand Up @@ -53,35 +53,37 @@ makeOutputBox bx
if !s.rangeCount then return
r = s.getRangeAt(0)
parent = getBox r.startContainer
focusBox parent
if !parent? or parent.getAttribute('LeisureOutput')? then return
tr = document.createRange()
tr.setStart parent, 0
tr.setEnd r.endContainer, r.endOffset
pos = getRangeText(tr).length
txt = parent.textContent
ast = (Leisure.compileNext txt, Leisure.Nil, true, null, true)[0]
offset = ast.leisureDefPrefix ? 0
brackets = Leisure.bracket ast, pos + offset
if oldBrackets[0] != parent or !oldBrackets[1].equals(brackets)
oldBrackets = [parent, brackets]
for node in document.querySelectorAll "[LeisureBrackets]"
unwrap node
parent.normalize()
if ast?
b = brackets
while b != Leisure.Nil
span = document.createElement 'span'
span.setAttribute 'LeisureBrackets', ''
span.setAttribute 'class', if b == brackets then 'LeisureFunc' else 'LeisureArg'
r = makeRange parent, b.head.head - offset, b.head.tail.head - offset
contents = r.cloneContents()
r.deleteContents()
r.insertNode span
span.appendChild contents
b = b.tail
s.removeAllRanges()
parent.normalize()
s.addRange(makeRange parent, pos, pos)
if ast?
offset = ast.leisureDefPrefix ? 0
brackets = Leisure.bracket ast, pos + offset
if oldBrackets[0] != parent or !oldBrackets[1].equals(brackets)
oldBrackets = [parent, brackets]
for node in document.querySelectorAll "[LeisureBrackets]"
unwrap node
parent.normalize()
if ast?
b = brackets
while b != Leisure.Nil
span = document.createElement 'span'
span.setAttribute 'LeisureBrackets', ''
span.setAttribute 'class', if b == brackets then 'LeisureFunc' else 'LeisureArg'
r = makeRange parent, b.head.head - offset, b.head.tail.head - offset
contents = r.cloneContents()
r.deleteContents()
r.insertNode span
span.appendChild contents
b = b.tail
s.removeAllRanges()
parent.normalize()
s.addRange(makeRange parent, pos, pos)

getRangeText = (r)-> r.cloneContents().textContent

Expand Down Expand Up @@ -127,7 +129,7 @@ toDefBox p
initNotebook = (el)->
el.replacing = true
removeOldDefs el
pgm = markupDefs findDefs el
pgm = markupDefs el, findDefs el
if !(el?.lastChild?.nodeType == 3 and el.lastChild.data[el.lastChild.data.length - 1] == '\n')
el.appendChild textNode('\n')
el.appendChild textNode('\n')
Expand All @@ -137,7 +139,7 @@ el.appendChild textNode('\n')
insertControls(el)
pgm

makeLabel = (text, c)->
makeLabel = (text, c)->
node = document.createElement 'SPAN'
node.innerHTML = text
node.setAttribute 'class', c
Expand Down Expand Up @@ -265,7 +267,7 @@ unwrap node
if txt?.nodeType == 3 and (m = txt.data.match /(^|[^\n])(\n+)$/)
txt.data = txt.data.substring(0, txt.data.length - m[2].length)

markupDefs = (defs)->
markupDefs = (el, defs)->
pgm = ''
auto = ''
for i in defs
Expand All @@ -278,6 +280,8 @@ bod.appendChild textNode('\n')
bx.appendChild (codeSpan name, 'codeName')
bx.appendChild (textNode(def))
bx.appendChild bod
bx.addEventListener 'blur', (-> evalDoc el), true, true
bx.leisureOwner = el
pgm += "#{name} #{def} #{body}\n"
else if main.leisureTest
s = codeSpan body, 'codeTest'
Expand All @@ -286,13 +290,15 @@ s.appendChild textNode('\n')
bx = box main, 'codeMainTest', true
bx.setAttribute 'class', 'codeMainTest green'
bx.appendChild s
bx.leisureOwner = el
else
if main.leisureAuto then auto += "#{body}\n"
s = codeSpan body, 'codeExpr'
s.appendChild textNode('\n')
s.setAttribute('generatedNL', '')
bx = box main, 'codeMainExpr', true
bx.appendChild s
bx.leisureOwner = el
makeOutputBox(bx)
for test in tests
console.log "TEST: #{JSON.stringify(test.leisureTest)}"
Expand All @@ -302,6 +308,7 @@ bx.appendChild s

evalOutput = (exBox)->
exBox = getBox exBox
focusBox exBox
cleanOutput exBox
d = document.createElement('div')
d.setAttribute 'style', 'float: right'
Expand Down Expand Up @@ -357,6 +364,7 @@ bx.appendChild s
node.setAttribute 'class', 'output'
node.setAttribute 'contentEditable', 'false'
node.source = source
node.leisureOwner = source.leisureOwner
source.output = node
node.innerHTML = "<div><div style='float: left'><button onclick='Notebook.evalOutput(this)'>-&gt;</button></div><button style='visibility: hidden'></button></div>"
source.parentNode.insertBefore node, source.nextSibling
Expand Down Expand Up @@ -494,15 +502,26 @@ nodeEnd child

queueAfterLoad = (func)-> postLoadQueue.push(func)

###
# handle focus manually, because focus and blur events don't seem to work in this case
###

oldFocus = null

focusBox = (box)->
if oldFocus?.classList.contains 'codeMain' then evalDoc(box.leisureOwner)
oldFocus = box

evalDoc = (el)->
[pgm, auto] = initNotebook(el)
try
if auto
auto = "do\n #{auto.trim().replace /\n/, '\n '}\n finishLoading 'fred'"
global.noredefs = false
Notebook.queueAfterLoad ->
Leisure.processDefs(Leisure.eval(ReplCore.generateCode('_doc', pgm, false)), global)
Leisure.processDefs(Leisure.eval(ReplCore.generateCode('_doc', pgm, false, false, false)), global)
Leisure.eval(ReplCore.generateCode('_auto', auto, false))
else Leisure.processDefs(Leisure.eval(ReplCore.generateCode('_doc', pgm, false)), global)
else Leisure.processDefs(Leisure.eval(ReplCore.generateCode('_doc', pgm, false, false, false)), global)
catch err
alert(err.stack)

Expand Down
85 changes: 55 additions & 30 deletions notebook.js
Expand Up @@ -4,7 +4,7 @@
*/

(function() {
var Leisure, Prim, ReplCore, addsLine, bindNotebook, box, changeTheme, changeView, checkMutateFromModification, checkMutateToDef, cleanOutput, codeBox, codeSpan, configureSaveLink, continueRangePosition, createFragment, createNode, delay, envFor, evalDoc, evalOutput, findDefs, getBox, getRangePosition, getRangeText, getRanges, grp, highlightPosition, initNotebook, insertControls, loadProgram, makeLabel, makeOption, makeOutputBox, makeRange, makeTestBox, makeTestCase, markupDefs, nodeEnd, oldBrackets, postLoadQueue, prepExpr, queueAfterLoad, removeOldDefs, req, root, runTests, selInDef, testPat, textNode, toDefBox, toExprBox, unwrap,
var Leisure, Prim, ReplCore, addsLine, bindNotebook, box, changeTheme, changeView, checkMutateFromModification, checkMutateToDef, cleanOutput, codeBox, codeSpan, configureSaveLink, continueRangePosition, createFragment, createNode, delay, envFor, evalDoc, evalOutput, findDefs, focusBox, getBox, getRangePosition, getRangeText, getRanges, grp, highlightPosition, initNotebook, insertControls, loadProgram, makeLabel, makeOption, makeOutputBox, makeRange, makeTestBox, makeTestCase, markupDefs, nodeEnd, oldBrackets, oldFocus, postLoadQueue, prepExpr, queueAfterLoad, removeOldDefs, req, root, runTests, selInDef, testPat, textNode, toDefBox, toExprBox, unwrap,
__indexOf = Array.prototype.indexOf || function(item) { for (var i = 0, l = this.length; i < l; i++) { if (i in this && this[i] === item) return i; } return -1; };

if ((typeof window !== "undefined" && window !== null) && (!(typeof global !== "undefined" && global !== null) || global === window)) {
Expand Down Expand Up @@ -85,6 +85,7 @@
if (!s.rangeCount) return;
r = s.getRangeAt(0);
parent = getBox(r.startContainer);
focusBox(parent);
if (!(parent != null) || (parent.getAttribute('LeisureOutput') != null)) {
return;
}
Expand All @@ -94,33 +95,35 @@
pos = getRangeText(tr).length;
txt = parent.textContent;
ast = (Leisure.compileNext(txt, Leisure.Nil, true, null, true))[0];
offset = (_ref = ast.leisureDefPrefix) != null ? _ref : 0;
brackets = Leisure.bracket(ast, pos + offset);
if (oldBrackets[0] !== parent || !oldBrackets[1].equals(brackets)) {
oldBrackets = [parent, brackets];
_ref2 = document.querySelectorAll("[LeisureBrackets]");
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
node = _ref2[_i];
unwrap(node);
}
parent.normalize();
if (ast != null) {
b = brackets;
while (b !== Leisure.Nil) {
span = document.createElement('span');
span.setAttribute('LeisureBrackets', '');
span.setAttribute('class', b === brackets ? 'LeisureFunc' : 'LeisureArg');
r = makeRange(parent, b.head.head - offset, b.head.tail.head - offset);
contents = r.cloneContents();
r.deleteContents();
r.insertNode(span);
span.appendChild(contents);
b = b.tail;
if (ast != null) {
offset = (_ref = ast.leisureDefPrefix) != null ? _ref : 0;
brackets = Leisure.bracket(ast, pos + offset);
if (oldBrackets[0] !== parent || !oldBrackets[1].equals(brackets)) {
oldBrackets = [parent, brackets];
_ref2 = document.querySelectorAll("[LeisureBrackets]");
for (_i = 0, _len = _ref2.length; _i < _len; _i++) {
node = _ref2[_i];
unwrap(node);
}
parent.normalize();
if (ast != null) {
b = brackets;
while (b !== Leisure.Nil) {
span = document.createElement('span');
span.setAttribute('LeisureBrackets', '');
span.setAttribute('class', b === brackets ? 'LeisureFunc' : 'LeisureArg');
r = makeRange(parent, b.head.head - offset, b.head.tail.head - offset);
contents = r.cloneContents();
r.deleteContents();
r.insertNode(span);
span.appendChild(contents);
b = b.tail;
}
}
s.removeAllRanges();
parent.normalize();
return s.addRange(makeRange(parent, pos, pos));
}
s.removeAllRanges();
parent.normalize();
return s.addRange(makeRange(parent, pos, pos));
}
};

Expand Down Expand Up @@ -188,7 +191,7 @@
var pgm, _ref;
el.replacing = true;
removeOldDefs(el);
pgm = markupDefs(findDefs(el));
pgm = markupDefs(el, findDefs(el));
if (!((el != null ? (_ref = el.lastChild) != null ? _ref.nodeType : void 0 : void 0) === 3 && el.lastChild.data[el.lastChild.data.length - 1] === '\n')) {
el.appendChild(textNode('\n'));
el.appendChild(textNode('\n'));
Expand Down Expand Up @@ -373,7 +376,7 @@
}
};

markupDefs = function markupDefs(defs) {
markupDefs = function markupDefs(el, defs) {
var auto, bod, body, bx, def, i, main, name, pgm, s, test, tests, _i, _j, _len, _len2;
pgm = '';
auto = '';
Expand All @@ -388,6 +391,10 @@
bx.appendChild(codeSpan(name, 'codeName'));
bx.appendChild(textNode(def));
bx.appendChild(bod);
bx.addEventListener('blur', (function() {
return evalDoc(el);
}), true, true);
bx.leisureOwner = el;
pgm += "" + name + " " + def + " " + body + "\n";
} else if (main.leisureTest) {
s = codeSpan(body, 'codeTest');
Expand All @@ -396,13 +403,15 @@
bx = box(main, 'codeMainTest', true);
bx.setAttribute('class', 'codeMainTest green');
bx.appendChild(s);
bx.leisureOwner = el;
} else {
if (main.leisureAuto) auto += "" + body + "\n";
s = codeSpan(body, 'codeExpr');
s.appendChild(textNode('\n'));
s.setAttribute('generatedNL', '');
bx = box(main, 'codeMainExpr', true);
bx.appendChild(s);
bx.leisureOwner = el;
makeOutputBox(bx);
}
for (_j = 0, _len2 = tests.length; _j < _len2; _j++) {
Expand All @@ -420,6 +429,7 @@
evalOutput = function evalOutput(exBox) {
var d;
exBox = getBox(exBox);
focusBox(exBox);
cleanOutput(exBox);
d = document.createElement('div');
d.setAttribute('style', 'float: right');
Expand Down Expand Up @@ -505,6 +515,7 @@
node.setAttribute('class', 'output');
node.setAttribute('contentEditable', 'false');
node.source = source;
node.leisureOwner = source.leisureOwner;
source.output = node;
node.innerHTML = "<div><div style='float: left'><button onclick='Notebook.evalOutput(this)'>-&gt;</button></div><button style='visibility: hidden'></button></div>";
source.parentNode.insertBefore(node, source.nextSibling);
Expand Down Expand Up @@ -714,18 +725,32 @@
return postLoadQueue.push(func);
};

/*
# handle focus manually, because focus and blur events don't seem to work in this case
*/

oldFocus = null;

focusBox = function focusBox(box) {
if (oldFocus != null ? oldFocus.classList.contains('codeMain') : void 0) {
evalDoc(box.leisureOwner);
}
return oldFocus = box;
};

evalDoc = function evalDoc(el) {
var auto, pgm, _ref;
_ref = initNotebook(el), pgm = _ref[0], auto = _ref[1];
try {
if (auto) {
auto = "do\n " + (auto.trim().replace(/\n/, '\n ')) + "\n finishLoading 'fred'";
global.noredefs = false;
Notebook.queueAfterLoad(function() {
return Leisure.processDefs(Leisure.eval(ReplCore.generateCode('_doc', pgm, false)), global);
return Leisure.processDefs(Leisure.eval(ReplCore.generateCode('_doc', pgm, false, false, false)), global);
});
return Leisure.eval(ReplCore.generateCode('_auto', auto, false));
} else {
return Leisure.processDefs(Leisure.eval(ReplCore.generateCode('_doc', pgm, false)), global);
return Leisure.processDefs(Leisure.eval(ReplCore.generateCode('_doc', pgm, false, false, false)), global);
}
} catch (err) {
return alert(err.stack);
Expand Down
4 changes: 2 additions & 2 deletions replCore.cs
Expand Up @@ -123,7 +123,7 @@ processResult result

escape = (str)-> str.replace(/\n/g, '\\n')

generateCode = (file, contents, loud, handle, nomacros)->
generateCode = (file, contents, loud, handle, nomacros, check)->
if loud then console.log("Compiling #{file}:\n")
objName = if file? and file.match /\.lsr$/ then file.substring(0, file.length - 4) else file ? '_anonymous'
out = """
Expand Down Expand Up @@ -168,7 +168,7 @@ processResult result
while rest and rest.trim()
if loud > 1 and prev != names and names != Leisure.Nil then console.log "Compiling function: #{names.head}"
oldRest = rest
[ast, err, rest] = Leisure.compileNext rest, globals, null, false, nomacros
[ast, err, rest] = Leisure.compileNext rest, globals, null, check, nomacros
if ast?.leisureName?
prev = ast.leisureName
names = names.tail
Expand Down

0 comments on commit b083ff4

Please sign in to comment.