summaryrefslogtreecommitdiff
path: root/genops.js
diff options
context:
space:
mode:
authortomsmeding <tom.smeding@gmail.com>2016-08-05 20:26:05 +0200
committertomsmeding <tom.smeding@gmail.com>2016-08-06 10:10:32 +0200
commitf67988fbfde6ad8a91466ef5d4227dcf9e5db6ce (patch)
treedb85d3936f717331c3eeed4fae43e5ed43324be9 /genops.js
parente6bb770a52980ef3d85c2d4b93fb240c026ce7f7 (diff)
Working preliminary version of parser
Diffstat (limited to 'genops.js')
-rwxr-xr-xgenops.js94
1 files changed, 81 insertions, 13 deletions
diff --git a/genops.js b/genops.js
index 33b688d..9b88cbc 100755
--- a/genops.js
+++ b/genops.js
@@ -3,7 +3,6 @@ const fs=require("fs");
function print(/*arguments*/){
- //console.log.apply(console,arguments);
process.stdout.write.apply(process.stdout,arguments);
}
@@ -45,8 +44,12 @@ function readopmap(fname){
return opmap;
}
-function outputfunc(opmap,name,gen,padw){
- print("int "+name+"(const char *op){\n");
+function outputfunc(_ /*opmap,name,gen,padw,dolen,rettype,defval,checkend*/){
+ let opmap=_.opmap, name=_.name, gen=_.gen,
+ padw=_.padw, dolen=_.dolen, rettype=_.rettype,
+ defval=_.defval, checkend=_.checkend;
+ print("\n"+rettype+" "+name+"(const char *op"+(dolen?",const int len":"")+"){\n");
+ if(dolen)print("\tif(len<=0)return "+defval+";\n");
print("\tswitch(op[0]){\n");
let firstchars={};
@@ -56,33 +59,98 @@ function outputfunc(opmap,name,gen,padw){
}
let arr=[];
for(k in firstchars){
- arr.push([k,firstchars[k].sort()]);
+ arr.push([k,firstchars[k].sort(function(a,b){
+ return b.length-a.length;
+ })]);
}
arr=arr.sort();
for(let tup of arr){
let k=tup[0],ops=tup[1];
print("\t\tcase '"+k+"': return ");
+ let expr="";
for(let op of ops){
- let cond="";
- for(j=1;j<op.length;j++)cond+="op["+j+"]=='"+op[j]+"'&&";
- cond+="op["+j+"]=='\\0'";
- print(cond+" ? "+pad(gen(opmap[op]),padw)+" : ");
+ let cond;
+ if(dolen){
+ cond="len=="+op.length;
+ for(j=1;j<op.length;j++)cond+="&&op["+j+"]=='"+op[j]+"'";
+ } else {
+ cond="";
+ for(j=1;j<op.length;j++)cond+="op["+j+"]=='"+op[j]+"'&&";
+ if(checkend)cond+="!op["+j+"]";
+ else cond=cond.slice(0,-2);
+ if(cond=="")cond="true";
+ }
+ expr+=cond+"?"+pad(gen(op,opmap[op]),padw)+":";
}
- print("-1;\n");
+ expr+=defval;
+ expr=expr.replace(/true\?([^:]*):[^)]*/,"$1");
+ print(expr+";\n");
}
- print("\t\tdefault: return -1;\n");
+ print("\t\tdefault: return "+defval+";\n");
print("\t}\n");
print("}\n");
}
const opmap=readopmap("LANGUAGE.txt");
-outputfunc(opmap,"precedence",o=>o.prec,2);
-print("\n");
const assocenum={
"Prefix": "AS_PREFIX", "Suffix": "AS_SUFFIX",
"Left": "AS_LEFT", "Right": "AS_RIGHT",
"Nonassociative": "AS_NONASSOC"
};
-outputfunc(opmap,"associativity",o=>assocenum[o.assoc],-11);
+
+print("#include <stddef.h>\n\n");
+print("#include \"opfuncs.h\"\n");
+print("#include \"parser.h\"\n");
+
+function alsolen(_){
+ outputfunc(_);
+ _.name+="_len";
+ _.dolen=true;
+ outputfunc(_);
+}
+
+alsolen({
+ opmap:opmap,
+ name:"precedence",
+ gen:(op,o)=>o.prec,
+ padw:2,
+ dolen:false,
+ rettype:"int",
+ defval:"-1",
+ checkend:true
+});
+
+alsolen({
+ opmap:opmap,
+ name:"associativity",
+ gen:(op,o)=>assocenum[o.assoc],
+ padw:-11,
+ dolen:false,
+ rettype:"int",
+ defval:"-1",
+ checkend:true
+});
+
+outputfunc({
+ opmap:opmap,
+ name:"parseoplength",
+ gen:(op,o)=>op.length,
+ padw:1,
+ dolen:false,
+ rettype:"int",
+ defval:"-1",
+ checkend:false
+});
+
+outputfunc({
+ opmap:opmap,
+ name:"opconststring_len",
+ gen:(op,o)=>'"'+op+'"',
+ padw:3,
+ dolen:true,
+ rettype:"const char*",
+ defval:"NULL",
+ checkend:true
+});