mirror of
https://github.com/GrammaticalFramework/gf-core.git
synced 2026-09-27 04:33:38 -06:00
Merge branch 'master' of https://github.com/GrammaticalFramework/gf-core
This commit is contained in:
@@ -0,0 +1,7 @@
|
||||
# Deprecation notice
|
||||
|
||||
As of June 2019, this JavaScript version of the GF runtime is considered deprecated,
|
||||
in favour of the TypeScript version in `../typescript/gflib.ts`.
|
||||
|
||||
If you don't want/need TypeScript and are just looking for a ready-to-use JavaScript version,
|
||||
see `../typescript/js/gflib.js` which is generated directly from the TypeScript version.
|
||||
+332
-332
@@ -1,38 +1,38 @@
|
||||
|
||||
function GFGrammar(abstract, concretes) {
|
||||
this.abstract = abstract;
|
||||
this.concretes = concretes;
|
||||
this.abstract = abstract;
|
||||
this.concretes = concretes;
|
||||
}
|
||||
|
||||
/* Translates a string from any concrete syntax to all concrete syntaxes.
|
||||
Uses the start category of the grammar.
|
||||
*/
|
||||
GFGrammar.prototype.translate = function (input, fromLang, toLang) {
|
||||
var outputs = new Object();
|
||||
var fromConcs = this.concretes;
|
||||
if (fromLang) {
|
||||
fromConcs = new Object();
|
||||
fromConcs[fromLang] = this.concretes[fromLang];
|
||||
}
|
||||
var toConcs = this.concretes;
|
||||
if (toLang) {
|
||||
toConcs = new Object();
|
||||
toConcs[toLang] = this.concretes[toLang];
|
||||
}
|
||||
for (var c1 in fromConcs) {
|
||||
var concrete = this.concretes[c1];
|
||||
var trees = concrete.parseString(input, this.abstract.startcat);
|
||||
if (trees.length > 0) {
|
||||
outputs[c1] = new Array();
|
||||
for (var i in trees) {
|
||||
outputs[c1][i] = new Object();
|
||||
for (var c2 in toConcs) {
|
||||
outputs[c1][i][c2] = this.concretes[c2].linearize(trees[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return outputs;
|
||||
var outputs = new Object();
|
||||
var fromConcs = this.concretes;
|
||||
if (fromLang) {
|
||||
fromConcs = new Object();
|
||||
fromConcs[fromLang] = this.concretes[fromLang];
|
||||
}
|
||||
var toConcs = this.concretes;
|
||||
if (toLang) {
|
||||
toConcs = new Object();
|
||||
toConcs[toLang] = this.concretes[toLang];
|
||||
}
|
||||
for (var c1 in fromConcs) {
|
||||
var concrete = this.concretes[c1];
|
||||
var trees = concrete.parseString(input, this.abstract.startcat);
|
||||
if (trees.length > 0) {
|
||||
outputs[c1] = new Array();
|
||||
for (var i in trees) {
|
||||
outputs[c1][i] = new Object();
|
||||
for (var c2 in toConcs) {
|
||||
outputs[c1][i][c2] = this.concretes[c2].linearize(trees[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return outputs;
|
||||
}
|
||||
|
||||
|
||||
@@ -47,56 +47,56 @@ String.prototype.setTag = function (tag) { this.tag = tag; };
|
||||
|
||||
/* Abstract syntax trees */
|
||||
function Fun(name) {
|
||||
this.name = name;
|
||||
this.args = new Array();
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
this.args[i-1] = arguments[i];
|
||||
}
|
||||
this.name = name;
|
||||
this.args = new Array();
|
||||
for (var i = 1; i < arguments.length; i++) {
|
||||
this.args[i-1] = arguments[i];
|
||||
}
|
||||
}
|
||||
Fun.prototype.print = function () { return this.show(0); } ;
|
||||
Fun.prototype.show = function (prec) {
|
||||
if (this.isMeta()) {
|
||||
if (isUndefined(this.type)) {
|
||||
return '?';
|
||||
} else {
|
||||
var s = '?:' + this.type;
|
||||
if (prec > 0) {
|
||||
s = "(" + s + ")" ;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
} else {
|
||||
var s = this.name;
|
||||
var cs = this.args;
|
||||
for (var i in cs) {
|
||||
s += " " + (isUndefined(cs[i]) ? "undefined" : cs[i].show(1));
|
||||
}
|
||||
if (prec > 0 && cs.length > 0) {
|
||||
s = "(" + s + ")" ;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
if (this.isMeta()) {
|
||||
if (isUndefined(this.type)) {
|
||||
return '?';
|
||||
} else {
|
||||
var s = '?:' + this.type;
|
||||
if (prec > 0) {
|
||||
s = "(" + s + ")" ;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
} else {
|
||||
var s = this.name;
|
||||
var cs = this.args;
|
||||
for (var i in cs) {
|
||||
s += " " + (isUndefined(cs[i]) ? "undefined" : cs[i].show(1));
|
||||
}
|
||||
if (prec > 0 && cs.length > 0) {
|
||||
s = "(" + s + ")" ;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
};
|
||||
Fun.prototype.getArg = function (i) {
|
||||
return this.args[i];
|
||||
return this.args[i];
|
||||
};
|
||||
Fun.prototype.setArg = function (i,c) {
|
||||
this.args[i] = c;
|
||||
this.args[i] = c;
|
||||
};
|
||||
Fun.prototype.isMeta = function() {
|
||||
return this.name == '?';
|
||||
return this.name == '?';
|
||||
} ;
|
||||
Fun.prototype.isComplete = function() {
|
||||
if (this.isMeta()) {
|
||||
return false;
|
||||
} else {
|
||||
for (var i in this.args) {
|
||||
if (!this.args[i].isComplete()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
if (this.isMeta()) {
|
||||
return false;
|
||||
} else {
|
||||
for (var i in this.args) {
|
||||
if (!this.args[i].isComplete()) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
} ;
|
||||
Fun.prototype.isLiteral = function() {
|
||||
return (/^[\"\-\d]/).test(this.name);
|
||||
@@ -127,98 +127,98 @@ Fun.prototype.isEqual = function(obj) {
|
||||
/* Type annotation */
|
||||
|
||||
function GFAbstract(startcat, types) {
|
||||
this.startcat = startcat;
|
||||
this.types = types;
|
||||
this.startcat = startcat;
|
||||
this.types = types;
|
||||
}
|
||||
GFAbstract.prototype.addType = function(fun, args, cat) {
|
||||
this.types[fun] = new Type(args, cat);
|
||||
this.types[fun] = new Type(args, cat);
|
||||
} ;
|
||||
GFAbstract.prototype.getArgs = function(fun) {
|
||||
return this.types[fun].args;
|
||||
return this.types[fun].args;
|
||||
}
|
||||
GFAbstract.prototype.getCat = function(fun) {
|
||||
return this.types[fun].cat;
|
||||
return this.types[fun].cat;
|
||||
};
|
||||
GFAbstract.prototype.annotate = function(tree, type) {
|
||||
if (tree.name == '?') {
|
||||
tree.type = type;
|
||||
} else {
|
||||
var typ = this.types[tree.name];
|
||||
for (var i in tree.args) {
|
||||
this.annotate(tree.args[i], typ.args[i]);
|
||||
}
|
||||
}
|
||||
return tree;
|
||||
if (tree.name == '?') {
|
||||
tree.type = type;
|
||||
} else {
|
||||
var typ = this.types[tree.name];
|
||||
for (var i in tree.args) {
|
||||
this.annotate(tree.args[i], typ.args[i]);
|
||||
}
|
||||
}
|
||||
return tree;
|
||||
} ;
|
||||
GFAbstract.prototype.handleLiterals = function(tree, type) {
|
||||
if (tree.name != '?') {
|
||||
if (type == "String" || type == "Int" || type == "Float") {
|
||||
tree.name = type + "_Literal_" + tree.name;
|
||||
} else {
|
||||
var typ = this.types[tree.name];
|
||||
for (var i in tree.args) {
|
||||
this.handleLiterals(tree.args[i], typ.args[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return tree;
|
||||
if (tree.name != '?') {
|
||||
if (type == "String" || type == "Int" || type == "Float") {
|
||||
tree.name = type + "_Literal_" + tree.name;
|
||||
} else {
|
||||
var typ = this.types[tree.name];
|
||||
for (var i in tree.args) {
|
||||
this.handleLiterals(tree.args[i], typ.args[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
return tree;
|
||||
} ;
|
||||
/* Hack to get around the fact that our SISR doesn't build real Fun objects. */
|
||||
GFAbstract.prototype.copyTree = function(x) {
|
||||
var t = new Fun(x.name);
|
||||
if (!isUndefined(x.type)) {
|
||||
t.type = x.type;
|
||||
}
|
||||
var cs = x.args;
|
||||
if (!isUndefined(cs)) {
|
||||
for (var i in cs) {
|
||||
t.setArg(i, this.copyTree(cs[i]));
|
||||
}
|
||||
}
|
||||
return t;
|
||||
var t = new Fun(x.name);
|
||||
if (!isUndefined(x.type)) {
|
||||
t.type = x.type;
|
||||
}
|
||||
var cs = x.args;
|
||||
if (!isUndefined(cs)) {
|
||||
for (var i in cs) {
|
||||
t.setArg(i, this.copyTree(cs[i]));
|
||||
}
|
||||
}
|
||||
return t;
|
||||
} ;
|
||||
GFAbstract.prototype.parseTree = function(str, type) {
|
||||
return this.annotate(this.parseTree_(str.match(/[\w\'\.\"]+|\(|\)|\?|\:/g), 0), type);
|
||||
return this.annotate(this.parseTree_(str.match(/[\w\'\.\"]+|\(|\)|\?|\:/g), 0), type);
|
||||
} ;
|
||||
GFAbstract.prototype.parseTree_ = function(tokens, prec) {
|
||||
if (tokens.length == 0 || tokens[0] == ")") { return null; }
|
||||
var t = tokens.shift();
|
||||
if (t == "(") {
|
||||
var tree = this.parseTree_(tokens, 0);
|
||||
tokens.shift();
|
||||
return tree;
|
||||
} else if (t == '?') {
|
||||
var tree = this.parseTree_(tokens, 0);
|
||||
return new Fun('?');
|
||||
} else {
|
||||
var tree = new Fun(t);
|
||||
if (prec == 0) {
|
||||
var c, i;
|
||||
for (i = 0; (c = this.parseTree_(tokens, 1)) !== null; i++) {
|
||||
tree.setArg(i,c);
|
||||
}
|
||||
}
|
||||
return tree;
|
||||
}
|
||||
if (tokens.length == 0 || tokens[0] == ")") { return null; }
|
||||
var t = tokens.shift();
|
||||
if (t == "(") {
|
||||
var tree = this.parseTree_(tokens, 0);
|
||||
tokens.shift();
|
||||
return tree;
|
||||
} else if (t == '?') {
|
||||
var tree = this.parseTree_(tokens, 0);
|
||||
return new Fun('?');
|
||||
} else {
|
||||
var tree = new Fun(t);
|
||||
if (prec == 0) {
|
||||
var c, i;
|
||||
for (i = 0; (c = this.parseTree_(tokens, 1)) !== null; i++) {
|
||||
tree.setArg(i,c);
|
||||
}
|
||||
}
|
||||
return tree;
|
||||
}
|
||||
} ;
|
||||
|
||||
function Type(args, cat) {
|
||||
this.args = args;
|
||||
this.cat = cat;
|
||||
this.args = args;
|
||||
this.cat = cat;
|
||||
}
|
||||
|
||||
/* Linearization */
|
||||
|
||||
function GFConcrete(flags, productions, functions, sequences, startCats, totalFIds) {
|
||||
this.flags = flags;
|
||||
this.productions = productions;
|
||||
this.functions = functions;
|
||||
this.sequences = sequences;
|
||||
this.startCats = startCats;
|
||||
this.totalFIds = totalFIds;
|
||||
this.flags = flags;
|
||||
this.productions = productions;
|
||||
this.functions = functions;
|
||||
this.sequences = sequences;
|
||||
this.startCats = startCats;
|
||||
this.totalFIds = totalFIds;
|
||||
|
||||
this.pproductions = productions;
|
||||
this.lproductions = new Object();
|
||||
this.pproductions = productions;
|
||||
this.lproductions = new Object();
|
||||
|
||||
for (var fid in productions) {
|
||||
for (var i in productions[fid]) {
|
||||
@@ -231,11 +231,11 @@ function GFConcrete(flags, productions, functions, sequences, startCats, totalFI
|
||||
rule.fun = fun;
|
||||
|
||||
var register = function (args, key, i) {
|
||||
if (i < args.length) {
|
||||
var c = 0;
|
||||
var arg = args[i].fid;
|
||||
if (i < args.length) {
|
||||
var c = 0;
|
||||
var arg = args[i].fid;
|
||||
|
||||
for (var k in productions[arg]) {
|
||||
for (var k in productions[arg]) {
|
||||
var rule = productions[arg][k];
|
||||
if (rule.id == "Coerce") {
|
||||
register(args,key + "_" + rule.arg,i+1);
|
||||
@@ -245,18 +245,18 @@ function GFConcrete(flags, productions, functions, sequences, startCats, totalFI
|
||||
|
||||
if (c == 0)
|
||||
register(args,key + "_" + arg,i+1);
|
||||
} else {
|
||||
var set = lproductions[key];
|
||||
} else {
|
||||
var set = lproductions[key];
|
||||
if (set == null) {
|
||||
set = new Array();
|
||||
lproductions[key] = set;
|
||||
}
|
||||
set.push({fun: fun, fid: fid});
|
||||
}
|
||||
}
|
||||
set.push({fun: fun, fid: fid});
|
||||
}
|
||||
}
|
||||
|
||||
register(rule.args,rule.fun.name,0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -271,26 +271,26 @@ GFConcrete.prototype.linearizeSyms = function (tree, tag) {
|
||||
var res = new Array();
|
||||
|
||||
if (tree.isString()) {
|
||||
var sym = new SymKS(tree.name);
|
||||
sym.tag = tag;
|
||||
res.push({fid: -1, table: [[sym]]});
|
||||
var sym = new SymKS(tree.name);
|
||||
sym.tag = tag;
|
||||
res.push({fid: -1, table: [[sym]]});
|
||||
} else if (tree.isInt()) {
|
||||
var sym = new SymKS(tree.name);
|
||||
sym.tag = tag;
|
||||
res.push({fid: -2, table: [[sym]]});
|
||||
var sym = new SymKS(tree.name);
|
||||
sym.tag = tag;
|
||||
res.push({fid: -2, table: [[sym]]});
|
||||
} else if (tree.isFloat()) {
|
||||
var sym = new SymKS(tree.name);
|
||||
sym.tag = tag;
|
||||
res.push({fid: -3, table: [[sym]]});
|
||||
var sym = new SymKS(tree.name);
|
||||
sym.tag = tag;
|
||||
res.push({fid: -3, table: [[sym]]});
|
||||
} else if (tree.isMeta()) {
|
||||
// TODO: Use lindef here
|
||||
// TODO: Use lindef here
|
||||
var cat = this.startCats[tree.type];
|
||||
|
||||
var sym = new SymKS(tree.name);
|
||||
sym.tag = tag;
|
||||
sym.tag = tag;
|
||||
|
||||
for (var fid = cat.s; fid <= cat.e; fid++) {
|
||||
res.push({fid: fid, table: [[sym]]});
|
||||
for (var fid = cat.s; fid <= cat.e; fid++) {
|
||||
res.push({fid: fid, table: [[sym]]});
|
||||
}
|
||||
} else {
|
||||
var cs = new Array();
|
||||
@@ -347,7 +347,7 @@ GFConcrete.prototype.syms2toks = function (syms) {
|
||||
case "KP":
|
||||
for (var j in sym.tokens) {
|
||||
ts.push(this.tagIt(sym.tokens[j],sym.tag));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -370,32 +370,32 @@ GFConcrete.prototype.tagAndLinearize = function (tree) {
|
||||
return this.syms2toks(res[0].table[0]);
|
||||
}
|
||||
GFConcrete.prototype.unlex = function (ts) {
|
||||
if (ts.length == 0) {
|
||||
return "";
|
||||
}
|
||||
if (ts.length == 0) {
|
||||
return "";
|
||||
}
|
||||
|
||||
var noSpaceAfter = /^[\(\-\[]/;
|
||||
var noSpaceBefore = /^[\.\,\?\!\)\:\;\-\]]/;
|
||||
var noSpaceAfter = /^[\(\-\[]/;
|
||||
var noSpaceBefore = /^[\.\,\?\!\)\:\;\-\]]/;
|
||||
|
||||
var s = "";
|
||||
for (var i = 0; i < ts.length; i++) {
|
||||
var t = ts[i];
|
||||
var after = i < ts.length-1 ? ts[i+1] : null;
|
||||
s += t;
|
||||
if (after != null && !t.match(noSpaceAfter)
|
||||
&& !after.match(noSpaceBefore)) {
|
||||
s += " ";
|
||||
}
|
||||
}
|
||||
return s;
|
||||
var s = "";
|
||||
for (var i = 0; i < ts.length; i++) {
|
||||
var t = ts[i];
|
||||
var after = i < ts.length-1 ? ts[i+1] : null;
|
||||
s += t;
|
||||
if (after != null && !t.match(noSpaceAfter)
|
||||
&& !after.match(noSpaceBefore)) {
|
||||
s += " ";
|
||||
}
|
||||
}
|
||||
return s;
|
||||
};
|
||||
GFConcrete.prototype.tagIt = function (obj, tag) {
|
||||
if (isString(obj)) {
|
||||
var o = new String(obj);
|
||||
o.setTag(tag);
|
||||
return o;
|
||||
var o = new String(obj);
|
||||
o.setTag(tag);
|
||||
return o;
|
||||
} else {
|
||||
var me = arguments.callee;
|
||||
var me = arguments.callee;
|
||||
if (arguments.length == 2) {
|
||||
me.prototype = obj;
|
||||
var o = new me();
|
||||
@@ -416,28 +416,28 @@ function isNumber(a) { return typeof a == 'number' && isFinite(a); }
|
||||
function isFunction(a) { return typeof a == 'function'; }
|
||||
|
||||
function dumpObject (obj) {
|
||||
if (isUndefined(obj)) {
|
||||
return "undefined";
|
||||
} else if (isString(obj)) {
|
||||
return '"' + obj.toString() + '"'; // FIXME: escape
|
||||
} else if (isBoolean(obj) || isNumber(obj)) {
|
||||
return obj.toString();
|
||||
} else if (isArray(obj)) {
|
||||
var x = "[";
|
||||
for (var i in obj) {
|
||||
x += dumpObject(obj[i]);
|
||||
if (i < obj.length-1) {
|
||||
x += ",";
|
||||
}
|
||||
}
|
||||
return x + "]";
|
||||
} else {
|
||||
var x = "{";
|
||||
for (var y in obj) {
|
||||
x += y + "=" + dumpObject(obj[y]) + ";" ;
|
||||
}
|
||||
return x + "}";
|
||||
}
|
||||
if (isUndefined(obj)) {
|
||||
return "undefined";
|
||||
} else if (isString(obj)) {
|
||||
return '"' + obj.toString() + '"'; // FIXME: escape
|
||||
} else if (isBoolean(obj) || isNumber(obj)) {
|
||||
return obj.toString();
|
||||
} else if (isArray(obj)) {
|
||||
var x = "[";
|
||||
for (var i in obj) {
|
||||
x += dumpObject(obj[i]);
|
||||
if (i < obj.length-1) {
|
||||
x += ",";
|
||||
}
|
||||
}
|
||||
return x + "]";
|
||||
} else {
|
||||
var x = "{";
|
||||
for (var y in obj) {
|
||||
x += y + "=" + dumpObject(obj[y]) + ";" ;
|
||||
}
|
||||
return x + "}";
|
||||
}
|
||||
}
|
||||
|
||||
/* ------------------------------------------------------------------------- */
|
||||
@@ -447,11 +447,11 @@ function dumpObject (obj) {
|
||||
|
||||
GFConcrete.prototype.showRules = function () {
|
||||
var ruleStr = new Array();
|
||||
ruleStr.push("");
|
||||
for (var i = 0, j = this.rules.length; i < j; i++) {
|
||||
ruleStr.push(this.rules[i].show());
|
||||
}
|
||||
return ruleStr.join("");
|
||||
ruleStr.push("");
|
||||
for (var i = 0, j = this.rules.length; i < j; i++) {
|
||||
ruleStr.push(this.rules[i].show());
|
||||
}
|
||||
return ruleStr.join("");
|
||||
};
|
||||
GFConcrete.prototype.tokenize = function (string) {
|
||||
var inToken = false;
|
||||
@@ -460,20 +460,20 @@ GFConcrete.prototype.tokenize = function (string) {
|
||||
|
||||
for (var i = 0; i < string.length; i++) {
|
||||
if ( string.charAt(i) == ' ' // space
|
||||
|| string.charAt(i) == '\f' // form feed
|
||||
|| string.charAt(i) == '\n' // newline
|
||||
|| string.charAt(i) == '\r' // return
|
||||
|| string.charAt(i) == '\t' // horizontal tab
|
||||
|| string.charAt(i) == '\v' // vertical tab
|
||||
|| string.charAt(i) == '\f' // form feed
|
||||
|| string.charAt(i) == '\n' // newline
|
||||
|| string.charAt(i) == '\r' // return
|
||||
|| string.charAt(i) == '\t' // horizontal tab
|
||||
|| string.charAt(i) == '\v' // vertical tab
|
||||
|| string.charAt(i) == String.fromCharCode(160) //
|
||||
) {
|
||||
if (inToken) {
|
||||
if (inToken) {
|
||||
end = i-1;
|
||||
inToken = false;
|
||||
|
||||
tokens.push(string.substr(start,end-start+1));
|
||||
}
|
||||
} else {
|
||||
} else {
|
||||
if (!inToken) {
|
||||
start = i;
|
||||
inToken = true;
|
||||
@@ -490,93 +490,93 @@ GFConcrete.prototype.tokenize = function (string) {
|
||||
return tokens;
|
||||
};
|
||||
GFConcrete.prototype.parseString = function (string, cat) {
|
||||
var tokens = this.tokenize(string);
|
||||
var tokens = this.tokenize(string);
|
||||
|
||||
var ps = new ParseState(this, cat);
|
||||
for (var i in tokens) {
|
||||
if (!ps.next(tokens[i]))
|
||||
var ps = new ParseState(this, cat);
|
||||
for (var i in tokens) {
|
||||
if (!ps.next(tokens[i]))
|
||||
return new Array();
|
||||
}
|
||||
return ps.extractTrees();
|
||||
}
|
||||
return ps.extractTrees();
|
||||
};
|
||||
/**
|
||||
* Generate list of suggestions given an input string
|
||||
*/
|
||||
GFConcrete.prototype.complete = function (input, cat) {
|
||||
|
||||
// Parameter defaults
|
||||
if (input == null) input = "";
|
||||
if (cat == null) cat = grammar.abstract.startcat;
|
||||
// Parameter defaults
|
||||
if (input == null) input = "";
|
||||
if (cat == null) cat = grammar.abstract.startcat;
|
||||
|
||||
// Tokenise input string & remove empty tokens
|
||||
tokens = input.trim().split(' ');
|
||||
for (var i = tokens.length - 1; i >= 0; i--) {
|
||||
if (tokens[i] == "") { tokens.splice(i, 1); }
|
||||
}
|
||||
// Tokenise input string & remove empty tokens
|
||||
tokens = input.trim().split(' ');
|
||||
for (var i = tokens.length - 1; i >= 0; i--) {
|
||||
if (tokens[i] == "") { tokens.splice(i, 1); }
|
||||
}
|
||||
|
||||
// Capture last token as it may be partial
|
||||
current = tokens.pop();
|
||||
if (current == null) current = "";
|
||||
// Capture last token as it may be partial
|
||||
current = tokens.pop();
|
||||
if (current == null) current = "";
|
||||
|
||||
// Init parse state objects.
|
||||
// ps2 is used for testing whether the final token is parsable or not.
|
||||
var ps = new ParseState(this, cat);
|
||||
var ps2 = new ParseState(this, cat);
|
||||
// Init parse state objects.
|
||||
// ps2 is used for testing whether the final token is parsable or not.
|
||||
var ps = new ParseState(this, cat);
|
||||
var ps2 = new ParseState(this, cat);
|
||||
|
||||
// Iterate over tokens, feed one by one to parser
|
||||
for (var i = 0; i < tokens.length ; i++) {
|
||||
if (!ps.next(tokens[i])) {
|
||||
return new Array(); // Incorrect parse, nothing to suggest
|
||||
}
|
||||
ps2.next(tokens[i]); // also consume token in ps2
|
||||
}
|
||||
// Iterate over tokens, feed one by one to parser
|
||||
for (var i = 0; i < tokens.length ; i++) {
|
||||
if (!ps.next(tokens[i])) {
|
||||
return new Array(); // Incorrect parse, nothing to suggest
|
||||
}
|
||||
ps2.next(tokens[i]); // also consume token in ps2
|
||||
}
|
||||
|
||||
// Attempt to also parse current, knowing it may be incomplete
|
||||
if (ps2.next(current)) {
|
||||
ps.next(current);
|
||||
tokens.push(current);
|
||||
current = "";
|
||||
}
|
||||
delete(ps2); // don't need this anymore
|
||||
// Attempt to also parse current, knowing it may be incomplete
|
||||
if (ps2.next(current)) {
|
||||
ps.next(current);
|
||||
tokens.push(current);
|
||||
current = "";
|
||||
}
|
||||
delete(ps2); // don't need this anymore
|
||||
|
||||
// Parse is successful so far, now get suggestions
|
||||
var acc = ps.complete(current);
|
||||
// Parse is successful so far, now get suggestions
|
||||
var acc = ps.complete(current);
|
||||
|
||||
// Format into just a list of strings & return
|
||||
// (I know the multiple nesting looks horrible)
|
||||
var suggs = new Array();
|
||||
if (acc.value) {
|
||||
// Iterate over all acc.value[]
|
||||
for (var v = 0; v < acc.value.length; v++) {
|
||||
// Iterate over all acc.value[].seq[]
|
||||
for (var s = 0; s < acc.value[v].seq.length; s++) {
|
||||
if (acc.value[v].seq[s].tokens == null) continue;
|
||||
// Iterate over all acc.value[].seq[].tokens
|
||||
for (var t = 0; t < acc.value[v].seq[s].tokens.length; t++) {
|
||||
suggs.push( acc.value[v].seq[s].tokens[t] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
// Format into just a list of strings & return
|
||||
// (I know the multiple nesting looks horrible)
|
||||
var suggs = new Array();
|
||||
if (acc.value) {
|
||||
// Iterate over all acc.value[]
|
||||
for (var v = 0; v < acc.value.length; v++) {
|
||||
// Iterate over all acc.value[].seq[]
|
||||
for (var s = 0; s < acc.value[v].seq.length; s++) {
|
||||
if (acc.value[v].seq[s].tokens == null) continue;
|
||||
// Iterate over all acc.value[].seq[].tokens
|
||||
for (var t = 0; t < acc.value[v].seq[s].tokens.length; t++) {
|
||||
suggs.push( acc.value[v].seq[s].tokens[t] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Note: return used tokens too
|
||||
return { 'consumed' : tokens, 'suggestions' : suggs };
|
||||
// Note: return used tokens too
|
||||
return { 'consumed' : tokens, 'suggestions' : suggs };
|
||||
}
|
||||
|
||||
// Apply Object Definition
|
||||
|
||||
function Apply(fun, args) {
|
||||
this.id = "Apply";
|
||||
this.fun = fun;
|
||||
this.args = args;
|
||||
this.id = "Apply";
|
||||
this.fun = fun;
|
||||
this.args = args;
|
||||
}
|
||||
Apply.prototype.show = function (cat) {
|
||||
var recStr = new Array();
|
||||
recStr.push(cat, " -> ", fun.name, " [", this.args, "]");
|
||||
return recStr.join("");
|
||||
var recStr = new Array();
|
||||
recStr.push(cat, " -> ", fun.name, " [", this.args, "]");
|
||||
return recStr.join("");
|
||||
};
|
||||
Apply.prototype.isEqual = function (obj) {
|
||||
if (this.id != obj.id || this.fun != obj.fun || this.args.length != obj.args.length)
|
||||
if (this.id != obj.id || this.fun != obj.fun || this.args.length != obj.args.length)
|
||||
return false;
|
||||
|
||||
for (var i in this.args) {
|
||||
@@ -588,37 +588,37 @@ Apply.prototype.isEqual = function (obj) {
|
||||
};
|
||||
|
||||
function PArg() {
|
||||
this.fid = arguments[arguments.length-1];
|
||||
if (arguments.length > 1)
|
||||
this.hypos = arguments.slice(0,arguments.length-1);
|
||||
this.fid = arguments[arguments.length-1];
|
||||
if (arguments.length > 1)
|
||||
this.hypos = arguments.slice(0,arguments.length-1);
|
||||
}
|
||||
|
||||
// Coerce Object Definition
|
||||
|
||||
function Coerce(arg) {
|
||||
this.id = "Coerce";
|
||||
this.arg = arg;
|
||||
this.arg = arg;
|
||||
}
|
||||
Coerce.prototype.show = function (cat) {
|
||||
var recStr = new Array();
|
||||
recStr.push(cat, " -> _ [", this.args, "]");
|
||||
return recStr.join("");
|
||||
var recStr = new Array();
|
||||
recStr.push(cat, " -> _ [", this.args, "]");
|
||||
return recStr.join("");
|
||||
};
|
||||
|
||||
// Const Object Definition
|
||||
|
||||
function Const(lit, toks) {
|
||||
this.id = "Const";
|
||||
this.lit = lit;
|
||||
this.toks = toks;
|
||||
this.lit = lit;
|
||||
this.toks = toks;
|
||||
}
|
||||
Const.prototype.show = function (cat) {
|
||||
var recStr = new Array();
|
||||
recStr.push(cat, " -> ", lit.print());
|
||||
return recStr.join("");
|
||||
var recStr = new Array();
|
||||
recStr.push(cat, " -> ", lit.print());
|
||||
return recStr.join("");
|
||||
};
|
||||
Const.prototype.isEqual = function (obj) {
|
||||
if (this.id != obj.id || this.lit.isEqual(obj.lit) || this.toks.length != obj.toks.length)
|
||||
if (this.id != obj.id || this.lit.isEqual(obj.lit) || this.toks.length != obj.toks.length)
|
||||
return false;
|
||||
|
||||
for (var i in this.toks) {
|
||||
@@ -638,41 +638,41 @@ function CncFun(name,lins) {
|
||||
|
||||
// Object to represent argument projections in grammar rules
|
||||
function SymCat(i, label) {
|
||||
this.id = "Arg";
|
||||
this.i = i;
|
||||
this.label = label;
|
||||
this.id = "Arg";
|
||||
this.i = i;
|
||||
this.label = label;
|
||||
}
|
||||
SymCat.prototype.getId = function () { return this.id; };
|
||||
SymCat.prototype.getArgNum = function () { return this.i };
|
||||
SymCat.prototype.show = function () {
|
||||
var argStr = new Array();
|
||||
argStr.push(this.i, this.label);
|
||||
return argStr.join(".");
|
||||
var argStr = new Array();
|
||||
argStr.push(this.i, this.label);
|
||||
return argStr.join(".");
|
||||
};
|
||||
|
||||
// Object to represent terminals in grammar rules
|
||||
function SymKS() {
|
||||
this.id = "KS";
|
||||
this.tokens = arguments;
|
||||
this.id = "KS";
|
||||
this.tokens = arguments;
|
||||
}
|
||||
SymKS.prototype.getId = function () { return this.id; };
|
||||
SymKS.prototype.show = function () {
|
||||
var terminalStr = new Array();
|
||||
terminalStr.push('"', this.tokens, '"');
|
||||
return terminalStr.join("");
|
||||
var terminalStr = new Array();
|
||||
terminalStr.push('"', this.tokens, '"');
|
||||
return terminalStr.join("");
|
||||
};
|
||||
|
||||
// Object to represent pre in grammar rules
|
||||
function SymKP(tokens,alts) {
|
||||
this.id = "KP";
|
||||
this.tokens = tokens;
|
||||
this.id = "KP";
|
||||
this.tokens = tokens;
|
||||
this.alts = alts;
|
||||
}
|
||||
SymKP.prototype.getId = function () { return this.id; };
|
||||
SymKP.prototype.show = function () {
|
||||
var terminalStr = new Array();
|
||||
terminalStr.push('"', this.tokens, '"');
|
||||
return terminalStr.join("");
|
||||
var terminalStr = new Array();
|
||||
terminalStr.push('"', this.tokens, '"');
|
||||
return terminalStr.join("");
|
||||
};
|
||||
|
||||
function Alt(tokens, prefixes) {
|
||||
@@ -682,15 +682,15 @@ function Alt(tokens, prefixes) {
|
||||
|
||||
// Object to represent pre in grammar rules
|
||||
function SymLit(i,label) {
|
||||
this.id = "Lit";
|
||||
this.i = i;
|
||||
this.label = label;
|
||||
this.id = "Lit";
|
||||
this.i = i;
|
||||
this.label = label;
|
||||
}
|
||||
SymLit.prototype.getId = function () { return this.id; };
|
||||
SymLit.prototype.show = function () {
|
||||
var argStr = new Array();
|
||||
argStr.push(this.i, this.label);
|
||||
return argStr.join(".");
|
||||
var argStr = new Array();
|
||||
argStr.push(this.i, this.label);
|
||||
return argStr.join(".");
|
||||
};
|
||||
|
||||
// Parsing
|
||||
@@ -812,35 +812,35 @@ ParseState.prototype.next = function (token) {
|
||||
*/
|
||||
ParseState.prototype.complete = function (currentToken) {
|
||||
|
||||
// Initialise accumulator for suggestions
|
||||
var acc = this.items.lookup(currentToken);
|
||||
if (acc == null)
|
||||
acc = new Trie();
|
||||
// Initialise accumulator for suggestions
|
||||
var acc = this.items.lookup(currentToken);
|
||||
if (acc == null)
|
||||
acc = new Trie();
|
||||
|
||||
this.process(
|
||||
// Items
|
||||
this.items.value,
|
||||
this.process(
|
||||
// Items
|
||||
this.items.value,
|
||||
|
||||
// Deal with literal categories
|
||||
function (fid) {
|
||||
// Always return null, as suggested by Krasimir
|
||||
return null;
|
||||
},
|
||||
// Deal with literal categories
|
||||
function (fid) {
|
||||
// Always return null, as suggested by Krasimir
|
||||
return null;
|
||||
},
|
||||
|
||||
// Takes an array of tokens and populates the accumulator
|
||||
function (tokens, item) {
|
||||
if (currentToken == "" || tokens[0].indexOf(currentToken) == 0) { //if begins with...
|
||||
var tokens1 = new Array();
|
||||
for (var i = 1; i < tokens.length; i++) {
|
||||
tokens1[i-1] = tokens[i];
|
||||
}
|
||||
acc.insertChain1(tokens1, item);
|
||||
}
|
||||
}
|
||||
);
|
||||
// Takes an array of tokens and populates the accumulator
|
||||
function (tokens, item) {
|
||||
if (currentToken == "" || tokens[0].indexOf(currentToken) == 0) { //if begins with...
|
||||
var tokens1 = new Array();
|
||||
for (var i = 1; i < tokens.length; i++) {
|
||||
tokens1[i-1] = tokens[i];
|
||||
}
|
||||
acc.insertChain1(tokens1, item);
|
||||
}
|
||||
}
|
||||
);
|
||||
|
||||
// Return matches
|
||||
return acc;
|
||||
// Return matches
|
||||
return acc;
|
||||
}
|
||||
ParseState.prototype.extractTrees = function() {
|
||||
this.process( this.items.value
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
{
|
||||
"parser": "@typescript-eslint/parser",
|
||||
"plugins": ["@typescript-eslint"],
|
||||
"extends": ["plugin:@typescript-eslint/recommended"],
|
||||
"rules": {
|
||||
"indent": "off",
|
||||
"@typescript-eslint/indent": ["warn", 2],
|
||||
"@typescript-eslint/no-use-before-define": ["error", {
|
||||
"functions": false,
|
||||
"classes": false
|
||||
}],
|
||||
"semi": "off",
|
||||
"@typescript-eslint/semi": ["warn", "never"],
|
||||
"quotes": ["warn", "single"],
|
||||
"@typescript-eslint/camelcase": "off",
|
||||
"@typescript-eslint/no-unused-vars": ["warn", { "argsIgnorePattern": "^_" }],
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
# GF TypeScript Runtime
|
||||
|
||||
`gflib.ts` is a TypeScript implementation of the GF runtime.
|
||||
It is ported from an older JavaScript implementation [`gflib.js`](../javascript/gflib.js),
|
||||
with some improvements.
|
||||
|
||||
Importantly, all **future** updates will only be made to this TypeScript version.
|
||||
|
||||
## Applicability
|
||||
|
||||
This runtime allows you use GF in pure JavaScript, and thus have GF-powered apps without the need for a server backend.
|
||||
However, it has not been actively maintained as the other runtimes have been.
|
||||
So its features are limited and it is not efficient, making it really only useful for smaller grammars.
|
||||
|
||||
## Using
|
||||
|
||||
`gflib.ts` can be transpiled to JavaScript by running `tsc` in this folder (of course you need TypeScript installed).
|
||||
It has no module dependencies.
|
||||
You can then include the generated `js/gflib.js` file in your application as usual.
|
||||
|
||||
_This generated JavaScript version is also included under version control,
|
||||
to make it easy for someone to use without having to install TypeScript._
|
||||
|
||||
Your GF grammar should be compiled with: `gf --make --output-format=js`
|
||||
|
||||
For an example of a working web application using the JavaScript runtime, see `../javascript`.
|
||||
|
||||
## What happened to `gflib.d.ts`?
|
||||
|
||||
There was once a file here called `gflib.d.ts`, which contained TypeScript type definitions for the **old** `gflib.js`.
|
||||
Since the runtime is now ported to TypeScript, those type definitions are no longer necessary (plus they contained many errors).
|
||||
Vendored
-337
@@ -1,337 +0,0 @@
|
||||
/**
|
||||
* gflib.dt.s
|
||||
*
|
||||
* by John J. Camilleri
|
||||
*
|
||||
* TypeScript type definitions for the "original" JS GF runtime (GF:src/runtime/javascript/gflib.js)
|
||||
*/
|
||||
|
||||
// Note: the String prototype is extended with:
|
||||
// String.prototype.tag = "";
|
||||
// String.prototype.setTag = function (tag) { this.tag = tag; };
|
||||
|
||||
/**
|
||||
* A GF grammar is one abstract and multiple concretes
|
||||
*/
|
||||
declare class GFGrammar {
|
||||
abstract: GFAbstract
|
||||
concretes: {[key: string]: GFConcrete}
|
||||
|
||||
constructor(abstract: GFAbstract, concretes: {[key: string]: GFConcrete})
|
||||
|
||||
translate(
|
||||
input: string,
|
||||
fromLang: string,
|
||||
toLang: string
|
||||
): {[key: string]: {[key: string]: string}}
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract Syntax Tree
|
||||
*/
|
||||
declare class Fun {
|
||||
name: string
|
||||
args: Fun[]
|
||||
|
||||
constructor(name: string, ...args: Fun[])
|
||||
|
||||
print(): string
|
||||
show(): string
|
||||
getArg(i: number): Fun
|
||||
setArg(i: number, c: Fun): void
|
||||
isMeta(): boolean
|
||||
isComplete(): boolean
|
||||
isLiteral(): boolean
|
||||
isString(): boolean
|
||||
isInt(): boolean
|
||||
isFloat(): boolean
|
||||
isEqual(obj: any): boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* Abstract syntax
|
||||
*/
|
||||
declare class GFAbstract {
|
||||
startcat: string
|
||||
types: {[key: string]: Type} // key is function name
|
||||
|
||||
constructor(startcat: string, types: {[key: string]: Type})
|
||||
|
||||
addType(fun: string, args: string[], cat: string): void
|
||||
getArgs(fun: string): string[]
|
||||
getCat(fun: string): string
|
||||
annotate(tree: Fun, type: string): Fun
|
||||
handleLiterals(tree: Fun, type: Type): Fun
|
||||
copyTree(x: Fun): Fun
|
||||
parseTree(str: string, type: string): Fun
|
||||
parseTree_(tokens: string[], prec: number): Fun
|
||||
}
|
||||
|
||||
/**
|
||||
* Type
|
||||
*/
|
||||
declare class Type {
|
||||
args: string[]
|
||||
cat: string
|
||||
|
||||
constructor(args: string[], cat: string)
|
||||
}
|
||||
|
||||
type ApplyOrCoerce = Apply | Coerce
|
||||
|
||||
/**
|
||||
* Concrete syntax
|
||||
*/
|
||||
declare class GFConcrete {
|
||||
flags: {[key: string]: string}
|
||||
productions: {[key: number]: ApplyOrCoerce[]}
|
||||
functions: CncFun[]
|
||||
sequences: Array<Array<Sym>>
|
||||
startCats: {[key: string]: {s: number, e: number}}
|
||||
totalFIds: number
|
||||
pproductions: {[key: number]: ApplyOrCoerce[]}
|
||||
lproductions: {[key: string]: {fid: FId, fun: CncFun}}
|
||||
|
||||
constructor(
|
||||
flags: {[key: string]: string},
|
||||
productions: {[key: number]: ApplyOrCoerce[]},
|
||||
functions: CncFun[],
|
||||
sequences: Array<Array<Sym>>,
|
||||
startCats: {[key: string]: {s: number, e: number}},
|
||||
totalFIds: number
|
||||
)
|
||||
|
||||
linearizeSyms(tree: Fun, tag: string): Array<{fid: FId, table: any}>
|
||||
syms2toks(syms: Sym[]): string[]
|
||||
linearizeAll(tree: Fun): string[]
|
||||
linearize(tree: Fun): string
|
||||
tagAndLinearize(tree: Fun): string[]
|
||||
unlex(ts: string): string
|
||||
tagIt(obj: any, tag: string): any
|
||||
// showRules(): string // Uncaught TypeError: Cannot read property 'length' of undefined at gflib.js:451
|
||||
tokenize(string: string): string[]
|
||||
parseString(string: string, cat: string): Fun[]
|
||||
complete(
|
||||
input: string,
|
||||
cat: string
|
||||
): {consumed: string[], suggestions: string[]}
|
||||
}
|
||||
|
||||
/**
|
||||
* Function ID
|
||||
*/
|
||||
type FId = number
|
||||
|
||||
/**
|
||||
* Apply
|
||||
*/
|
||||
declare class Apply {
|
||||
id: string
|
||||
fun: FId
|
||||
args: PArg[]
|
||||
|
||||
constructor(fun: FId, args: PArg[])
|
||||
|
||||
show(cat: string): string
|
||||
isEqual(obj: any): boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* PArg
|
||||
*/
|
||||
declare class PArg {
|
||||
fid: FId
|
||||
hypos: any[]
|
||||
|
||||
constructor(fid: FId, ...hypos: any[])
|
||||
}
|
||||
|
||||
/**
|
||||
* Coerce
|
||||
*/
|
||||
declare class Coerce {
|
||||
id: string
|
||||
arg: FId
|
||||
|
||||
constructor(arg: FId)
|
||||
|
||||
show(cat: string): string
|
||||
}
|
||||
|
||||
/**
|
||||
* Const
|
||||
*/
|
||||
declare class Const {
|
||||
id: string
|
||||
lit: Fun
|
||||
toks: any[]
|
||||
|
||||
constructor(lit: Fun, toks: any[])
|
||||
|
||||
show(cat: string): string
|
||||
isEqual(obj: any): boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* CncFun
|
||||
*/
|
||||
declare class CncFun {
|
||||
name: string
|
||||
lins: FId[]
|
||||
|
||||
constructor(name: string, lins: FId[])
|
||||
}
|
||||
|
||||
type Sym = SymCat | SymKS | SymKP | SymLit
|
||||
|
||||
/**
|
||||
* SymCat
|
||||
*/
|
||||
declare class SymCat {
|
||||
id: string
|
||||
i: number
|
||||
label: number
|
||||
|
||||
constructor(i: number, label: number)
|
||||
|
||||
getId(): string
|
||||
getArgNum(): number
|
||||
show(): string
|
||||
}
|
||||
|
||||
/**
|
||||
* SymKS
|
||||
*/
|
||||
declare class SymKS {
|
||||
id: string
|
||||
tokens: string[]
|
||||
|
||||
constructor(...tokens: string[])
|
||||
|
||||
getId(): string
|
||||
show(): string
|
||||
}
|
||||
|
||||
/**
|
||||
* SymKP
|
||||
*/
|
||||
declare class SymKP {
|
||||
id: string
|
||||
tokens: string[]
|
||||
alts: Alt[]
|
||||
|
||||
constructor(tokens: string[], alts: Alt[])
|
||||
|
||||
getId(): string
|
||||
show(): string
|
||||
}
|
||||
|
||||
/**
|
||||
* Alt
|
||||
*/
|
||||
declare class Alt {
|
||||
tokens: string[]
|
||||
prefixes: string[]
|
||||
|
||||
constructor(tokens: string[], prefixes: string[])
|
||||
}
|
||||
|
||||
/**
|
||||
* SymLit
|
||||
*/
|
||||
declare class SymLit {
|
||||
id: string
|
||||
i: number
|
||||
label: number
|
||||
|
||||
constructor(i: number, label: number)
|
||||
|
||||
getId(): string
|
||||
show(): string
|
||||
}
|
||||
|
||||
/**
|
||||
* Trie
|
||||
*/
|
||||
declare class Trie {
|
||||
value: any
|
||||
items: Trie[]
|
||||
|
||||
insertChain(keys, obj): void
|
||||
insertChain1(keys, obj): void
|
||||
lookup(key, obj): any
|
||||
isEmpty(): boolean
|
||||
}
|
||||
|
||||
/**
|
||||
* ParseState
|
||||
*/
|
||||
declare class ParseState {
|
||||
concrete: GFConcrete
|
||||
startCat: string
|
||||
items: Trie
|
||||
chart: Chart
|
||||
|
||||
constructor(concrete: GFConcrete, startCat: string)
|
||||
|
||||
next(token: string): boolean
|
||||
complete(correntToken: string): Trie
|
||||
extractTrees(): any[]
|
||||
process(
|
||||
agenda,
|
||||
literalCallback: (fid: FId) => any,
|
||||
tokenCallback: (tokens: string[], item: any) => any
|
||||
): void
|
||||
}
|
||||
|
||||
/**
|
||||
* Chart
|
||||
*/
|
||||
declare class Chart {
|
||||
active: any
|
||||
actives: {[key: number]: any}
|
||||
passive: any
|
||||
forest: {[key: number]: ApplyOrCoerce[]}
|
||||
nextId: number
|
||||
offset: number
|
||||
|
||||
constructor(concrete: GFConcrete)
|
||||
|
||||
lookupAC(fid: FId,label)
|
||||
lookupACo(offset, fid: FId, label)
|
||||
|
||||
labelsAC(fid: FId)
|
||||
insertAC(fid: FId, label, items): void
|
||||
|
||||
lookupPC(fid: FId, label, offset)
|
||||
insertPC(fid1: FId, label, offset, fid2: FId): void
|
||||
shift(): void
|
||||
expandForest(fid: FId): any[]
|
||||
}
|
||||
|
||||
/**
|
||||
* ActiveItem
|
||||
*/
|
||||
declare class ActiveItem {
|
||||
offset: number
|
||||
dot: number
|
||||
fun: CncFun
|
||||
seq: Array<Sym>
|
||||
args: PArg[]
|
||||
fid: FId
|
||||
lbl: number
|
||||
|
||||
constructor(
|
||||
offset: number,
|
||||
dot: number,
|
||||
fun: CncFun,
|
||||
seq: Array<Sym>,
|
||||
args: PArg[],
|
||||
fid: FId,
|
||||
lbl: number
|
||||
)
|
||||
|
||||
isEqual(obj: any): boolean
|
||||
shiftOverArg(i: number, fid: FId): ActiveItem
|
||||
shiftOverTokn(): ActiveItem
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because one or more lines are too long
@@ -0,0 +1,12 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "none",
|
||||
"target": "es3",
|
||||
"strict": true,
|
||||
"noImplicitAny": true,
|
||||
"removeComments": true,
|
||||
"outDir": "js",
|
||||
"sourceMap": true
|
||||
},
|
||||
"compileOnSave": true
|
||||
}
|
||||
Reference in New Issue
Block a user