diff --git a/javascript/gflib.js b/javascript/gflib.js index fb8016ab..a570bbb3 100644 --- a/javascript/gflib.js +++ b/javascript/gflib.js @@ -5,7 +5,7 @@ function Fun(name) { } Fun.prototype.print = function () { return this.show(0); } ; Fun.prototype.show = function (prec) { - if (this.name == '?') { + if (this.isMeta()) { if (isUndefined(this.type)) { return '?'; } else { @@ -44,7 +44,22 @@ Fun.prototype.getChildren = function () { } return a; } ; - +Fun.prototype.isMeta = function() { + return this.name == '?'; +} ; +Fun.prototype.isComplete = function() { + if (this.isMeta()) { + return false; + } else { + var cs = this.getChildren(); + for (var i in cs) { + if (!cs[i].isComplete()) { + return false; + } + } + return true; + } +} ; /* Concrete syntax terms */ @@ -103,17 +118,13 @@ Abstract.prototype.copyTree = function(x, type) { return this.annotate(this.copyTree_(x), type); }; Abstract.prototype.copyTree_ = function(x) { - if (typeof x == 'string' && x == '?') { - return new Fun('?'); - } else { - var t = new Fun(x.name); - for (var i = 0; ; i++) { - var c = x['arg' + i]; - if (isUndefined(c)) { break; } - t.setChild(i, this.copyTree(c)); - } - return t; + var t = new Fun(x.name); + for (var i = 0; ; i++) { + var c = x['arg' + i]; + if (isUndefined(c)) { break; } + t.setChild(i, this.copyTree(c)); } + return t; } ; Abstract.prototype.parseTree = function(str, type) { return this.annotate(this.parseTree_(str.match(/[\w\']+|\(|\)|\?/g), 0), type); @@ -155,7 +166,7 @@ Concrete.prototype.addRule = function (name, f) { this.rules[name] = f; }; Concrete.prototype.lindef = function (cat, v) { return this.rules["_d"+cat]([new Str(v)]); } ; Concrete.prototype.linearize = function (tree) { return this.linearizeToTerm(tree).print(); }; Concrete.prototype.linearizeToTerm = function (tree) { - if (tree.name == '?') { + if (tree.isMeta()) { if (isUndefined(tree.type)) { return new Meta(); } else {