forked from GitHub/gf-core
Syntax editor: internal improvements. re-introduce initialize_from function
This commit is contained in:
@@ -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;
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user