diff options
Diffstat (limited to 'genops.js')
-rwxr-xr-x | genops.js | 94 |
1 files changed, 81 insertions, 13 deletions
@@ -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 +}); |