Skip to content

Commit

Permalink
Merge pull request #10 from TezTech/optimized
Browse files Browse the repository at this point in the history
Optimized parser
  • Loading branch information
stephenandrews authored Feb 21, 2019
2 parents 8be0a35 + 227eaf8 commit 79c176c
Show file tree
Hide file tree
Showing 44 changed files with 356 additions and 302 deletions.
4 changes: 2 additions & 2 deletions dist/fi-compile.min.js

Large diffs are not rendered by default.

19 changes: 9 additions & 10 deletions lib/compile.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ module.exports = function(core){
if (t == "temp") {
c += "A";
c += a;
c += "R;";
c += "R";
return {
code : c,
type : rettype
Expand All @@ -63,7 +63,7 @@ module.exports = function(core){
if (t == "input") {
c += "A";
c += a;
c += "R;";
c += "R";
return {
code : c,
type : rettype
Expand All @@ -73,7 +73,7 @@ module.exports = function(core){
if (t == "storage") {
c += "D";
c += a;
c += "R;";
c += "R";
return {
code : c,
type : rettype
Expand All @@ -97,15 +97,14 @@ module.exports = function(core){
var c = "C";
if (core.map.entry[core.currentCall]['temp'].length > 0) c += "D";
if (core.map.entry[core.currentCall]['input'].length > 0) c += "D";
c += "AR;";
return "DIP{DUP;"+c+"};CONS;SWAP;SET_"+c;
c += "AR";
return [["DIP",["DUP", c]], "CONS", "SWAP", "SET_"+c];
},
ml : function(a, b){
var code = a.toUpperCase();
if (typeof b != 'undefined'){
code += "{" + b + "}";
code = [a, b];
}
code += ";"
return code;
},
literal : function(t, v){
Expand Down Expand Up @@ -133,19 +132,19 @@ module.exports = function(core){
error : function(e){
if (typeof e == 'string') e = 'string "' + e + '"';
else e = "nat " + parseInt(e);
return "IF_NONE{PUSH "+e+";FAILWITH}{};";
return [["IF_NONE", ["PUSH "+e, "FAILWITH"], []]];
},
getter : function(v){
var f = find(v);
return {
code : "DUP;" + f.code,
code : ["DUP", f.code],
type : f.type
}
},
setter : function(v){
var f = find(v);
return {
code : "SWAP;SET_" + f.code,
code : ["SWAP", "SET_" + f.code],
type : f.type
}
}
Expand Down
38 changes: 18 additions & 20 deletions lib/compile/code.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,39 +5,35 @@ module.exports = function(core){
methodHandlers = {},
constants = {
BALANCE : {
code : "BALANCE;",
code : ['BALANCE'],
type : "mutez"
},
SOURCE : {
code : "SOURCE;",
code : ["SOURCE"],
type : "address"
},
SENDER : {
code : "SENDER;",
code : ["SENDER"],
type : "address"
},
SELF : {
code : "SELF;",
code : ["SELF"],
type : "contract *"
},
OWNER : {
code : "SELF;ADDRESS;",
code : ["SELF", "ADDRESS"],
type : "address"
},
AMOUNT : {
code : "AMOUNT;",
code : ["AMOUNT"],
type : "mutez"
},
STEPS : {
code : "STEPS_TO_QUOTA;",
type : "nat"
},
STEPS_TO_QUOTA : {
code : "STEPS_TO_QUOTA;",
GAS : {
code : ["STEPS_TO_QUOTA"],
type : "nat"
},
NOW : {
code : "NOW;",
code : ["NOW"],
type : "timestamp"
}
},
Expand Down Expand Up @@ -65,25 +61,27 @@ module.exports = function(core){
if (core.literalTypes.indexOf(com) >= 0){
if (com == 'pkh') com = 'key_hash';
return {
code : "PUSH " + com + " " + core.compile.literal(com, op.shift()) + ";",
code : ["PUSH " + com + " " + core.compile.literal(com, op.shift())],
type : [com]
};
}
else if (typeof constants[com] != 'undefined'){
return {
code : constants[com].code,
code : constants[com].code.slice(0),
constant : com,
type : [constants[com].type]
}
}
else if (typeof core.map.const != 'undefined' && core.helper.findInObjArray(core.map.const, "name", com) >= 0){
var i = core.helper.findInObjArray(core.map.const, "name", com);
return {
code : "PUSH " + core.map.const[i].type + " " + core.compile.literal(core.map.const[i].type, core.map.const[i].value) + ";",
code : ["PUSH " + core.map.const[i].type + " " + core.compile.literal(core.map.const[i].type, core.map.const[i].value)],
type : [core.map.const[i].type]
}
}
else if (typeof methodHandlers[com] != 'undefined') {
return methodHandlers[com](op);
var t = methodHandlers[com](op);
return t;
}
else {
try {
Expand All @@ -97,7 +95,7 @@ module.exports = function(core){
return function(code){
if (typeof code == 'string') code = core.parse.main(code);
if (typeof code[0] == 'string') return _compileCode(code);
var compiled = "";
var compiled = [];
for (var i = 0; i < code.length; i++){
op = code[i].slice(0);
if (!op.length) continue;
Expand All @@ -106,9 +104,9 @@ module.exports = function(core){
} catch (e){
throw e;
}
if (typeof line.code != 'string') throw "Invalid line function";
//if (typeof line.code != 'string') throw "Invalid line function";
if (line.type) throw "Code returns a value that is not stored";
compiled += line.code;
compiled = compiled.concat(line.code);
}
return {
code : compiled,
Expand Down
6 changes: 3 additions & 3 deletions lib/compile/condition.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,11 @@ module.exports = function(core){
else rhs = co[2];
if (['and', 'or', 'neq','le','ge','lt','gt','eq'].indexOf(rhs[0]) >= 0) rhs = compileCondition(rhs);
else rhs = core.compile.code(rhs).code;
var code = lhs + "DIP{" + rhs + "};";
var code = lhs.concat([["DIP", rhs]]);
if (['and', 'or'].indexOf(com) >= 0) {
code += com.toUpperCase() + ";";
code = code.concat([com.toUpperCase()]);
}else if (['neq','le','ge','lt','gt','eq'].indexOf(com) >= 0){
code += "COMPARE;" + com.toUpperCase() + ";";
code = code.concat(['COMPARE', com.toUpperCase()]);
}
return code;
}
Expand Down
6 changes: 3 additions & 3 deletions lib/compile/methods/abs.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@ abs(int) => nat
*/
module.exports = function(core){
return function(op){
var ret = {code : "", type : ['nat']};
var ret = {code : [], type : ['nat']};
if (op.length != 1) throw "Not enough arguments for function abs, expects 1";
var a1 = core.compile.code(op.shift());
if (a1.type[0] != 'int') throw "Invalid type for abs, expects int not " + a1.type[0];
ret.code += a1.code;
ret.code += core.compile.ml('abs');
ret.code = a1.code;
ret.code.push("ABS");
return ret;
}
};
8 changes: 4 additions & 4 deletions lib/compile/methods/add.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,18 +28,18 @@ var iotypes = {

module.exports = function(core){
return function(op){
var ret = {code : "", type : false};
var ret = {code : [], type : false};
if (op.length < 2) throw "Not enough arguments for function add, expects at least 2";
var instr = core.compile.ml('add'), a1 = core.compile.code(op.shift()), an;
if (typeof iotypes[a1.type[0]] == 'undefined') throw "Invalid type for add, expects int, nat, mutez or timestamp not " + a1.type[0];
ret.type = a1.type;
ret.code += a1.code;
ret.code = a1.code;
while(op.length){
an = core.compile.code(op.shift());
if (typeof iotypes[ret.type[0]][an.type[0]] == 'undefined') throw "Invalid type for add " + an.type[0];
ret.type = [iotypes[ret.type[0]][an.type[0]]];
ret.code += core.compile.ml("dip", an.code);
ret.code += instr;
ret.code.push(["DIP", an.code]);
ret.code.push('ADD');
}
return ret;
}
Expand Down
15 changes: 9 additions & 6 deletions lib/compile/methods/assert.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@
//
module.exports = function(core){
return function(op){
var ret = {code : "", type : false};
var ret = {code : [], type : false};
var condition = core.compile.condition(op.shift());
ret.code += condition;
ret.code += "IF{}{";
ret.code = condition;

var er;
if (op.length)
ret.code += core.compile.code(op.shift()).code;
er = core.compile.code(op.shift()).code;
else
ret.code += "PUSH string \"Failed assert\";";
ret.code += "FAILWITH};";
er = ["PUSH string \"Failed assert\""];
er.push("FAILWITH");

ret.code.push(["IF", [], er]);
return ret
}
};
8 changes: 4 additions & 4 deletions lib/compile/methods/concat.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@ concat(bytes, bytes, ...) => bytes
*/
module.exports = function(core){
return function(op){
var ret = {code : "", type : false};
var ret = {code : [], type : false};
if (op.length < 2) throw "Not enough arguments for function concat - expects at least two";
var instr = core.compile.ml('concat'), a1 = core.compile.code(op.shift()), an;
if (['string', 'bytes'].indexOf(a1.type[0]) < 0) throw "Invalid type for concat, expecting string or bytes not " + a1.type[0];
ret.code += a1.code;
ret.code = a1.code;
ret.type = a1.type;
while(op.length){
an = core.compile.code(op.shift());
if (an.type[0] != ret.type[0]) throw "Invalid type for concat, expecting " + ret.type[0] + " not " + an.type[0];
ret.code += core.compile.ml("dip", an.code);
ret.code += instr;
ret.code.push(["DIP", an.code]);
ret.code.push(instr);
}
return ret;
}
Expand Down
13 changes: 7 additions & 6 deletions lib/compile/methods/concat_ws.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,20 @@ concat_ws(string sperator, string....) => string
*/
module.exports = function(core){
return function(op){
var ret = {code : "", type : ['string']};
var ret = {code : [], type : ['string']};
var sep = core.compile.code(op.shift());
var a1 = core.compile.code(op.shift()), an;
if (sep.type[0] != 'string') throw "Invalid type for seperator, expecting string not " + sep.type[0];
if (a1.type[0] != 'string') throw "Invalid type for concat_ws, expecting string now " + a1.type[0];
ret.code += a1.code;
ret.code = a1.code;
while(op.length){
ret.code += core.compile.ml('dip', sep.code);
ret.code += "CONCAT;"
ret.code.push(['DIP', sep.code]);
ret.code.push("CONCAT")
an = core.compile.code(op.shift());
if (an.type[0] != 'string') throw "Invalid type for concat, expecting string not " + an.type[0];
ret.code += core.compile.ml('dip', an.code);
ret.code += "CONCAT;"

ret.code.push(['DIP', an.code]);
ret.code.push("CONCAT")
}
return ret
}
Expand Down
12 changes: 6 additions & 6 deletions lib/compile/methods/delegate.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,18 @@ delegate(key_hash)
*/
module.exports = function(core){
return function(op){
var ret = {code : "", type : false};
var ret = {code : [], type : false};
if (op.length > 1) throw "Invalid argument count for delegate - expecting 0 or 1";
if (op.length) {
var delegate = core.compile.code(op.shift());
if (delegate.type[0] != "key_hash") throw "Invalid type for delegate, expecting key_hash not " + delegate.type[0];
ret.code += delegate.code;
ret.code += "SOME;";
ret.code = delegate.code;
ret.code.push("SOME");
} else {
ret.code += "NONE key_hash;";
ret.code = ["NONE key_hash"];
}
ret.code += "SET_DELEGATE;";
ret.code += core.compile.operation();
ret.code.push("SET_DELEGATE");
ret.code = ret.code.concat(core.compile.operation());
return ret
}
};
10 changes: 6 additions & 4 deletions lib/compile/methods/div.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,18 +24,20 @@ var iotypes = {

module.exports = function(core){
return function(op){
var ret = {code : "", type : false};
var ret = {code : [], type : false};
if (op.length < 2) throw "Not enough arguments, expecting at least two";
var a1 = core.compile.code(op.shift()), an;
if (typeof iotypes[a1.type[0]] == 'undefined') throw "Invalid type for div, expecting int, nat or mutez, not " + a1.type[0];
ret.type = a1.type;
ret.code += a1.code;
ret.code = a1.code;
while(op.length){
an = core.compile.code(op.shift());
if (typeof iotypes[ret.type[0]][an.type[0]] == 'undefined') throw "Invalid type for div between " +ret.type[0]+" and "+an.type[0];
ret.type = [iotypes[ret.type[0]][an.type[0]]];
ret.code += core.compile.ml('dip', an.code);
ret.code += "EDIV;IF_NONE{PUSH string \"Divisible by 0\";FAILWITH}{};CAR;";
ret.code.push(['DIP', an.code]);
ret.code.push("EDIV");
ret.code.push(["IF_NONE", ["PUSH string \"Divisible by 0\"", "FAILWITH"], []]);
ret.code.push("CAR");
}
return ret
}
Expand Down
14 changes: 7 additions & 7 deletions lib/compile/methods/drop.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,19 +5,19 @@ xx.drop(_ key)
*/
module.exports = function(core){
return function(op){
var ret = {code : "", type : false};
var ret = {code : [], type : false};
var vvName = op.shift(), key = core.compile.code(op.shift()), vv = core.compile.code(vvName);
if (['map', 'big_map', 'set'].indexOf(vv.type[0]) < 0) throw "Invalid type for drop, expecting map, big_map or set, not " + vv.type[0];
if (core.compile.type(key.type[0]) != core.compile.type(vv.type[1])) throw "Invalid key type, expecting " + vv.type[1] + " not " + key.type[0];
ret.code += key.code;
ret.code = key.code;
if (vv.type[0] == 'set'){
ret.code += core.compile.ml('dip', "PUSH bool False;");
ret.code.push(['DIP', ["PUSH bool False"]]);
} else {
ret.code += core.compile.ml('dip', "NONE "+core.compile.type(vv.type[2])+";");
ret.code.push(['DIP', ["NONE "+core.compile.type(vv.type[2])]]);
}
ret.code += core.compile.ml('diip', vv.code);
ret.code += "UPDATE;";
ret.code += core.compile.setter(vvName[0]).code;
ret.code.push(['DIIP', vv.code]);
ret.code.push("UPDATE");
ret.code = ret.code.concat(core.compile.setter(vvName[0]).code);
return ret
}
};
9 changes: 5 additions & 4 deletions lib/compile/methods/get.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ xx.get(_ key) => _
*/
module.exports = function(core){
return function(op){
var ret = {code : "", type : false};
var ret = {code : [], type : false};
var map = core.compile.code(op.shift()), key = core.compile.code(op.shift());
if (['map', 'big_map'].indexOf(map.type[0]) < 0) throw "Invalid type for get, expect map or big_map not " + map.type[0];
ret.code += key.code;
ret.code += core.compile.ml('dip', map.code);
ret.code += "GET;IF_NONE{PUSH string \"Key not found in map\";FAILWITH}{};";
ret.code = key.code;
ret.code.push(['DIP', map.code]);
ret.code.push("GET");
ret.code.push(["IF_NONE", ["PUSH string \"Key not found in map\"", "FAILWITH"], []]);
ret.type = map.type[2];
return ret;
}
Expand Down
Loading

0 comments on commit 79c176c

Please sign in to comment.