Mercurial > repos > rhope
view jsbackend.rhope @ 156:ed70399a07aa
Add Substring method to string and improve performance of Partition
author | Mike Pavone <pavone@retrodev.com> |
---|---|
date | Thu, 23 Dec 2010 02:00:27 +0000 |
parents | fc3815b7462f |
children | 4580c08fd4e8 |
line wrap: on
line source
Import backendutils_c.rhope Blueprint JS Method Registry { Lookup Next ID } JS Method Registry[:out] { builtins <- [[[[[[[[[[[[[Dictionary[] ]Set["+", "METHOD_ADD"] ]Set["-", "METHOD_SUB"] ]Set["/", "METHOD_DIV"] ]Set["*", "METHOD_MUL"] ]Set["LShift", "METHOD_LSHIFT"] ]Set["RShift", "METHOD_RSHIFT"] ]Set["=", "METHOD_EQUALS"] ]Set[">", "METHOD_GREATER"] ]Set["<", "METHOD_LESS"] ]Set["If", "METHOD_IF"] ]Set["Set Missing Field", "METHOD_SETFIELDMISSING"] ]Set["Get Missing Field", "METHOD_GETFIELDMISSING"] ]Set["Missing Method", "METHOD_MISSING"] out <- [[Build[JS Method Registry()]]Lookup <<[builtins]]Next ID<<[0] } Register Method@JS Method Registry[reg,method:out] { [[reg]Lookup >>]Index[method] { out <- reg }{ method ID <- [reg]Next ID>> new lookup <- [[reg]Lookup >>]Set[method, ["METHOD_FIRST_USER+"]Append[String[method ID]]] out <- [[reg]Lookup <<[new lookup]]Next ID <<[[method ID]+[1]] } } Method ID@JS Method Registry[reg,method:out,notfound] { out,notfound <- [[reg]Lookup >>]Index[method] } Blueprint JS Field Registry { Lookup Next ID } JS Field Registry[:out] { out <- [[Build[JS Field Registry()]]Lookup <<[Dictionary[]]]Next ID<<[1] } Register Field@JS Field Registry[reg,field:out] { [[reg]Lookup >>]Index[field] { out <- reg }{ field ID <- [reg]Next ID>> new lookup <- [[reg]Lookup >>]Set[field, field ID] out <- [[reg]Lookup <<[new lookup]]Next ID <<[[field ID]+[1]] } } Field ID@JS Field Registry[reg,field:out,notfound] { out,notfound <- [[reg]Lookup >>]Index[field] } Blueprint JS Type { Name Fields Methods Init Copy Cleanup } JS Type[name:out] { out <- [[[[[[Build[JS Type()]]Name <<[name]]Fields <<[()]]Methods <<[()]]Init <<["NULL"]]Copy <<["NULL"]]Cleanup <<["NULL"] } Add Field@JS Type[ctype,name,type:out] { out <- [ctype]Fields <<[ [[ctype]Fields >>]Append[ [[()]Append[name]]Append[type] ] ] } Add Method@JS Type[ctype,name:out] { out <- [ctype]Methods <<[ [[ctype]Methods >>]Append[name] ] } Register Methods@JS Type[ctype,method reg:out] { out <- Fold[Register Method[?], method reg, [ctype]Methods >>] } _Register Field JS[reg,field:out] { name <- [field]Index[0] out <- [reg]Register Field[name] } Register Fields@JS Type[ctype,field reg:out] { out <- Fold[_Register Field JS[?], field reg, [ctype]Fields >>] } Type Init@JS Type[jstype,id,method reg,field reg,p:out] { ename <- Escape Rhope Name[[jstype]Name >>,p] [("Array", "Worker")]Find[=[[jstype]Name >>, ?]] { constructor <- [[[["var t_"]Append[ename]]Append[" = "]]Append[ [("Array","Function")]Index[~] ]]Append[";\n"] }{ constructor <- [["function t_"]Append[ename]]Append["()\n{}\n"] } out <- [[[[[constructor ]Append[ [[[["t_"]Append[ename]]Append[".prototype.type_id = "]]Append[id]]Append[";\n"] ] ]Append[ [["t_"]Append[ename]]Append[".prototype.conversions = new Array();\n"] ] ]Append[ [["t = new t_Blueprint;\nt.id = "]Append[id]]Append[";\n"] ] ]Append[ [["t.construct = t_"]Append[ename]]Append[";\n"] ] ]Append[ [["registered_types["]Append[id]]Append["] = t;\n\n"] ] } Blueprint JS Type Registry { Lookup Definitions Next ID Escape Pattern } JS Type Registry[p:out] { out <- [[[[Build[JS Type Registry()]]Lookup << [ [[[[[[[[[[[[[[[[[[Dictionary[] ]Set["UInt8", "TYPE_UINT8"] //1 ]Set["UInt16", "TYPE_UINT16"] //2 ]Set["UInt32", "TYPE_UINT32"] //3 ]Set["UInt64", "TYPE_UINT64"] //4 ]Set["Int8", "TYPE_INT8"] //5 ]Set["Int16", "TYPE_INT16"] //6 ]Set["Int32", "TYPE_INT32"] //7 ]Set["Int64", "TYPE_INT64"] //8 ]Set["Boolean", "TYPE_BOOLEAN"] //9 ]Set["Float32", "TYPE_FLOAT32"] //10 ]Set["Float64", "TYPE_FLOAT64"] //11 ]Set["Blueprint", "TYPE_BLUEPRINT"] //12 ]Set["Array", "TYPE_ARRAY"] //13 ]Set["Boxed Array", "TYPE_BOXEDARRAY"]//14 ]Set["Worker", "TYPE_WORKER"] //15 ]Set["Method Missing Exception", "TYPE_METHODMISSINGEXCEPTION"] //16 ]Set["Field Missing Exception", "TYPE_FIELDMISSINGEXCEPTION"] //17 ]Set["Wrong Type Exception", "TYPE_WRONGTYPEEXCEPTION"]] //18 ]Definitions << [Dictionary[]] ]Next ID <<[0] ]Escape Pattern <<[p] } _Type Inits JS[reg,method reg,field reg,text,def,name:out] { out <- [[text]Append[ [def]Type Init[[reg]Type ID[name], method reg, field reg,[reg]Escape Pattern >>] ]]Append["\n\n"] } Type Inits@JS Type Registry[reg,method reg,field reg:out] { out <- Fold[_Type Inits JS[reg, method reg, field reg, ?], "", [reg]Definitions >>] } Register Type@JS Type Registry[reg,def:out] { name <- [def]Name >> [[reg]Lookup >>]Index[name] { [[reg]Definitions >>]Index[name] { out <- reg }{ out <- [reg]Definitions <<[[[reg]Definitions >>]Set[name, def]] } }{ out <- [[[reg]Lookup <<[ [[reg]Lookup >>]Set[name, ["TYPE_FIRST_USER+"]Append[String[[reg]Next ID >>]]] ] ]Definitions <<[ [[reg]Definitions >>]Set[name, def] ] ]Next ID <<[ [[reg]Next ID >>]+[1] ] } } Type ID@JS Type Registry[reg,name:out,notfound] { out <- [[reg]Lookup >>]Index[name] {} { ,notfound <- If[[name]=["Any Type"]] { out <- "0" } } } Simple Type?@JS Type Registry[reg,name:yep,nope,notfound] { ,notfound <- [[reg]Definitions >>]Index[name] { yep,nope <- If[[[[~]Fields >>]Length] = [1]] } } Defined?@JS Type Registry[reg,name:yep,nope] { yep,nope <- [[reg]Definitions >>]Index[name] } Blueprint JS Function { Name Inputs Outputs Convention Variables Statements Method Registry Field Registry Type Registry Constants Input Types Output Types Resume Index Last NumParams Escape Pattern } JS Function[name,inputs,outputs,convention,p:out] { out <- JS Function With Registry[name,inputs,outputs,convention, JS Method Registry[], JS Field Registry[], JS Type Registry[p],p] } JS Function With Registry[name,inputs,outputs,convention,registry,field reg,type reg,p:out] { out <- [[[[[[[[[[[[[[[Build[JS Function()] ]Name <<[name] ]Inputs <<[inputs] ]Outputs <<[outputs] ]Convention <<[convention] ]Variables <<[Dictionary[]] ]Statements <<[()] ]Method Registry <<[registry] ]Field Registry <<[field reg] ]Type Registry <<[type reg] ]Constants <<[Dictionary[]] ]Input Types <<[ Fold[Append[?, "Any Type"], (), inputs] ] ]Output Types <<[ Fold[Append[?, "Any Type"], (), outputs] ] ]Resume Index <<[1] ]Last NumParams <<[-1] ]Escape Pattern <<[p] } Set Input Type@JS Function[func,type,input num:out] { out <- [func]Input Types <<[ [[func]Input Types >>]Set[input num, type] ] } Set Output Type@JS Function[func,type,output num:out] { out <- [func]Output Types <<[ [[func]Output Types >>]Set[output num, type] ] } Register Constant@JS Function[func,name,constant:out] { out <- [func]Constants <<[ [[func]Constants >>]Set[name, constant] ] } Allocate Var@JS Function[func,name,type:out] { out <- [func]Variables <<[ [[func]Variables >>]Set[name,type] ] } Add Statement@JS Function[func,statement:out] { out <- [func]Statements <<[ [[func]Statements >>]Append[["\t"]Append[[statement]Append[";\n"]]] ] } Add Raw Line@JS Function[func,line:out] { out <- [func]Statements <<[ [[func]Statements >>]Append[["\t"]Append[[line]Append["\n"]]] ] } Add Operator Statement@JS Function[func,psource1,psource2,pdest,op:out] { source1 <- [psource1]Make Op[func] source2 <- [psource2]Make Op[func] dest <- [pdest]Make Op[func] out <- [func]Add Statement[[[[[dest]Append[" = "]]Append[source1]]Append[op]]Append[source2]] } Make AddRef Op@JS Function[func,val:out] { out <- [val]Make Op[func] } Add@JS Function[func,source1,source2,dest:out] { out <- [func]Add Operator Statement[source1,source2,dest," + "] } Sub@JS Function[func,source1,source2,dest:out] { out <- [func]Add Operator Statement[source1,source2,dest," - "] } Multiply@JS Function[func,source1,source2,dest:out] { out <- [func]Add Operator Statement[source1,source2,dest," * "] } Get Constant Type@JS Function[func,const:out] { //TODO: Support more types as needed, particularly Float64 when support for that type is added in general val <- [[func]Constants >>]Index[const] {} { typename <- "Any Type" } [(Int32(),UInt8(),UInt32())]Find[=[val,?]] { typename <- [("Int32","UInt8","UInt32")]Index[~] } { typename <- "Any Type" } out <- Type Instance[typename] } Name Match[field,target name:out] { out <- [[field]Index[0]]=[target name] } Get Field Type@JS Function[func,otype,field:out] { def <- [[[func]Type Registry >>]Definitions >>]Index[[otype]Name >>] { [[~]Fields >>]Find[Name Match[?,field]] { out <- [[[def]Fields >>]Index[~]]Index[1] } { out <- Type Instance["Any Type"] } }{ out <- Type Instance["Any Type"] } } Get Var Type@JS Function[func,varname:out] { [[func]Inputs >>]Find[=[varname,?]] { out <- [[func]Input Types >>]Index[~] }{ [[func]Outputs >>]Find[=[varname,?]] { out <- [[func]Output Types >>]Index[~] }{ out <- [[func]Variables >>]Index[varname] {} { out <- Type Instance["Any Type"] } } } } Divide@JS Function[func,source1,source2,dest:out] { sourcetype <- [source1]Get Type[func] If[[[sourcetype]Name >>]=["Float64"]] { out <- [func]Add Operator Statement[source1,source2,dest," / "] }{ out <- [func]Add Statement[ [[[[[Make Op[dest, func]]Append[" = Math.floor(("]]Append[ Make Op[source1,func] ]]Append[") / ("]]Append[Make Op[source2, func]]]Append["))"] ] } } DoLShift@JS Function[func,source1,source2,dest:out] { out <- [func]Add Operator Statement[source1,source2,dest," << "] } DoRShift@JS Function[func,source1,source2,dest:out] { out <- [func]Add Operator Statement[source1,source2,dest," >> "] } BitAnd@JS Function[func,source1,source2,dest:out] { out <- [func]Add Operator Statement[source1,source2,dest," & "] } BitOr@JS Function[func,source1,source2,dest:out] { out <- [func]Add Operator Statement[source1,source2,dest," | "] } CompLess@JS Function[func,source1,source2,dest:out] { out <- [func]Add Operator Statement[source1,source2,dest," < "] } CompGreater@JS Function[func,source1,source2,dest:out] { out <- [func]Add Operator Statement[source1,source2,dest," > "] } CompEqual@JS Function[func,source1,source2,dest:out] { out <- [func]Add Operator Statement[source1,source2,dest," == "] } CompLessEqual@JS Function[func,source1,source2,dest:out] { out <- [func]Add Operator Statement[source1,source2,dest," <= "] } CompGreaterEqual@JS Function[func,source1,source2,dest:out] { out <- [func]Add Operator Statement[source1,source2,dest," >= "] } CompNotEqual@JS Function[func,source1,source2,dest:out] { out <- [func]Add Operator Statement[source1,source2,dest," != "] } Move@JS Function[func,psource,pdest:out] { source <- [psource]Make Op[func] dest <- [pdest]Make Op[func] out <- [func]Add Statement[[[dest]Append[" = "]]Append[source]] } Do AddRef@JS Function[func,psource,pdest:out] { out <- [func]Move[psource,pdest] } AddRef No Dest@JS Function[func,psource:out] { out <- func } Release@JS Function[func,psource:out] { out <- func } Set Null@JS Function[func,pdest:out] { dest <- [pdest]Make Op[func] out <- [func]Add Statement[[dest]Append[" = null"]] } Lookup Constant@JS Function[func,const,doaddref:out] { out <- ["_const_"]Append[Escape Rhope Name[const,[func]Escape Pattern >>]] } Field Result@JS Function[func,var,field:out] { as op <- [var]Make Op[func] out <- [[as op]Append[".p_"]]Append[Escape Rhope Name[field,[func]Escape Pattern >>]] } Read Field@JS Function[func,var,field:out,result op] { out <- func result op <- Field Ref[var,field] } Write Field@JS Function[func,var,field:out,result op] { out <- func result op <- Field Ref[var,field] } Set Field Null@JS Function[func,var,field:out] { out <- [func]Add Statement[ [[func]Field Result[var,field]]Append[" = null"] ] } Copy@JS Function[func,pdest:out] { dest <- [pdest]Make Op[func] out <- [func]Add Statement[ [dest]Append[[[" = copy_object("]Append[dest]]Append[")"]] ] } Box@JS Function[func,psource,pdest,type:out] { dest <- [pdest]Make Op[func] source <- [psource]Make Op[func] typename <- [type]Name >> [("Int32","UInt32","UInt8")]Find[=[typename,?]] { out <- [func]Add Statement[ [[[[dest]Append[[" = make_"]Append[typename]]]Append["("]]Append[source]]Append[")"] ] }{ If[[typename]=["Boolean"]] { out <- [func]Add Statement[ [[[[dest]Append[" = make_Bool"]]Append["("]]Append[source]]Append[")"] ] }{ out <- [func]Move[psource,pdest] } } } Unbox@JS Function[func,psource,pdest:out] { dest <- [pdest]Make Op[func] source <- [psource]Make Op[func] out <- [func]Add Statement[ [[[dest]Append[" = "]]Append[source]]Append[".unbox()"] ] } Get Raw Pointer@JS Function[func,psource,pdest:out] { out <- func } Array Raw Pointer@JS Function[func,psource,pdest:out] { dest <- [pdest]Make Op[func] source <- [psource]Make Op[func] out <- [func]Add Statement[ [[[dest]Append[" = ((char *)"]]Append[source]]Append[")+ sizeof(t_Array)"] ] } _Function Arg JS[func,val,inputnum:out] { out <- [func]Add Raw Line[ [[[["SetParam(" ]Append[String[inputnum]] ]Append[", "] ]Append[val] ]Append[")"] ] } _Val Function Arg JS[func,val,inputnum,worker:out] { out <- [func]Add Raw Line[ [[[[[["VCSetParam(" ]Append[worker] ]Append[", "] ]Append[String[inputnum]] ]Append[", "] ]Append[val] ]Append[")"] ] } Method Call@JS Function[func,method,args:out] { If[[method]=["Call"]] { out <- [[[[[func]Add Raw Line[[["if ("]Append[Make Op[[args]Index[0], func]]]Append[".type_id == TYPE_WORKER) {"]] ]Val Call[[args]Index[0], Tail[args,1]] ]Add Raw Line["} else {"] ]Func Base["Call",args, "MCall"] ]Add Raw Line["}"] }{ out <- [func]Func Base[Escape Rhope Name[method,[func]Escape Pattern >>],args, "MCall"] } } Val Call@JS Function[func,to call,args:out] { worker <- Make Op[to call, func] rargs <- Map[args, Make Op[?, func]] out <- [[[[[func]Add Raw Line[[[[["if ("]Append[worker]]Append[".Args.length > 0 || "]]Append[worker]]Append[".IsMethod) { "]] ]Add Statement[[[[[" res = valcall("]Append[worker]]Append["["]]Append[ [rargs]Join[","] ]]Append["])"]] ]Add Raw Line["} else {"] ]Add Statement[[[[[" res = "]Append[worker]]Append["("]]Append[ [rargs]Join[","] ]]Append[")"]] ]Add Raw Line["}"] } Call@JS Function[func,name,args:out] { If[[name]=["Call@Worker"]] { //TODO: Handle case when user explicitly calls the fully qualified version, but the type of the first arg isn't Worker out <- [func]Val Call[[args]Index[0], Tail[args,1]] }{ out <- [func]Func Base[Escape Rhope Name[name,[func]Escape Pattern >>],args, "Call"] } } Func Base@JS Function[func,tocall,args,type:out] { Print[ [[func]Name >>]Append[ [": Func Base("]Append[tocall] ] ] rargs <- Map[args, Make Op[?, func]] If[[type]=["MCall"]] { out <- [func]Add Statement[[[[[[["res = "]Append[[rargs]Index[0]]]Append[".f_"]]Append[tocall]]Append["("]]Append[ [Tail[rargs, 1]]Join[","] ]]Append[")"]] }{ out <- [func]Add Statement[[[[["res = f_"]Append[tocall]]Append["("]]Append[ [rargs]Join[","] ]]Append[")"]] } } Call Foreign@JS Function[func,name,language,args,store result:out] { rargs <- Map[args, Make Op[?, func]] //Assume language = "JS" for now If[[name]Ends With["@"]] { base <- [[[[[[rargs]Index[0]]Append["."]]Append[ [name]Slice[ [[name]Length]-[1] ] ]]Append["("]]Append[ [Tail[rargs,1]]Join[","] ]]Append[")"] }{ base <- [[[name]Append["("]]Append[ Join[rargs, ", "] ]]Append[")"] } ,do store <- [(String(), String Slice(), String Cat())]Find[=[Blueprint Of[store result], ?]] { ,do store <- If[[store result]=[""]] { stmt <- Val[base] } } Val[do store] { stmt <- [[Make Op[store result, func]]Append[" = "]]Append[base] } out <- [func]Add Statement[stmt] } Get Field Call@JS Function[func,field,source:out] { //This will need to change later when I add support for "Field Missing" efield <- Escape Rhope Name[field, [func]Escape Pattern >>] out <- [func]Add Statement[[[[["res = ["]Append[Make Op[source,func]]]Append[".p_"]]Append[efield]]Append["]"]] } Set Field Call@JS Function[func,field,object,value:out] { out <- [func]Func Base[Escape Rhope Name[[field]Append[" <<"],[func]Escape Pattern >>], [[()]Append[object]]Append[value], "MCall"] } Tail Method Call@JS Function[func,method,args:out] { //Javascript doesn't support tail calls, at least not directly anyway out <- [func]Method Call[method,args] } Tail Call@JS Function[func,name,args:out] { If[[name]=[[func]Name >>]] { //TODO: Support simple tail recursion out <- func }{ out <- [func]Call[name,args] } } Resolve@JS Function[func,op:out] { If[[[func]Convention >>] = ["rhope"]] { out <- ["lv_"]Append[Escape Rhope Name[op, [func]Escape Pattern >>]] }{ out <- Escape Rhope Name[op,[func]Escape Pattern >>] } } Resolve Output@JS Function[func,name:out] { If[[[func]Convention >>] = ["rhope"]] { out <- ["lv_"]Append[Escape Rhope Name[name, [func]Escape Pattern >>]] }{ out <- Escape Rhope Name[name,[func]Escape Pattern >>] } } Instruction Stream@JS Function[func:out] { out <- [func]Statements <<[()] } _If JS[func, statement:out] { out <- [func]Statements <<[ [[func]Statements >>]Append[ ["\t"]Append[statement] ] ] } Do If@JS Function[func,condition,stream:out] { cond <- [condition]Make Op[func] If[[[stream]Statements >>]Length] { out <- [Fold[_If JS[?], [[func ]Add Raw Line[ [["if("]Append[cond]]Append[")"] ] ]Add Raw Line["{"], [stream]Statements >>] ]Add Raw Line["}"] }{ out <- func } } Discard Outputs@JS Function[func,first to discard:out] { out <- func } Result Reference@JS Function[func,output:out] { out <- [["res["]Append[String[output]]]Append["]"] } Checked Result Reference@JS Function[func,output:out] { out <- [func]Result Reference[output] } If Null Else@JS Function[func,left,right:out] { check <- [Make Condition[left]]Make Op[func] l <- [left]Make Op[func] r <- [right]Make Op[func] out <- [[[[[["(" ]Append[check] ]Append[" != null ? "] ]Append[l] ]Append[" : "] ]Append[r] ]Append[")"] } Set Outputs@JS Function[func:out] { If[[[func]Convention >>] = ["rhope"]] { out <- [["\treturn ["]Append[ [ Map[Map[[func]Outputs >>, Escape Rhope Name[?, [func]Escape Pattern >>]], ["lv_"]Append[?]] ]Join[","] ]]Append["];\n"] }{ [[func]Outputs >>]Index[0] { out <- [["\treturn "]Append[Escape Rhope Name[~,[func]Escape Pattern >>]]]Append[";\n"] }{ out <- "" } } } Check Param Type JS[text,type,input num,func:out] { [(String(),String Cat(),String Slice())]Find[=[Blueprint Of[type],?]] { typename <- type }{ typename <- [type]Name >> } If[[typename] = ["Any Type"]] { out <- text }{ input <- ["lv_"]Append[Escape Rhope Name[[[func]Inputs >>]Index[input num], [func]Escape Pattern >>]] out <- [text]Append[ [[[["\t"]Append[input]]Append["= check_type("]]Append[input]]Append[ [[", "]Append[ [[func]Type Registry >>]Type ID[typename] ]]Append[");"] ] ] } } _Add Prefix[val:out] { out <- ["lv_"]Append[val] } Text@JS Function[func:out] { Print[["Text@JS Function: "]Append[[func]Name >>]] If[ [[func]Convention >>] = ["rhope"] ] { before,,after <- [[func]Name >>]Partition["@"] { If[[after]=[""]] { norm name <- Val[before] } { ivars <- Tail[[func]Inputs >>, 1] cname <- [[["t_"]Append[Escape Rhope Name[after,[func]Escape Pattern >>]] ]Append[[".prototype.f_"]Append[Escape Rhope Name[before,[func]Escape Pattern >>]]] ]Append[" = function"] [[func]Inputs >>]Index[0] { move this <- ["\tlv_"]Append[[Escape Rhope Name[~, [func]Escape Pattern >>]]Append[" = this;"]] } { move this <- "" } } } {} {} { norm name <- Name >>[func] } Val[norm name] { ivars <- [func]Inputs >> fname <- ["f_"]Append[Escape Rhope Name[norm name,[func]Escape Pattern >>]] move this <- "" } inproc <- Val[Map[?, _Add Prefix[?]]] }{ fname <- Escape Rhope Name[[func]Name >>,[func]Escape Pattern >>] ivars <- Inputs >>[func] move this <- "" inproc <- Val[Val[?]] } cname <- ["function "]Append[fname] param check <- Fold[Check Param Type JS[?, ?, ?, func], "", [func]Input Types >>] allvars <- Concatenate[[func]Outputs >>, Keys[[func]Variables >>]] If[[allvars]Length] { vardec <- [["\tvar "]Append[ [ [inproc]Call[Map[allvars, Escape Rhope Name[?, [func]Escape Pattern >>]]] ]Join[","] ]]Append[";\n"] }{ vardec <- "" } out <- [[[[[[[[[cname ]Append["("] ]Append[ [[inproc]Call[Map[ivars, Escape Rhope Name[?, [func]Escape Pattern >>]]]]Join[","] ] ]Append[")\n{\n"] ]Append[move this] ]Append[param check] ]Append[vardec] ]Append[ [[func]Statements >>]Join[""] ] ]Append[[func]Set Outputs] ]Append["}"] } Blueprint JS Program { Functions Method Registry Field Registry Type Registry Libraries Escape Pattern } JS Program[:out] { p <- Pattern[("_", "@", " ", ":", "?", "+", "-", "*", "/", "<", ">", "(", ")", "!", "=", "'", "\"", "\t", ",", ".", "\n", "{", "}", "[", "]", "#", "\\", "\r", ";", "&", "|", "%", "^", "`", "~")] out <- [[[[[[Build[JS Program()]]Functions <<[Dictionary[]]]Method Registry <<[JS Method Registry[]]]Type Registry <<[JS Type Registry[p]]]Field Registry <<[JS Field Registry[]]]Libraries <<[Dictionary[]]]Escape Pattern <<[p] } Supported Number Types@JS Program[program:out] { out <- ("Int32","UInt8","UInt32") } Needed Specials@JS Program[program,typename,makespecial:out] { out <- () } Set Stdlib Imports@JS Program[program,parser:out] { out <- [parser]Imports <<[ [[parser]Imports >>]Set["kerneljs.rhope", Yes] ] } Link@JS Program[program,language,library:out] { If[[library] = ["runtime"]] { out <- program }{ langlibs <- [[program]Libraries >>]Index[language] {} { langlibs <- Dictionary[] } out <- [program]Libraries <<[ [[program]Libraries >>]Set[language, [langlibs]Set[library, Yes]] ] } } Register Type@JS Program[program,def:out] { out <- [[[program]Type Registry <<[ [[program]Type Registry >>]Register Type[def] ] ]Method Registry <<[ [def]Register Methods[[program]Method Registry >>] ] ]Field Registry <<[ [def]Register Fields[[program]Field Registry >>] ] } Create Type@JS Program[program,name:out] { out <- JS Type[name] } Create Function@JS Program[program,name,inputs,outputs,convention:out] { out <- JS Function With Registry[name,inputs,outputs,convention, [program]Method Registry >>, [program]Field Registry >>, [program]Type Registry >>, [program]Escape Pattern >>] } Store Function@JS Program[program,func:out] { out <- [program]Functions <<[ [[program]Functions >>]Set[ [func]Name >>, func] ] } Method?@JS Program[program,funcname:is,isnot] { is,isnot <- [[program]Method Registry >>]Method ID[funcname] } _Text JS Program[text,func,type reg:out] { out <- [text]Append[[[ [func]Type Registry <<[type reg] ]Text]Append["\n\n"]] } Combine Consts[consts,func:out] { out <- Combine[[func]Constants >>, consts] } _List Literal El[text,val,index,type reg:out] { out <- [[[[text ]Append[", "] ]Append[index] ]Append[", "] ]Append[Const Construct JS[val, type reg]] } Const Construct JS[value,type reg:out] { valtype <- Blueprint Of[value] [(Int8(),UInt8(),Int16(),UInt16(),Int32(),UInt32(),Int64(),UInt64())]Find[=[valtype,?]] { size <- [("8","16","32","64")]Index[[~]/[2]] If[[~]Mod[2]] { s <- "UI" } { s <- "I" } out <- [[[[[["make_" ]Append[s] ]Append["nt"] ]Append[size] ]Append["("] ]Append[String[value]] ]Append[")"] }{ If[[valtype] = [Type Instance()]] { //TODO: Support parametric types typeid <- [type reg]Type ID[[value]Name >>] out <- [["make_Blueprint("]Append[typeid]]Append[")"] }{ If[[valtype] = [Boolean()]] { If[value] { out <- "make_Bool(true)" }{ out <- "make_Bool(false)" } }{ [(String(),String Slice(),String Cat())]Find[=[valtype,?]] { out <- [["make_String(\""]Append[ [[[[value]Replace["\\", "\\\\"]]Replace["\n", "\\n"]]Replace["\"", "\\\""]]Replace["\r", "\\r"] ]]Append["\")"] }{ If[[valtype]=[Worker Literal()]] { //TODO: Figure out how to fully support these in nested cases //or workaround the problem higher up in the food chain [[value]Args >>]Last { size <- String[[~]+[1]] } { size <- "0" } out <- [[[[[["make_Worker(f_" ]Append[Escape Rhope Name[[value]Name >>,[type reg]Escape Pattern >>]] ]Append[", "] ]Append[size] ]Append[", "] ]Append[String[Fold[+[1,?], 0, [value]Args >>]]] ]Append[")"] }{ [(List(), List Leaf())]Find[=[?,valtype]] { out <- [Fold[_List Literal El[?, ?, ?, type reg], ["make_List("]Append[String[[value]Length]], value]]Append[")"] }{ out <- "UnhandledLiteralType" } } } } } } } _Set Worker Params JS[text,param,num,type reg,name:out] { out <- [text]Append[ [[[[[["\t((object **)(((t_Worker *)_const_" ]Append[name] ]Append[")+1))["] ]Append[String[num]] ]Append["] = "] ]Append[Const Construct JS[param, type reg]] ]Append[";\n"] ] } _Set Consts JS Program[text,value,name,type reg:out] { valtype <- Blueprint Of[value] [(String(),String Cat(),String Slice(),Worker Literal(),List(),List Leaf())]Find[=[valtype,?]] { out <- text }{ Const Construct JS[value,type reg] { out <- [text]Append[ [[[["var _const_"]Append[Escape Rhope Name[name,[type reg]Escape Pattern >>]]]Append[" = "]]Append[~]]Append[";\n"] ] } } } _Set List Els[text,el,index,type reg:out] { out <- [[text]Append[ [["\tinout[1] = " ]Append[Const Construct JS[index,type reg]] ]Append[ [[";\n\tinout[2] = " ]Append[Const Construct JS[el, type reg]] ]Append[";\n"] ]]]Append["\trhope(FUNC_Set, inout, 3, 3);\n"] } _Set Late Consts JS[text,value,name,type reg:out] { valtype <- Blueprint Of[value] [(String(),String Cat(),String Slice(),Worker Literal(),List(),List Leaf())]Find[=[valtype,?]] { If[[~]>[3]] { out <- [Fold[_Set List Els[?, ?, ?, type reg], [text]Append["\trhope(FUNC_List, inout, 0, 1);\n"], value] ]Append[[["var _const_"]Append[Escape Rhope Name[name,[type reg]Escape Pattern >>]]]Append[" = inout[0];\n"]] }{ Const Construct JS[value,type reg] { init <- [text]Append[ [[[["var _const_"]Append[Escape Rhope Name[name,[type reg]Escape Pattern >>]]]Append[" = "]]Append[~]]Append[";\n"] ] } If[[valtype]=[Worker Literal()]] { out <- Fold[_Set Worker Params JS[?, ?, ?, type reg, Escape Rhope Name[name,[type reg]Escape Pattern >>]], init, [value]Args >>] }{ out <- Val[init] } } }{ out <- text } } Text Filename@JS Program[program,source name:out] { out <- [source name]Append[".js"] } Text@JS Program[program:out] { p <- [program]Escape Pattern >> constants <- Fold[Combine Consts[?], Dictionary[], [program]Functions >>] out <- [[[[[[" var i = 0; var TYPE_ANY = i++; var TYPE_INT32 = i++; var TYPE_UINT8 = i++; var TYPE_UINT32 = i++; var TYPE_BOOLEAN = i++; var TYPE_FLOAT64 = i++; var TYPE_BLUEPRINT = i++; var TYPE_ARRAY = i++; var TYPE_WORKER = i++; var TYPE_FIRST_USER = i; Object.prototype.unbox = function() { return this; } registered_types = new Array(); function t_Blueprint() { } t_Blueprint.prototype.type_id = TYPE_BLUEPRINT; t_Blueprint.prototype.conversions = new Array(); var t = new t_Blueprint; t.id = TYPE_BLUEPRINT; t.construct = t_Blueprint; registered_types[TYPE_BLUEPRINT] = t;\n\n" ]Append[ [[program]Type Registry >>]Type Inits[[program]Method Registry >>, [program]Field Registry >>] ] ]Append[" t_Int32.prototype.unbox = function() { return this.p_Num; } t_UInt32.prototype.unbox = function() { return this.p_Num; } t_UInt8.prototype.unbox = function() { return this.p_Num; } t_Boolean.prototype.unbox = function() { return this.p_Val; } function make_Int32(val) { var out = new t_Int32; out.p_Num = val; return out; } function make_UInt8(val) { var out = new t_UInt8; out.p_Num = val & 255; return out; } function make_UInt32(val) { var out = new t_UInt32; out.p_Num = val; return out; } function make_Bool(val) { var out = new t_Boolean; out.p_Val = val; return out; } function make_Float64(val) { var out = new t_Float64; out.p_Num = val; return out; } function make_String(string) { var out = new t_String; out.p_Buffer = string; return out; } function make_Blueprint(typeid) { return registered_types[typeid]; } function check_type(val,typeid) { if (val.type_id = typeid) { return val; } if (val.conversions[type_id] != undefined) { var out = val.conversions[type_id](val); return out[0]; } throw new Error(\"Conversion needed\"); } function copy_object(obj) { if (obj.type_id == TYPE_ARRAY) { return obj.slice(0); } var dest = new registered_types[obj.type_id].construct; for (var prop in obj) { if (obj.hasOwnProperty(prop)) { dest[prop] = obj[prop]; } } return dest; } function _internal_js_length(arr) { return arr.length; } function _internal_js_eq(left,right) { return left == right; } function _internal_array_set(arr,index,val) { arr[index] = val; } function _internal_array_get(arr,index) { return arr[index] } function f_Build(type) { type = check_type(type, TYPE_BLUEPRINT); return [new type.construct()]; } function f_BlueprintSP_Of(val) { return [registered_types[val.type_id]]; } function f_ID(type) { type = check_type(type, TYPE_BLUEPRINT); return [type.id]; } function f_BlueprintSP_FromSP_ID(id) { id = check_type(id, TYPE_UINT32); if (id.p_Num > 0 && registered_types[id.p_Num] != null) { return [registered_types[id.p_Num], null]; } else { return [null,id]; } }\n"] ]Append[Fold[_Text JS Program[?, ?, [program]Type Registry >>], "", [program]Functions >>]] ]Append[Fold[_Set Consts JS Program[?, ?, ?, [program]Type Registry >>], "", constants]] ]Append[Fold[_Set Late Consts JS[?, ?, ?, [program]Type Registry >>], "", constants]] ]Append[" try { var args = f_List()[0]; for (var i in arguments) { args = args.f_Append(make_String(arguments[i]))[0]; } res = f_Main(args); } catch(e) { res = f_Main(); } if (res[0] != null && res[0].type_id == TYPE_INT32) { print(res[0].p_Num); } "] }