1
0
forked from GitHub/gf-core

Syntax editor: internal improvements. re-introduce initialize_from function

This commit is contained in:
john.j.camilleri
2012-11-29 15:40:18 +00:00
parent c3f82bf10f
commit 8cefec807a
2 changed files with 67 additions and 25 deletions

View File

@@ -5,10 +5,12 @@ function NodeID(x) {
// Initialize from input // Initialize from input
if (x) { if (x) {
switch (typeof x) { var type = Object.prototype.toString.call(x);
case "number": this.id = [x]; break; switch (type) {
case "string": this.id = map(function(s){return parseInt(s)}, x.split(",")); break; case "[object Number]": this.id = [x]; break;
case "object": this.id = Array.clone(x.get()); break; // another NodeID case "[object String]": this.id = map(function(s){return parseInt(s)}, x.split(",")); break;
case "[object Array]" : this.id = Array.clone(x); break;
case "[object Object]": this.id = Array.clone(x.get()); break; // another NodeID
} }
} }
@@ -28,6 +30,11 @@ function NodeID(x) {
return JSON.stringify(this.id)==JSON.stringify(other.id); return JSON.stringify(this.id)==JSON.stringify(other.id);
} }
// clone
this.clone = function() {
return new NodeID( this );
}
} }
/* --- Abstract Syntax Tree (with state)------------------------------------- */ /* --- Abstract Syntax Tree (with state)------------------------------------- */
@@ -62,6 +69,7 @@ function AST(fun, cat) {
return new ASTNode({ return new ASTNode({
"fun": fun, "fun": fun,
"cat": cat, "cat": cat,
"deps": {}, // dependent types
"children": [] "children": []
}); });
} }
@@ -70,6 +78,9 @@ function AST(fun, cat) {
this.current = new NodeID(); // current id in tree this.current = new NodeID(); // current id in tree
this.getCurrent = function() {
return this.find(this.current);
}
this.getFun = function() { this.getFun = function() {
return this.find(this.current).fun; return this.find(this.current).fun;
} }
@@ -83,9 +94,24 @@ function AST(fun, cat) {
this.find(this.current).cat = c; this.find(this.current).cat = c;
} }
// Add a single type dependency at current node
this.addDep = function(k, type) {
// Add unassigned type variable to current
var cur = this.getCurrent();
cur.deps[k] = null;
// Add actual type dep node
var node = newNode(k, type);
node.depid = k; // links to dep in parent
this._add(this.current, node);
return node;
}
// Add a single fun at current node // Add a single fun at current node
this.add = function(fun, cat) { this.add = function(fun, cat) {
this._add(this.current, newNode(fun,cat)); var node = newNode(fun,cat);
this._add(this.current, node);
return node;
} }
// add node as child of id // add node as child of id
@@ -117,14 +143,12 @@ function AST(fun, cat) {
} }
// id should be a list of child indices [0,1,0]
// or a string separated by commas "0,1,0"
this.find = function(id) { this.find = function(id) {
var lid = undefined var lid = undefined
switch (typeof id) { if (Object.prototype.toString.call(id) == "[object Object]") {
case "number": lid = [id]; break; lid = Array.clone( id.get() );
case "string": lid = id.split(","); break; } else {
case "object": lid = Array.clone(id.get()); break; // clone NodeID array alert("non-NodeID passed to AST.find()");
} }
var node = this.root; var node = this.root;
if (lid[0] == 0) lid.shift(); if (lid[0] == 0) lid.shift();
@@ -165,6 +189,13 @@ function AST(fun, cat) {
} }
} }
// Return parent of current node
this.getParent = function(i) {
var parent_id = this.current.clone();
parent_id.get().pop();
return this.find(parent_id);
}
// Move current id to child number i // Move current id to child number i
this.toChild = function(i) { this.toChild = function(i) {
this.current.add(i); this.current.add(i);
@@ -219,20 +250,27 @@ AST.parse_type_signature = function(str) {
var ix = str.indexOf(":"); var ix = str.indexOf(":");
// judgement type // judgement type
var bits = str.substr(0, ix).split(" "); var bits = str.substr(0, ix).trim().split(" ");
obj.type = bits[0]; obj.type = bits[0];
// name (possibly with constructors) // name (possibly with constructors)
obj.name = bits.slice(1); obj.name = bits.slice(1);
// function args (possibly with type dependency) // function args (possibly with type dependency)
var regex_dep = new RegExp(/\(\s*(.+?)\s*:\s*(.+?)\s*\)/);
var bits = map(function(s){return s.trim()}, str.substr(ix+1).split("->")); var bits = map(function(s){return s.trim()}, str.substr(ix+1).split("->"));
for (var i=0 ; i<bits.length-1; i++) { for (var i=0 ; i<bits.length-1; i++) {
var bit = bits[i]; var bit = bits[i];
obj.args.push(bit); var m = regex_dep.exec(bit);
if (m == null) {
obj.args.push(bit);
} else {
// We have a type dependency
obj.deps.push({ "id": m[1], "type": m[2] });
}
} }
// return type //return type
obj.ret = bits[bits.length-1]; obj.ret = bits[bits.length-1];
return obj; return obj;

View File

@@ -100,15 +100,11 @@ Editor.prototype.get_startcat=function() {
return this.gm.startcat; return this.gm.startcat;
} }
// TODO Editor.prototype.initialize_from=function(opts) {
// Editor.prototype.initialize_from=function(opts) { var t=this;
// var t=this; if (opts.abstr)
// if (opts.startcat) t.import_ast(opts.abstr);
// t.options.initial_startcat=opts.startcat; }
// t.change_grammar();
// if (opts.abstr)
// t.import_ast(opts.abstr);
// }
// Called after changing grammar or startcat // Called after changing grammar or startcat
Editor.prototype.start_fresh=function () { Editor.prototype.start_fresh=function () {
@@ -125,6 +121,7 @@ Editor.prototype.start_fresh=function () {
Editor.prototype.get_refinements=function(cat) { Editor.prototype.get_refinements=function(cat) {
var t = this; var t = this;
t.ui.refinements.innerHTML = "...";
if (cat == undefined) if (cat == undefined)
cat = t.ast.getCat(); cat = t.ast.getCat();
var args = { var args = {
@@ -192,7 +189,6 @@ Editor.prototype.get_refinements=function(cat) {
Editor.prototype.select_refinement=function(fun) { Editor.prototype.select_refinement=function(fun) {
var t = this; var t = this;
t.ui.refinements.innerHTML = "...";
t.ast.removeChildren(); t.ast.removeChildren();
t.ast.setFun(fun); t.ast.setFun(fun);
@@ -200,8 +196,15 @@ Editor.prototype.select_refinement=function(fun) {
var def = t.grammar_constructors.funs[fun].def; var def = t.grammar_constructors.funs[fun].def;
var typeobj = AST.parse_type_signature(def); var typeobj = AST.parse_type_signature(def);
// Add dependent type placeholders
if (typeobj.deps.length > 0) {
for (var i in typeobj.deps) {
t.ast.addDep(typeobj.deps[i].id, typeobj.deps[i].type);
}
}
// Add function argument placeholders
if (typeobj.args.length > 0) { if (typeobj.args.length > 0) {
// Add placeholders
for (var i in typeobj.args) { for (var i in typeobj.args) {
t.ast.add(null, typeobj.args[i]); t.ast.add(null, typeobj.args[i]);
} }
@@ -212,6 +215,7 @@ Editor.prototype.select_refinement=function(fun) {
t.update_linearisation(); t.update_linearisation();
// Select next hole & get its refinements // Select next hole & get its refinements
t.ui.refinements.innerHTML = "...";
t.ast.toNextHole(); t.ast.toNextHole();
t.update_current_node(); t.update_current_node();
} }