Painting

by lmeyerov

HTML

<script src="http://www.eecs.berkeley.edu/~lmeyerov/projects/pbrowser/pubfiles/tip/render.js"></script>
<script src="http://www.flapjax-lang.org/download/flapjax-2.1.js"></script>
<script src="http://www.eecs.berkeley.edu/~lmeyerov/projects/pbrowser/pubfiles/tip/runSelectors.js"></script>
<script src="http://www.eecs.berkeley.edu/~lmeyerov/projects/pbrowser/pubfiles/tip/DOMToRender.js"></script>
<script src="http://www.eecs.berkeley.edu/~lmeyerov/projects/pbrowser/pubfiles/tip/sizzle.js"></script>
<style id="documentStyle">
    * { refName: nextNode; }
    Binary > * { refName: left; }
    Binary > * + * { refName: right; }
    Nary > * { refName: childs }
</style>

<Root id="document">
<Intermediate>
  <Nary>
    <Last></Last>
    <Last></Last>
    <Intermediate>
      <Last></Last>
    </Intermediate>
  </Nary>
</Intermediate>
</Root>

<script type="text/superconductor">
interface Top { }
class Root : Top { 
  children { nextNode : Node }
  attributes { 
    var screen : int;  
  }
  actions {
     screen := paintStart(100, 100) + paintRect(20, 20, 30, 50, "red", 0) + paintLine(0, 10, 20, 100, "blue");
  }    
}    
interface Node { var numAfter : int; }
  
class Last : Node { 
  actions { numAfter := 1; }
}   

class Intermediate : Node {
  children { nextNode : Node; }
  actions { numAfter := nextNode.numAfter + 1; }
}
    
class Binary : Node {
   children { left: Node; right: Node; }
   actions { numAfter := left.numAfter + right.numAfter + 1; }
}
    
class Nary : Node {
    children { childs : [ Node ] }
    actions {
      loop childs {
        numAfter := fold 1 .. self$-.numAfter + childs$i.numAfter;
      }
    }
}
    
    
</script>

CSS

textarea { width: 100%; height: 200px; }
    canvas { border: 1px dashed gray; width: 400px; height: 400px;  float: left }
    pre { float: left; margin-left: 1em }
    h2 { float: none; clear: both; }

JavaScript

/* init html extras */
(function () {
window.layout = function () {};
insertDomB(
    DIV(P(INPUT({type: "button", id: "compile", value: "synthesize script"}),
          SPAN({id: 'status'})),
        P(H2("Data"),
          CANVAS({id: "solution", width: 400, height: 400}),
          PRE({id:"dump"})),
        P(H2("Generated JavaScript"),
          PRE({id:"engine", style: {float: "none"}}))),
    document.body, 'end');

    var s = document.createElement('script');
    s.id = 'layoutEngine';
    document.body.appendChild(s);
    })();

/* list demo */
console.log("\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\npage load");
logger = {log: function () {}};
/* setup for sizzle */
state = undefined;

attrMap = {};
otherAttrs = [];

/* ajax */
var outE = receiverE();
$E('compile', 'click').mapE(function() {

    var src = $(document).getElements('script[type*=superconductor]').get('text')[0];
    
    var myRequest = new Request({
        url: 'http://ftl.eecs.berkeley.edu/response.php',
        method: 'post',
        data: {
            'src': src
        },
        onSuccess: function(text, xml) {
            console.log(text);
            console.log("received from server: " + text.length + " characters");
            if (text.substring(0,6) == "error:")
                console.error("Synthesis error: " + text.substring(6));
            else
                outE.sendEvent(text);
        }
    }).send();
});

window.layoutE = receiverE();
outE.mapE(function (src) { 
    var p = $('layoutEngine');
    if (p) document.body.removeChild(p);
    var s = document.createElement('script');
    s.text = src + "; window.layoutE.sendEvent(layout);";
    s.id = 'layoutEngine';
    document.body.appendChild(s);
});


var numRequestsB = $E('compile', 'click').collectE(0, function (_, acc) { return acc + 1; }).startsWith(0);
var numResponsesB = outE.collectE(0, function (_, acc) { return acc + 1; }).startsWith(0);
var isOffB = liftB(function (a,b) { return a != b; }, numRequestsB,...