comparison jsbackend.rhope @ 133:e1911b2fd5cc

Start work on Javascript backend
author Mike Pavone <pavone@retrodev.com>
date Wed, 10 Nov 2010 22:29:33 -0500
parents
children 18a4403fe576
comparison
equal deleted inserted replaced
132:1f238280047f 133:e1911b2fd5cc
1 Import backendutils_c.rhope
2
3 Blueprint JS Method Registry
4 {
5 Lookup
6 Next ID
7 }
8
9 JS Method Registry[:out]
10 {
11 builtins <- [[[[[[[[[[[[[Dictionary[]
12 ]Set["+", "METHOD_ADD"]
13 ]Set["-", "METHOD_SUB"]
14 ]Set["/", "METHOD_DIV"]
15 ]Set["*", "METHOD_MUL"]
16 ]Set["LShift", "METHOD_LSHIFT"]
17 ]Set["RShift", "METHOD_RSHIFT"]
18 ]Set["=", "METHOD_EQUALS"]
19 ]Set[">", "METHOD_GREATER"]
20 ]Set["<", "METHOD_LESS"]
21 ]Set["If", "METHOD_IF"]
22 ]Set["Set Missing Field", "METHOD_SETFIELDMISSING"]
23 ]Set["Get Missing Field", "METHOD_GETFIELDMISSING"]
24 ]Set["Missing Method", "METHOD_MISSING"]
25 out <- [[Build[JS Method Registry()]]Lookup <<[builtins]]Next ID<<[0]
26
27 }
28
29 Register Method@JS Method Registry[reg,method:out]
30 {
31 [[reg]Lookup >>]Index[method]
32 {
33 out <- reg
34 }{
35 method ID <- [reg]Next ID>>
36 new lookup <- [[reg]Lookup >>]Set[method, ["METHOD_FIRST_USER+"]Append[String[method ID]]]
37 out <- [[reg]Lookup <<[new lookup]]Next ID <<[[method ID]+[1]]
38 }
39 }
40
41 Method ID@JS Method Registry[reg,method:out,notfound]
42 {
43 out,notfound <- [[reg]Lookup >>]Index[method]
44 }
45
46 Blueprint JS Field Registry
47 {
48 Lookup
49 Next ID
50 }
51
52 JS Field Registry[:out]
53 {
54 out <- [[Build[JS Field Registry()]]Lookup <<[Dictionary[]]]Next ID<<[1]
55
56 }
57
58 Register Field@JS Field Registry[reg,field:out]
59 {
60 [[reg]Lookup >>]Index[field]
61 {
62 out <- reg
63 }{
64 field ID <- [reg]Next ID>>
65 new lookup <- [[reg]Lookup >>]Set[field, field ID]
66 out <- [[reg]Lookup <<[new lookup]]Next ID <<[[field ID]+[1]]
67 }
68 }
69
70 Field ID@JS Field Registry[reg,field:out,notfound]
71 {
72 out,notfound <- [[reg]Lookup >>]Index[field]
73 }
74
75 Blueprint JS Type
76 {
77 Name
78 Fields
79 Methods
80 Init
81 Copy
82 Cleanup
83
84 }
85
86 JS Type[name:out]
87 {
88 out <- [[[[[[Build[JS Type()]]Name <<[name]]Fields <<[()]]Methods <<[()]]Init <<["NULL"]]Copy <<["NULL"]]Cleanup <<["NULL"]
89 }
90
91 Add Field@JS Type[ctype,name,type:out]
92 {
93 out <- [ctype]Fields <<[ [[ctype]Fields >>]Append[ [[()]Append[name]]Append[type] ] ]
94 }
95
96 Add Method@JS Type[ctype,name:out]
97 {
98 out <- [ctype]Methods <<[ [[ctype]Methods >>]Append[name] ]
99 }
100
101 Register Methods@JS Type[ctype,method reg:out]
102 {
103 out <- Fold[Register Method[?], method reg, [ctype]Methods >>]
104 }
105
106 _Register Field JS[reg,field:out]
107 {
108 name <- [field]Index[0]
109 out <- [reg]Register Field[name]
110 }
111
112 Register Fields@JS Type[ctype,field reg:out]
113 {
114 out <- Fold[_Register Field JS[?], field reg, [ctype]Fields >>]
115 }
116
117 Rhope Type to JS[type,p:out,array]
118 {
119 If[[Blueprint Of[type]]=[Type Instance()]]
120 {
121 variant <- [type]Variant >>
122 If[[[type]Name >>] = ["Array"]]
123 {
124 [("Naked","Raw Pointer")]Find[=[variant,?]]
125 {
126 /*
127 //Below code assumes that paramaterized types are implemented
128 pre param <- [[type]Params >>]Index[0] {}
129 { pre param <- Type Instance["Any Type"] }
130 [[type]Params >>]Index[1]
131 { param,param <- [pre param]Set Variant[~] }
132 { param <- Val[pre param] }
133 child type <- Rhope Type to JS[param]
134 If[[variant] = ["Naked"]]
135 {
136 out <- Val[child type]
137 array <- "[1]"
138 }{
139 out <- [child type]Append[" *"]
140 array <- ""
141 } */
142 out <- "void *"
143 array <- ""
144 }{
145 typename <- "Array"
146 }
147 primitive <- No
148 }{
149 ,regulartype <- [("Naked","Raw Pointer")]Find[=[variant,?]]
150 {
151 [("Int64","Int32","Int16","Int8")]Find[=[[type]Name >>,?]]
152 {
153 primitive <- Yes
154 [[type]Name >>]Slice[3] {}
155 { typename <- [["int"]Append[~]]Append["_t"] }
156 }{
157 ,regulartype <- [("UInt64","UInt32","UInt16","UInt8")]Find[=[[type]Name >>,?]]
158 {
159 primitive <- Yes
160 [[type]Name >>]Slice[4] {}
161 { typename <- [["uint"]Append[~]]Append["_t"] }
162 }
163 }
164 }
165
166 Val[regulartype]
167 {
168 typename <- [type]Name >>
169 primitive <- No
170 }
171 }
172 }{
173 typename <- type
174 param <- "Any Type"
175 variant <- "boxed"
176 primitive <- No
177 }
178
179 Val[typename]
180 { array <- "" }
181 If[[typename] = ["Any Type"]]
182 {
183 out <- "struct object *"
184 }{
185 [("Naked","Raw Pointer")]Find[=[variant,?]]
186 {
187 If[primitive]
188 {
189 prefix <- ""
190 }{
191 prefix <- "nt_"
192 }
193 }{
194 prefix <- "t_"
195 }
196
197 If[[variant]=["Naked"]]
198 {
199 postfix <- ""
200 }{
201 postfix <- " *"
202 }
203 }
204 If[primitive]
205 {
206 escaped <- Val[typename]
207 }{
208 escaped <- Escape Rhope Name[typename,p]
209 }
210 out <- [[prefix]Append[escaped]]Append[postfix]
211 }
212
213 _Type Def JS Type[text,field,p:out]
214 {
215 name <- [field]Index[0]
216 ,postfix <- Rhope Type to JS[[field]Index[1],p]
217 { type <- ["\n\t"]Append[~] }
218
219 out <- [[[[text]Append[type]]Append[" "]]Append[[Escape Rhope Name[name,p]]Append[postfix]]]Append[";"]
220 }
221
222 Type Def@JS Type[ctype,p:out]
223 {
224 If[[[[ctype]Fields >>]Length] = [1]]
225 {
226 out <- [[[[_Type Def JS Type["typedef struct {\n\tobject _SP_header;\n\t", [[ctype]Fields >>]Index[0], p]]Append["\n} t_"]]Append[Escape Rhope Name[[ctype]Name >>,p]]]Append[";"]
227 ]Append[
228 [[[["typedef "
229 ]Append[Rhope Type to JS[ [[[ctype]Fields >>]Index[0]]Index[1],p ]]
230 ]Append[" nt_"]
231 ]Append[Escape Rhope Name[[ctype]Name >>,p]]
232 ]Append[";"] ]
233 }{
234 //HACK!!!
235 If[[[ctype]Name >>]=["Blueprint"]]
236 {
237 out <- ""
238 }{
239 [("Array","Boxed Array","Worker")]Find[=[[ctype]Name >>,?]]
240 { oend <- "\nMObject(" }
241 { oend <- "\nObject(" }
242 out <- [Fold[_Type Def JS Type[?,?,p], "OBegin", [ctype]Fields >>]]Append[ [[oend]Append[Escape Rhope Name[[ctype]Name >>,p]]]Append[")"] ]
243 }
244 }
245 }
246
247 _Type Init JS[type name,method reg,text,method,p:out]
248 {
249 out <- [[text]Append[[["\n\tadd_method(bp, "]Append[ [method reg]Method ID[method] ]]Append[ [[", MethodName("]Append[Escape Rhope Name[method,p]]]Append[[","]Append[Escape Rhope Name[type name,p]]]]]]Append["));"]
250 }
251
252 _Type Init JS Field[type name,field reg,text,field,p:out]
253 {
254 fname <- [field]Index[0]
255 out <- [[[[text]Append[[["\n\tadd_getter(bp, "]Append[ String[[field reg]Field ID[fname]] ]]Append[ [[", MethodName("]Append[Escape Rhope Name[[fname]Append[" >>"],p]]]Append[[","]Append[Escape Rhope Name[type name,p]]]]]]Append["));"]
256 ]Append[[["\n\tadd_setter(bp, "]Append[ String[[field reg]Field ID[fname]] ]]Append[ [[", MethodName("]Append[Escape Rhope Name[[fname]Append[" <<"],p]]]Append[[","]Append[Escape Rhope Name[type name,p]]]]]]Append["));"]
257 }
258
259 Type Init@JS Type[ctype,id,method reg,field reg,p:out]
260 {
261 [("Array","Boxed Array", "Worker")]Find[=[[ctype]Name >>, ?]]
262 { size <- "-1" }
263 {
264 [("Int64","Int32","Int16","Int8")]Find[=[[ctype]Name >>, ?]]
265 {
266 [[ctype]Name >>]Slice[3] {}
267 { typename <- [["int"]Append[~]]Append["_t"] }
268 }{
269 [("UInt64","UInt32","UInt16","UInt8")]Find[=[[ctype]Name >>, ?]]
270 {
271 [[ctype]Name >>]Slice[4] {}
272 { typename <- [["uint"]Append[~]]Append["_t"] }
273 }{
274 If[[[ctype]Name >>]=["Blueprint"]]
275 { typename <- "blueprint *" }
276 {
277 If[[[ctype]Name >>]=["Boolean"]]
278 { typename <- "int32_t" }
279 { typename <- ["nt_"]Append[Escape Rhope Name[[ctype]Name >>,p]] }
280 }
281 }
282 }
283 size <- [["sizeof("]Append[typename]]Append[")"]
284 }
285 start <- [["\tbp = register_type_byid("
286 ]Append[id]
287 ]Append[
288 [[", "]Append[size]
289 ]Append[
290 [", (special_func)"]Append[
291 [
292 [[[[Escape Rhope Name[[ctype]Init >>,p]
293 ]Append[", (special_func)"]
294 ]Append[Escape Rhope Name[[ctype]Copy >> ,p]]
295 ]Append[", (special_func)"]
296 ]Append[Escape Rhope Name[[ctype]Cleanup >>,p]]
297 ]Append[");"]]] ]
298 out <- Val[start]//Fold[[["_Type Init JS Field"]Set Input[0, [ctype]Name >>]]Set Input[1, field reg], Fold[[["_Type Init JS"]Set Input[0, [ctype]Name >>]]Set Input[1, method reg], start, [ctype]Methods >>], [ctype]Fields >>]
299 }
300
301 Blueprint JS Type Registry
302 {
303 Lookup
304 Definitions
305 Next ID
306 Escape Pattern
307 }
308
309 JS Type Registry[p:out]
310 {
311 out <- [[[[Build[JS Type Registry()]]Lookup << [
312 [[[[[[[[[[[[[[[[[[[Dictionary[]
313 ]Set["UInt8", "TYPE_UINT8"] //1
314 ]Set["UInt16", "TYPE_UINT16"] //2
315 ]Set["UInt32", "TYPE_UINT32"] //3
316 ]Set["UInt64", "TYPE_UINT64"] //4
317 ]Set["Int8", "TYPE_INT8"] //5
318 ]Set["Int16", "TYPE_INT16"] //6
319 ]Set["Int32", "TYPE_INT32"] //7
320 ]Set["Int64", "TYPE_INT64"] //8
321 ]Set["Boolean", "TYPE_BOOLEAN"] //9
322 ]Set["Float32", "TYPE_FLOAT32"] //10
323 ]Set["Float64", "TYPE_FLOAT64"] //11
324 ]Set["Real Number", "TYPE_FLOAT64"]
325 ]Set["Blueprint", "TYPE_BLUEPRINT"] //12
326 ]Set["Array", "TYPE_ARRAY"] //13
327 ]Set["Boxed Array", "TYPE_BOXEDARRAY"]//14
328 ]Set["Worker", "TYPE_WORKER"] //15
329 ]Set["Method Missing Exception", "TYPE_METHODMISSINGEXCEPTION"] //16
330 ]Set["Field Missing Exception", "TYPE_FIELDMISSINGEXCEPTION"] //17
331 ]Set["Wrong Type Exception", "TYPE_WRONGTYPEEXCEPTION"]] //18
332 ]Definitions << [Dictionary[]]
333 ]Next ID <<[0]
334 ]Escape Pattern <<[p]
335 }
336
337 _Type Defs JS[text,def,p:out]
338 {
339 out <- [[text]Append[[def]Type Def[p]]]Append["\n\n"]
340 }
341
342 Type Defs@JS Type Registry[reg:out]
343 {
344 out <- Fold[_Type Defs JS[?,?,[reg]Escape Pattern >>], "", [reg]Definitions >>]
345 }
346
347 _Type Inits JS[reg,method reg,field reg,text,def,name:out]
348 {
349 out <- [[text]Append[ [def]Type Init[[reg]Type ID[name], method reg, field reg,[reg]Escape Pattern >>] ]]Append["\n\n"]
350 }
351
352 Type Inits@JS Type Registry[reg,method reg,field reg:out]
353 {
354 out <- Fold[_Type Inits JS[reg, method reg, field reg, ?], "", [reg]Definitions >>]
355 }
356
357 Register Type@JS Type Registry[reg,def:out]
358 {
359 name <- [def]Name >>
360 [[reg]Lookup >>]Index[name]
361 {
362 [[reg]Definitions >>]Index[name]
363 {
364 out <- reg
365 }{
366 out <- [reg]Definitions <<[[[reg]Definitions >>]Set[name, def]]
367 }
368 }{
369 out <- [[[reg]Lookup <<[ [[reg]Lookup >>]Set[name, ["TYPE_FIRST_USER+"]Append[String[[reg]Next ID >>]]] ]
370 ]Definitions <<[ [[reg]Definitions >>]Set[name, def] ]
371 ]Next ID <<[ [[reg]Next ID >>]+[1] ]
372 }
373 }
374
375 Type ID@JS Type Registry[reg,name:out,notfound]
376 {
377 out <- [[reg]Lookup >>]Index[name] {}
378 {
379 ,notfound <- If[[name]=["Any Type"]]
380 { out <- "0" }
381 }
382 }
383
384 Simple Type?@JS Type Registry[reg,name:yep,nope,notfound]
385 {
386 ,notfound <- [[reg]Definitions >>]Index[name]
387 {
388 yep,nope <- If[[[[~]Fields >>]Length] = [1]]
389 }
390 }
391
392 Defined?@JS Type Registry[reg,name:yep,nope]
393 {
394 yep,nope <- [[reg]Definitions >>]Index[name]
395 }
396
397 Blueprint JS Function
398 {
399 Name
400 Inputs
401 Outputs
402 Convention
403 Variables
404 Statements
405 Method Registry
406 Field Registry
407 Type Registry
408 Constants
409 Input Types
410 Output Types
411 Resume Index
412 Last NumParams
413 Escape Pattern
414 }
415
416 JS Function[name,inputs,outputs,convention,p:out]
417 {
418 out <- JS Function With Registry[name,inputs,outputs,convention, JS Method Registry[], JS Field Registry[], JS Type Registry[p],p]
419 }
420
421 JS Function With Registry[name,inputs,outputs,convention,registry,field reg,type reg,p:out]
422 {
423 out <- [[[[[[[[[[[[[[[Build[JS Function()]
424 ]Name <<[name]
425 ]Inputs <<[inputs]
426 ]Outputs <<[outputs]
427 ]Convention <<[convention]
428 ]Variables <<[Dictionary[]]
429 ]Statements <<[()]
430 ]Method Registry <<[registry]
431 ]Field Registry <<[field reg]
432 ]Type Registry <<[type reg]
433 ]Constants <<[Dictionary[]]
434 ]Input Types <<[ Fold[Append[?, "Any Type"], (), inputs] ]
435 ]Output Types <<[ Fold[Append[?, "Any Type"], (), outputs] ]
436 ]Resume Index <<[1]
437 ]Last NumParams <<[-1]
438 ]Escape Pattern <<[p]
439 }
440
441 Set Input Type@JS Function[func,type,input num:out]
442 {
443 out <- [func]Input Types <<[ [[func]Input Types >>]Set[input num, type] ]
444 }
445
446 Set Output Type@JS Function[func,type,output num:out]
447 {
448 out <- [func]Output Types <<[ [[func]Output Types >>]Set[output num, type] ]
449 }
450
451 Register Constant@JS Function[func,name,constant:out]
452 {
453 out <- [func]Constants <<[ [[func]Constants >>]Set[name, constant] ]
454 }
455
456 Allocate Var@JS Function[func,name,type:out]
457 {
458 out <- [func]Variables <<[ [[func]Variables >>]Set[name,type] ]
459 }
460
461 Add Statement@JS Function[func,statement:out]
462 {
463 out <- [func]Statements <<[ [[func]Statements >>]Append[["\t"]Append[[statement]Append[";\n"]]] ]
464 }
465
466 Add Raw Line@JS Function[func,line:out]
467 {
468 out <- [func]Statements <<[ [[func]Statements >>]Append[["\t"]Append[[line]Append["\n"]]] ]
469 }
470
471 Add Operator Statement@JS Function[func,psource1,psource2,pdest,op:out]
472 {
473 source1 <- [psource1]Make Op[func]
474 source2 <- [psource2]Make Op[func]
475 dest <- [pdest]Make Op[func]
476 out <- [func]Add Statement[[[[[dest]Append[" = "]]Append[source1]]Append[op]]Append[source2]]
477 }
478
479 Add@JS Function[func,source1,source2,dest:out]
480 {
481 out <- [func]Add Operator Statement[source1,source2,dest," + "]
482 }
483
484 Sub@JS Function[func,source1,source2,dest:out]
485 {
486 out <- [func]Add Operator Statement[source1,source2,dest," - "]
487 }
488
489 Multiply@JS Function[func,source1,source2,dest:out]
490 {
491 out <- [func]Add Operator Statement[source1,source2,dest," * "]
492 }
493
494 Divide@JS Function[func,source1,source2,dest:out]
495 {
496 out <- [func]Add Operator Statement[source1,source2,dest," / "]
497 }
498
499 DoLShift@JS Function[func,source1,source2,dest:out]
500 {
501 out <- [func]Add Operator Statement[source1,source2,dest," << "]
502 }
503
504 DoRShift@JS Function[func,source1,source2,dest:out]
505 {
506 out <- [func]Add Operator Statement[source1,source2,dest," >> "]
507 }
508
509 BitAnd@JS Function[func,source1,source2,dest:out]
510 {
511 out <- [func]Add Operator Statement[source1,source2,dest," & "]
512 }
513
514 BitOr@JS Function[func,source1,source2,dest:out]
515 {
516 out <- [func]Add Operator Statement[source1,source2,dest," | "]
517 }
518
519 CompLess@JS Function[func,source1,source2,dest:out]
520 {
521 out <- [func]Add Operator Statement[source1,source2,dest," < "]
522 }
523
524 CompGreater@JS Function[func,source1,source2,dest:out]
525 {
526 out <- [func]Add Operator Statement[source1,source2,dest," > "]
527 }
528
529 CompEqual@JS Function[func,source1,source2,dest:out]
530 {
531 out <- [func]Add Operator Statement[source1,source2,dest," == "]
532 }
533
534 CompLessEqual@JS Function[func,source1,source2,dest:out]
535 {
536 out <- [func]Add Operator Statement[source1,source2,dest," <= "]
537 }
538
539 CompGreaterEqual@JS Function[func,source1,source2,dest:out]
540 {
541 out <- [func]Add Operator Statement[source1,source2,dest," >= "]
542 }
543
544 CompNotEqual@JS Function[func,source1,source2,dest:out]
545 {
546 out <- [func]Add Operator Statement[source1,source2,dest," != "]
547 }
548
549 Move@JS Function[func,psource,pdest:out]
550 {
551 source <- [psource]Make Op[func]
552 dest <- [pdest]Make Op[func]
553 out <- [func]Add Statement[[[dest]Append[" = "]]Append[source]]
554 }
555
556 Do AddRef@JS Function[func,psource,pdest:out]
557 {
558 source <- [psource]Make Op[func]
559 dest <- [pdest]Make Op[func]
560 out <- [func]Add Statement[[[[dest]Append[" = add_ref((object *)"]]Append[source]]Append[")"]]
561 }
562
563 AddRef No Dest@JS Function[func,psource:out]
564 {
565 source <- [psource]Make Op[func]
566 out <- [func]Add Statement[[["add_ref((object *)"]Append[source]]Append[")"]]
567 }
568
569 Release@JS Function[func,psource:out]
570 {
571 source <- [psource]Make Op[func]
572 out <- [func]Add Statement[[["release_ref((object *)"]Append[source]]Append[")"]]
573 }
574
575 Set Null@JS Function[func,pdest:out]
576 {
577 dest <- [pdest]Make Op[func]
578 out <- [func]Add Statement[[dest]Append[" = NULL"]]
579 }
580
581 Lookup Constant@JS Function[func,const,doaddref:out]
582 {
583 var <- ["_const_"]Append[Escape Rhope Name[const,[func]Escape Pattern >>]]
584 If[doaddref]
585 {
586 out <- [["add_ref("]Append[var]]Append[")"]
587 }{
588 out <- Val[var]
589 }
590 }
591
592 Field Result@JS Function[func,var,field:out]
593 {
594 as op <- [var]Make Op[func]
595 [(String(),String Cat(),String Slice())]Find[=[Blueprint Of[var],?]]
596 {
597 [[func]Inputs >>]Find[=[var,?]]
598 {
599 type <- [[func]Input Types >>]Index[~]
600
601 }{
602 type <- [[func]Variables >>]Index[var] { Print["op refers to a var"] }
603 {
604 [[func]Outputs >>]Find[=[var,?]]
605 {
606 type <- [[func]Output Types >>]Index[~]
607 }{
608 //Does it make sense for us to do this?
609 type <- Type Instance["Any Type"]
610 }
611 }
612 }
613 }{
614 type <- Type Instance["Any Type"]
615 }
616 If[[[func]Convention >>] = ["rhope"]]
617 {
618 If[[type] = ["Any Type"]]
619 {
620 rvar <- Val[as op]
621 }{
622 rvar <- [[[["(("]Append[ Rhope Type to JS[type,[func]Escape Pattern >>] ]]Append[")("]]Append[as op]]Append["))"]
623 }
624 }{
625 rvar <- Val[as op]
626 }
627
628 [[func]Type Registry >>]Simple Type?[[type]Name >>]
629 { access <- "->" }
630 { access <- "->payload." }
631 {
632 //TODO: Generate some kind of error/exception in this case
633 access <- "->"
634 }
635 out <- [[rvar]Append[access]]Append[Escape Rhope Name[field,[func]Escape Pattern >>]]
636 }
637
638 Read Field@JS Function[func,var,field:out,result op]
639 {
640 out <- func
641 result op <- Field Ref[var,field]
642 }
643
644 Write Field@JS Function[func,var,field:out,result op]
645 {
646 out <- func
647 result op <- Field Ref[var,field]
648 }
649
650
651
652
653 Set Field Null@JS Function[func,var,field:out]
654 {
655 out <- [func]Add Statement[ [[func]Field Result[var,field]]Append[" = NULL"] ]
656 }
657
658 Copy@JS Function[func,pdest:out]
659 {
660 dest <- [pdest]Make Op[func]
661 out <- [func]Add Statement[ [dest]Append[[[" = copy_object("]Append[dest]]Append[")"]] ]
662 }
663
664 Box@JS Function[func,psource,pdest,type:out]
665 {
666 dest <- [pdest]Make Op[func]
667 source <- [psource]Make Op[func]
668 out <- [func]Add Statement[
669 [[[[[dest
670 ]Append[" = naked_to_boxed("]
671 ]Append[ [[func]Type Registry >>]Type ID[[type]Name >>] ]
672 ]Append[", &"]
673 ]Append[source]
674 ]Append[")"] ]
675 }
676
677 Unbox@JS Function[func,psource,pdest:out]
678 {
679 dest <- [pdest]Make Op[func]
680 source <- [psource]Make Op[func]
681 out <- [func]Add Statement[
682 [[[["boxed_to_naked("
683 ]Append[source]
684 ]Append[", &"]
685 ]Append[dest]
686 ]Append[")"] ]
687 }
688
689 Get Raw Pointer@JS Function[func,psource,pdest:out]
690 {
691 dest <- [pdest]Make Op[func]
692 source <- [psource]Make Op[func]
693 out <- [func]Add Statement[ [[[dest]Append[" = (void*)("]]Append[source]]Append[" + 1)"] ]
694 }
695
696 Array Raw Pointer@JS Function[func,psource,pdest:out]
697 {
698 dest <- [pdest]Make Op[func]
699 source <- [psource]Make Op[func]
700 out <- [func]Add Statement[ [[[dest]Append[" = ((char *)"]]Append[source]]Append[")+ sizeof(t_Array)"] ]
701 }
702
703 _Function Arg JS[func,val,inputnum:out]
704 {
705 out <- [func]Add Raw Line[
706 [[[["SetParam("
707 ]Append[String[inputnum]]
708 ]Append[", "]
709 ]Append[val]
710 ]Append[")"]
711 ]
712 }
713
714 _Val Function Arg JS[func,val,inputnum,worker:out]
715 {
716 out <- [func]Add Raw Line[
717 [[[[[["VCSetParam("
718 ]Append[worker]
719 ]Append[", "]
720 ]Append[String[inputnum]]
721 ]Append[", "]
722 ]Append[val]
723 ]Append[")"]
724 ]
725 }
726
727 Method Call@JS Function[func,method,args:out]
728 {
729 out <- [func]Call[method,args]
730 }
731
732 Val Call@JS Function[func,to call,args:out]
733 {
734 worker <- Make Op[Strip Addref[to call], func]
735 rargs <- Map[args, Make Op[?, func]]
736
737 If[[[func]Last NumParams >>] = [-1]]
738 {
739 prepped <- [[func]Add Raw Line[
740 [[[["VCPrepCall("
741 ]Append[worker]
742 ]Append[", "]
743 ]Append[String[[rargs]Length]]
744 ]Append[")"] ]
745 ]Last NumParams <<[[rargs]Length]
746 }{
747 prepped <- [[func]Add Raw Line[
748 [[[[[["VCRePrepCall("
749 ]Append[worker]
750 ]Append[", "]
751 ]Append[String[[rargs]Length]]
752 ]Append[", "]
753 ]Append[String[[func]Last NumParams >>]]
754 ]Append[")"] ]
755 ]Last NumParams <<[[rargs]Length]
756 }
757
758
759 out <- [[[[Fold[_Val Function Arg JS[?, ?, ?, worker], prepped, rargs]
760 ]Add Raw Line[
761 [[[[[[[["ValCall("
762 ]Append[worker]
763 ]Append[", "]
764 ]Append[String[[rargs]Length]]
765 ]Append[", "]
766 ]Append[String[[func]Resume Index >>]]
767 ]Append[", "]
768 ]Append[Escape Rhope Name[[func]Name >>,[func]Escape Pattern >>]]
769 ]Append[")"]]
770 ]Add Raw Line["DISPATCH"]
771 ]Add Raw Line[
772 [[[["ValCallPostlude("
773 ]Append[String[[func]Resume Index >>]]
774 ]Append[", "]
775 ]Append[Escape Rhope Name[[func]Name >>,[func]Escape Pattern >>]]
776 ]Append[")"]]
777 ]Resume Index <<[ [[func]Resume Index >>]+[1] ]
778 }
779
780 Call@JS Function[func,name,args:out]
781 {
782 If[[name]=["Call@Worker"]]
783 {
784 //TODO: Handle case when user explicitly calls the fully qualified version, but the type of the first arg isn't Worker
785 out <- [func]Val Call[[args]Index[0], Tail[args,1]]
786 }{
787 If[[name]=["Call"]]
788 {
789 to call <- [args]Index[0]
790 last numparams <- [func]Last NumParams >>
791 out <- [[[[[[func]Add Raw Line[[["if (get_blueprint("]Append[Make Op[Strip Addref[to call], func]]]Append[")->type_id == TYPE_WORKER) {"]]
792 ]Val Call[to call, Tail[args,1]]
793 ]Add Raw Line["} else {"]
794 ]Last NumParams <<[last numparams]
795 ]Func Base["Call",args, "Call"]
796 ]Add Raw Line["}"]
797 }{
798 out <- [func]Func Base[Escape Rhope Name[name,[func]Escape Pattern >>],args, "Call"]
799 }
800 }
801 }
802
803 Func Base@JS Function[func,tocall,args,type:out]
804 {
805 Print[ [[func]Name >>]Append[ [": Func Base("]Append[tocall] ] ]
806 rargs <- Map[args, Make Op[?, func]]
807
808 If[[[rargs]Length] > [[func]Last NumParams >>]]
809 {
810 If[[[func]Last NumParams >>] = [-1]]
811 {
812 freed <- Val[func]
813 }{
814 freed <- [func]Add Raw Line["FreeCall"]
815 }
816 prepped <- [[freed]Add Raw Line[ [["PrepCall("]Append[String[[rargs]Length]]]Append[")"] ]
817 ]Last NumParams <<[[rargs]Length]
818 }{
819 prepped <- Val[func]
820 }
821
822
823 out <- [[Fold[_Function Arg JS[?], prepped, rargs]
824 ]Add Raw Line[
825 [[[[[[[[[type]Append["("]
826 ]Append[tocall]
827 ]Append[", "]
828 ]Append[String[[rargs]Length]]
829 ]Append[", "]
830 ]Append[String[[func]Resume Index >>]]
831 ]Append[", "]
832 ]Append[Escape Rhope Name[[func]Name >>,[func]Escape Pattern >>]]
833 ]Append[")"]]
834 ]Resume Index <<[ [[func]Resume Index >>]+[1] ]
835 }
836
837 Call Foreign@JS Function[func,name,language,args,store result:out]
838 {
839 rargs <- Map[args, Make Op[?, func]]
840 //Assume language = "JS" for now
841 base <- [[[name]Append["("]]Append[ Join[rargs, ", "] ]]Append[")"]
842 ,do store <- [(String(), String Slice(), String Cat())]Find[=[Blueprint Of[store result], ?]]
843 {
844 ,do store <- If[[store result]=[""]]
845 { stmt <- Val[base] }
846 }
847
848 Val[do store]
849 { stmt <- [[Make Op[store result, func]]Append[" = "]]Append[base] }
850 out <- [func]Add Statement[stmt]
851 }
852
853 Get Field Call@JS Function[func,field,source:out]
854 {
855 out <- [func]Func Base[Escape Rhope Name[[field]Append[" >>"],[func]Escape Pattern >>], [()]Append[source], "Call"]
856 }
857
858 Set Field Call@JS Function[func,field,object,value:out]
859 {
860 out <- [func]Func Base[Escape Rhope Name[[field]Append[" <<"],[func]Escape Pattern >>], [[()]Append[object]]Append[value], "Call"]
861 }
862
863 Tail Method Call@JS Function[func,method,args:out]
864 {
865 out <- [func]Func Base[[[func]Method Registry >>]Method ID[method],args, "TMCall"]
866 }
867
868 Tail Call@JS Function[func,name,args:out]
869 {
870 out <- [func]Func Base[Escape Rhope Name[name,[func]Escape Pattern >>],args, "TCall"]
871 }
872
873 Resolve@JS Function[func,op:out]
874 {
875 If[[[func]Convention >>] = ["rhope"]]
876 {
877 [[func]Inputs >>]Find[=[op,?]]
878 {
879 out <- [["my_cdata->params["]Append[String[~]]]Append[" ]"]
880 }{
881 out <- [[["lv_"]Append[Escape Rhope Name[[func]Name >>,[func]Escape Pattern >>]]]Append["->"]]Append[Escape Rhope Name[op,[func]Escape Pattern >>]]
882 }
883 }{
884 out <- Escape Rhope Name[op,[func]Escape Pattern >>]
885 }
886 }
887
888 Resolve Output@JS Function[func,name:out]
889 {
890 If[[[func]Convention >>] = ["rhope"]]
891 {
892 out <- [[["lv_"]Append[Escape Rhope Name[[func]Name >>,[func]Escape Pattern >>]]]Append["->"]]Append[Escape Rhope Name[name,[func]Escape Pattern >>]]
893 }{
894 out <- Escape Rhope Name[name,[func]Escape Pattern >>]
895 }
896 }
897
898 Instruction Stream@JS Function[func:out]
899 {
900 out <- [func]Statements <<[()]
901 }
902
903 _If JS[func, statement:out]
904 {
905 out <- [func]Statements <<[ [[func]Statements >>]Append[ ["\t"]Append[statement] ] ]
906 }
907
908 Do If@JS Function[func,condition,stream:out]
909 {
910 cond <- [condition]Make Op[func]
911 out <- [[Fold[_If JS[?], [[func
912 ]Add Raw Line[ [["if("]Append[cond]]Append[")"] ]
913 ]Add Raw Line["{"], [stream]Statements >>]
914 ]Add Raw Line["}"]
915 ]Resume Index <<[[stream]Resume Index >>]
916
917 }
918
919 Discard Outputs@JS Function[func,first to discard:out]
920 {
921 out <- [[[[[func
922 ]Add Raw Line[[["for(idx = "]Append[String[first to discard]]]Append["; idx < cdata->num_params; ++idx)"]]
923 ]Add Raw Line["{"]
924 ]Add Raw Line[" if (cdata->params[idx])"]
925 ]Add Raw Line[" release_ref(cdata->params[idx]);"]
926 ]Add Raw Line["}"]
927 }
928
929 Result Reference@JS Function[func,output:out]
930 {
931 out <- [["cdata->params["]Append[String[output]]]Append["]"]
932 }
933
934 Checked Result Reference@JS Function[func,output:out]
935 {
936 out <- [[[["("]Append[String[output]]]Append[" < cdata->num_params ? cdata->params["]]Append[String[output]]]Append["] : NULL)"]
937 }
938
939
940 If Null Else@JS Function[func,left,right:out]
941 {
942 check <- [[Make Condition[left]]Strip Addref]Make Op[func]
943 l <- [left]Make Op[func]
944 r <- [right]Make Op[func]
945 out <- [[[[[["("
946 ]Append[check]
947 ]Append[" ? "]
948 ]Append[l]
949 ]Append[" : "]
950 ]Append[r]
951 ]Append[")"]
952 }
953
954 _Set Outputs JS[string,inputname,inputnum,func:out]
955 {
956 out <- [string]Append[[[ [ ["\tRet("]Append[String[inputnum]] ]Append[ [[", lv_"]Append[Escape Rhope Name[[func]Name >>,[func]Escape Pattern >>]]]Append["->"]]]Append[Escape Rhope Name[inputname,[func]Escape Pattern >>]]]Append[")\n"]]
957 }
958
959 Set Outputs@JS Function[func:out]
960 {
961 If[[[func]Convention >>] = ["rhope"]]
962 {
963 out <- [[[Fold[_Set Outputs JS[?, ?, ?, func], "", [func]Outputs >>]]Append["\tNumRet("]]Append[String[[[func]Outputs >>]Length]]]Append[")\n"]
964 }{
965 [[func]Outputs >>]Index[0]
966 {
967 out <- [["\treturn "]Append[Escape Rhope Name[~,[func]Escape Pattern >>]]]Append[";\n"]
968 }{
969 out <- ""
970 }
971 }
972 }
973 _Output Defs JS[string,varname,index,func:out]
974 {
975 out <- [[[string]Append[ ["\t"]Append[Rhope Type to JS[[[func]Output Types >>]Index[index],[func]Escape Pattern >>]] ]]Append[[" "]Append[Escape Rhope Name[varname,[func]Escape Pattern >>]]]]Append[";\n"]
976 }
977 _Var Defs JS[string,type,varname,p:out]
978 {
979 out <- [[[string]Append[ ["\t"]Append[Rhope Type to JS[type,p]] ]]Append[[" "]Append[Escape Rhope Name[varname,p]]]]Append[";\n"]
980 }
981
982
983 Definitions@JS Function[func:out]
984 {
985 Print[["Definitions@JS Function: "]Append[[func]Name >>]]
986 {
987 If[ [[[func]Convention >>] = ["rhope"]] And [[ [[[func]Variables >>]Length]+[[[func]Outputs >>]Length] ] > [0]] ]
988 {
989 localtype <- [[[Fold[_Output Defs JS[?, ?, ?, func], Fold[_Var Defs JS[?,?,?,[func]Escape Pattern >>],"typedef struct {\n", [func]Variables >>], [func]Outputs >>]]Append["} lt_"]]Append[Escape Rhope Name[[func]Name >>,[func]Escape Pattern >>]]]Append[";\n"]
990 }{
991 localtype <- ""
992 }
993
994 If[ [[func]Convention >>] = ["rhope"] ]
995 {
996 /* parts <- [[func]Name >>]Split["@"]
997 [parts]Index[1]
998 {
999 proto <- [[[["MethodDef("
1000 ]Append[Escape Rhope Name[[parts]Index[0],[func]Escape Pattern >>]]
1001 ]Append[", "]
1002 ]Append[Escape Rhope Name[~,[func]Escape Pattern >>]]
1003 ]Append[")\n"]
1004 }{
1005 proto <- [["FuncDef("]Append[Escape Rhope Name[[func]Name >>,[func]Escape Pattern >>]]]Append[")\n"]
1006 } */
1007 out <- Val[localtype]
1008 }{
1009 out <- [[func]Naked Proto]Append[";\n"]
1010 }
1011 }
1012 }
1013
1014 _Proto Input[list,input,index,types,p:out]
1015 {
1016 out <- [list]Append[ [[Rhope Type to JS[[types]Index[index],p]]Append[" "]]Append[Escape Rhope Name[input,p]] ]
1017 }
1018
1019 Naked Proto@JS Function[func:out]
1020 {
1021 [[func]Output Types >>]Index[0]
1022 {
1023 outtype <- [Rhope Type to JS[~,[func]Escape Pattern >>]]Append[" "]
1024 }{
1025 outtype <- "void "
1026 }
1027 out <- [[[[outtype
1028 ]Append[ Escape Rhope Name[[func]Name >>,[func]Escape Pattern >>]]
1029 ]Append["("]
1030 ]Append[ [Fold[_Proto Input[?, ?, ?, [func]Input Types >>,[func]Escape Pattern >>], (), [func]Inputs >>]]Join[", "] ]
1031 ]Append[")"]
1032 }
1033
1034 Type Check@JS Function[func,text,type,input num:out]
1035 {
1036 If[[type] = ["Any Type"]]
1037 {
1038 out <- text
1039 }{
1040 out <- [text]Append[ [["\tParam("]Append[input num]]Append[ [[", "]Append[ [[func]Type Registry >>]Type ID[type] ]]Append[")"] ] ]
1041 }
1042 }
1043
1044 Check Param Type JS[text,type,input num,func:out]
1045 {
1046 [(String(),String Cat(),String Slice())]Find[=[Blueprint Of[type],?]]
1047 {
1048 typename <- type
1049 }{
1050 typename <- [type]Name >>
1051 }
1052 If[[typename] = ["Any Type"]]
1053 {
1054 out <- text
1055 }{
1056 out <- [text]Append[[[["\tParam("]Append[String[input num]]]Append[ [","]Append[ [[func]Type Registry >>]Type ID[typename] ] ]]Append[")\n"]]
1057 }
1058 }
1059
1060 Text@JS Function[func:out]
1061 {
1062 Print[["Text@JS Function: "]Append[[func]Name >>]]
1063 If[ [[func]Convention >>] = ["rhope"] ]
1064 {
1065 before <- [[func]Name >>]Partition["@"] {} {}
1066 {
1067 type <- "MethodImpl"
1068 cname <- [[[[Escape Rhope Name[before,[func]Escape Pattern >>]
1069 ]Append[", "]
1070 ]Append[Escape Rhope Name[~,[func]Escape Pattern >>]]
1071 ]Append[", "]
1072 ]Append[ [[func]Type Registry >>]Type ID[~] ]
1073 }{
1074 type <- "Func"
1075 cname <- Val[fname]
1076 }
1077 fname <- Escape Rhope Name[[func]Name >>,[func]Escape Pattern >>]
1078 param check <- Fold[Check Param Type JS[?, ?, ?, func], "", [func]Input Types >>]
1079 If[ [ [[[func]Variables >>]Length]+[[[func]Outputs >>]Length] ] = [0] ]
1080 {
1081 out <- [[[[[[[[ [type]Append["NoLocals("]
1082 ]Append[cname]
1083 ]Append[",\n\tNumParams "]
1084 ]Append[ String[[[func]Inputs >>]Length] ]
1085 ]Append[")\n\n"]
1086 ]Append[param check]
1087 ]Append[ [[func]Statements >>]Join[""] ]
1088 ]Append["EndFuncNoLocals\n"]
1089 ]Append["DISPATCH"]
1090 }{
1091 If[[[func]Last NumParams >>] = [-1]]
1092 {
1093 freecall <- ""
1094 }{
1095 freecall <- "\n\tFreeCall\n"
1096 }
1097 out <- [[[[[[[[[[ [type]Append["("]
1098 ]Append[cname]
1099 ]Append[",\n\tNumParams "]
1100 ]Append[ String[[[func]Inputs >>]Length] ]
1101 ]Append[")\n\n"]
1102 ]Append[param check]
1103 ]Append[ [[func]Statements >>]Join[""] ]
1104 ]Append[freecall]
1105 ]Append[[func]Set Outputs]
1106 ]Append[[["EndFunc("]Append[fname]]Append[")\n"]]
1107 ]Append["DISPATCH"]
1108 }
1109 }{
1110
1111 out <- [[[
1112 Fold[_Output Defs JS[?, ?, ?, func],
1113 Fold[_Var Defs JS[?], [[func]Naked Proto]Append["\n{"], [func]Variables >>], [func]Outputs >>]
1114 ]Append[[[func]Statements >>]Join[""]]
1115 ]Append[[func]Set Outputs]
1116 ]Append["}"]
1117 }
1118 }
1119
1120 Blueprint JS Program
1121 {
1122 Functions
1123 Method Registry
1124 Field Registry
1125 Type Registry
1126 Libraries
1127 Escape Pattern
1128 }
1129
1130 JS Program[:out]
1131 {
1132 p <- Pattern[("_", "@", " ", ":", "?", "+", "-", "*", "/", "<", ">", "(", ")", "!", "=", "'",
1133 "\"", "\t", ",", ".", "\n", "{", "}", "[", "]", "#", "\\", "\r", ";", "&", "|", "%", "^", "`", "~")]
1134 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]
1135 }
1136
1137 Link@JS Program[program,language,library:out]
1138 {
1139 If[[library] = ["runtime"]]
1140 {
1141 out <- program
1142 }{
1143 langlibs <- [[program]Libraries >>]Index[language] {}
1144 { langlibs <- Dictionary[] }
1145 out <- [program]Libraries <<[ [[program]Libraries >>]Set[language, [langlibs]Set[library, Yes]] ]
1146 }
1147 }
1148
1149 Register Type@JS Program[program,def:out]
1150 {
1151 out <- [[[program]Type Registry <<[ [[program]Type Registry >>]Register Type[def] ]
1152 ]Method Registry <<[ [def]Register Methods[[program]Method Registry >>] ]
1153 ]Field Registry <<[ [def]Register Fields[[program]Field Registry >>] ]
1154 }
1155
1156 Create Type@JS Program[program,name:out]
1157 {
1158 out <- JS Type[name]
1159 }
1160
1161 Create Function@JS Program[program,name,inputs,outputs,convention:out]
1162 {
1163 out <- JS Function With Registry[name,inputs,outputs,convention, [program]Method Registry >>, [program]Field Registry >>, [program]Type Registry >>, [program]Escape Pattern >>]
1164 }
1165
1166 Store Function@JS Program[program,func:out]
1167 {
1168 out <- [program]Functions <<[ [[program]Functions >>]Set[ [func]Name >>, func] ]
1169 }
1170
1171 Method?@JS Program[program,funcname:is,isnot]
1172 {
1173 is,isnot <- [[program]Method Registry >>]Method ID[funcname]
1174 }
1175
1176 _Defs JS Program[text,func:out]
1177 {
1178 def <- [func]Definitions
1179 If[[def]=[""]]
1180 {
1181 out <- text
1182 }{
1183 out <- [text]Append[[def]Append["\n\n"]]
1184 }
1185 }
1186
1187 _Text JS Program[text,func,type reg:out]
1188 {
1189 out <- [text]Append[[[ [func]Type Registry <<[type reg] ]Text]Append["\n\n"]]
1190 }
1191
1192 Combine Consts[consts,func:out]
1193 {
1194 out <- Combine[[func]Constants >>, consts]
1195 }
1196
1197 _Consts JS Program[text,value,name,p:out]
1198 {
1199 out <- [text]Append[ [["object * _const_"]Append[Escape Rhope Name[name,p]]]Append[";\n"] ]
1200 }
1201
1202 _Consts JS Release[text,value,name,p:out]
1203 {
1204 out <- [text]Append[ [["\trelease_ref(_const_"]Append[Escape Rhope Name[name,p]]]Append[");\n"] ]
1205 }
1206
1207 _List Literal El[text,val,index,type reg:out]
1208 {
1209 out <- [[[[text
1210 ]Append[", "]
1211 ]Append[index]
1212 ]Append[", "]
1213 ]Append[Const Construct JS[val, type reg]]
1214 }
1215
1216 Const Construct JS[value,type reg:out]
1217 {
1218 valtype <- Blueprint Of[value]
1219 [(Int8(),UInt8(),Int16(),UInt16(),Int32(),UInt32(),Int64(),UInt64())]Find[=[valtype,?]]
1220 {
1221 size <- [("8","16","32","64")]Index[[~]/[2]]
1222 If[[~]Mod[2]]
1223 { s <- "UI" }
1224 { s <- "I" }
1225
1226 out <- [[[[[["make_"
1227 ]Append[s]
1228 ]Append["nt"]
1229 ]Append[size]
1230 ]Append["("]
1231 ]Append[String[value]]
1232 ]Append[")"]
1233 }{
1234 If[[valtype] = [Type Instance()]]
1235 {
1236 //TODO: Support parametric types
1237 typeid <- [type reg]Type ID[[value]Name >>]
1238
1239 out <- [["make_Blueprint("]Append[typeid]]Append[")"]
1240 }{
1241 If[[valtype] = [Boolean()]]
1242 {
1243 If[value]
1244 {
1245 out <- "make_Bool(1)"
1246 }{
1247 out <- "make_Bool(0)"
1248 }
1249 }{
1250
1251 [(String(),String Slice(),String Cat())]Find[=[valtype,?]]
1252 {
1253 out <- [["make_String(\""]Append[ [[[[value]Replace["\\", "\\\\"]]Replace["\n", "\\n"]]Replace["\"", "\\\""]]Replace["\r", "\\r"] ]]Append["\")"]
1254 }{
1255 If[[valtype]=[Worker Literal()]]
1256 {
1257 //TODO: Figure out how to fully support these in nested cases
1258 //or workaround the problem higher up in the food chain
1259 [[value]Args >>]Last
1260 { size <- String[[~]+[1]] }
1261 { size <- "0" }
1262 out <- [[[[[["make_Worker(FUNC_"
1263 ]Append[Escape Rhope Name[[value]Name >>,[type reg]Escape Pattern >>]]
1264 ]Append[", "]
1265 ]Append[size]
1266 ]Append[", "]
1267 ]Append[String[Fold[+[1,?], 0, [value]Args >>]]]
1268 ]Append[")"]
1269 }{
1270 [(List(), List Leaf())]Find[=[?,valtype]]
1271 {
1272 out <- [Fold[_List Literal El[?, ?, ?, type reg], ["make_List("]Append[String[[value]Length]], value]]Append[")"]
1273 }{
1274 out <- "UnhandledLiteralType"
1275 }
1276 }
1277 }
1278 }
1279 }
1280
1281 }
1282 }
1283
1284 _Set Worker Params JS[text,param,num,type reg,name:out]
1285 {
1286 out <- [text]Append[
1287 [[[[[["\t((object **)(((t_Worker *)_const_"
1288 ]Append[name]
1289 ]Append[")+1))["]
1290 ]Append[String[num]]
1291 ]Append["] = "]
1292 ]Append[Const Construct JS[param, type reg]]
1293 ]Append[";\n"] ]
1294 }
1295
1296 _Set Consts JS Program[text,value,name,type reg:out]
1297 {
1298 valtype <- Blueprint Of[value]
1299 [(String(),String Cat(),String Slice(),Worker Literal(),List(),List Leaf())]Find[=[valtype,?]]
1300 {
1301 Print[[name]Append[" is not of an early constant type"]]
1302 out <- text
1303 }{
1304 Const Construct JS[value,type reg]
1305 { out <- [text]Append[ [[[["\t_const_"]Append[Escape Rhope Name[name,[type reg]Escape Pattern >>]]]Append[" = "]]Append[~]]Append[";\n"] ] }
1306 }
1307 }
1308
1309 _Set List Els[text,el,index,type reg:out]
1310 {
1311 out <- [[text]Append[
1312 [["\tinout[1] = "
1313 ]Append[Const Construct JS[index,type reg]]
1314 ]Append[
1315 [[";\n\tinout[2] = "
1316 ]Append[Const Construct JS[el, type reg]]
1317 ]Append[";\n"]
1318 ]]]Append["\trhope(FUNC_Set, inout, 3, 3);\n"]
1319 }
1320
1321 _Set Late Consts JS[text,value,name,type reg:out]
1322 {
1323 valtype <- Blueprint Of[value]
1324 [(String(),String Cat(),String Slice(),Worker Literal(),List(),List Leaf())]Find[=[valtype,?]]
1325 {
1326 If[[~]>[3]]
1327 {
1328 out <- [Fold[_Set List Els[?, ?, ?, type reg], [text]Append["\trhope(FUNC_List, inout, 0, 1);\n"], value]
1329 ]Append[[["\t_const_"]Append[Escape Rhope Name[name,[type reg]Escape Pattern >>]]]Append[" = inout[0];\n"]]
1330 }{
1331 Const Construct JS[value,type reg]
1332 { init <- [text]Append[ [[[["\t_const_"]Append[Escape Rhope Name[name,[type reg]Escape Pattern >>]]]Append[" = "]]Append[~]]Append[";\n"] ] }
1333
1334 If[[valtype]=[Worker Literal()]]
1335 {
1336 out <- Fold[_Set Worker Params JS[?, ?, ?, type reg, Escape Rhope Name[name,[type reg]Escape Pattern >>]], init, [value]Args >>]
1337 }{
1338 out <- Val[init]
1339 }
1340 }
1341 }{
1342 out <- text
1343 }
1344 }
1345
1346 _Dispatch Switch Sub[text, num, name:out]
1347 {
1348 out <- [[[[[text
1349 ]Append["\tResumeEntry("]
1350 ]Append[String[num]]
1351 ]Append[","]
1352 ]Append[name]
1353 ]Append[")\\\n"]
1354 }
1355
1356 _Dispatch Switch[text,func,raw name:out]
1357 {
1358 If[[[func]Convention >>] = ["rhope"]]
1359 {
1360 name <- Escape Rhope Name[raw name,[func]Escape Pattern >>]
1361 out <- [[text]Append[ [["\tDispatchEntry("]Append[name]]Append[")\\\n"] ]
1362 ]Append[Fold[_Dispatch Switch Sub[?, ?, name], "", Range[1, [func]Resume Index >>]]]
1363 }{
1364 out <- text
1365 }
1366 }
1367
1368 _Dispatch Switch Methods[p,text,id,raw name:out]
1369 {
1370 name <- Escape Rhope Name[raw name,p]
1371 out <- [text]Append[ [["\tDispatchEntry("]Append[name]]Append[")\\\n"] ]
1372 }
1373
1374 _Dispatch Enum Sub[text, num, name:out]
1375 {
1376 out <- [[[[[text
1377 ]Append["\tRES_"]
1378 ]Append[String[num]]
1379 ]Append["_"]
1380 ]Append[name]
1381 ]Append[",\n"]
1382 }
1383
1384 _Dispatch Enum[text,func,raw name:out]
1385 {
1386 If[[[func]Convention >>] = ["rhope"]]
1387 {
1388 name <- Escape Rhope Name[raw name,[func]Escape Pattern >>]
1389 out <- [[text]Append[ [["\tFUNC_"]Append[name]]Append[",\n"] ]
1390 ]Append[Fold[_Dispatch Enum Sub[?, ?, name], "", Range[1, [func]Resume Index >>]]]
1391 }{
1392 out <- text
1393 }
1394 }
1395
1396 _Dispatch Enum Methods[p,text,types,name:out]
1397 {
1398 out <- [text]Append[ [["\tFUNC_"]Append[Escape Rhope Name[name,p]]]Append[",\n"] ]
1399 }
1400
1401 Dispatch@JS Program[program,all methods:out]
1402 {
1403 out <- [[[[["typedef enum {\n"
1404 ]Append[Fold[_Dispatch Enum[?],
1405 [Fold[_Dispatch Enum Methods[[program]Escape Pattern >>,?], "", all methods]]Append["\tFUNC_Build,\n\tFUNC_BlueprintSP_Of,\n\tFUNC_ID,\n\tFUNC_BlueprintSP_FromSP_ID,\n"],
1406 [program]Functions >>]]
1407 ]Append["\tEND\n} funcids;\n\n"]
1408 ]Append["#define DispatchEntries \\\n"]
1409 ]Append[Fold[_Dispatch Switch[?],
1410 [Fold[_Dispatch Switch Methods[[program]Escape Pattern >>,?], "", all methods]]Append["\tDispatchEntry(Build)\\\n\tDispatchEntry(BlueprintSP_Of)\\\n\tDispatchEntry(ID)\\\n\tDispatchEntry(BlueprintSP_FromSP_ID)\\\n"],
1411 [program]Functions >>]]
1412 ]Append["\tEndEntry\n\n"]
1413 }
1414
1415 Not Native[func:out]
1416 {
1417 If[[[func]Convention >>] = ["rhope"]]
1418 { out <- No }
1419 { out <- Yes }
1420 }
1421
1422 Native[func:out]
1423 {
1424 out <- [[func]Convention >>] = ["rhope"]
1425 }
1426
1427 Local Pointers[text,func:out]
1428 {
1429 If[ [ [[[func]Variables >>]Length]+[[[func]Outputs >>]Length] ] = [0] ]
1430 {
1431 out <- text
1432 }{
1433 out <- [text]Append[[["\tFuncDef("]Append[Escape Rhope Name[[func]Name >>,[func]Escape Pattern >>]]]Append[")\n"]]
1434 }
1435 }
1436
1437 _Method to Types[dict,name,type:out]
1438 {
1439 typelist <- [dict]Index[name] {}
1440 { typelist <- () }
1441
1442 out <- [dict]Set[name, [typelist]Append[[type]Name >>]]
1443
1444 }
1445
1446 _Field to Types[dict,field,type:out]
1447 {
1448 name <- [field]Index[0]
1449 out <- _Method to Types[_Method to Types[dict, [name]Append[" >>"], type], [name]Append[" <<"], type]
1450
1451 }
1452
1453 Method to Types[dict,type:out]
1454 {
1455 out <- Fold[_Method to Types[?, ?, type], dict, [type]Methods >>]
1456 }
1457
1458 Field to Types[dict,type:out]
1459 {
1460 out <- Fold[_Field to Types[?, ?, type], dict, [type]Fields >>]
1461 }
1462
1463 _Method Dispatch[text, type, method, reg: out]
1464 {
1465 out <- [[[[[[[text]Append["\tMethodDispatch("]]Append[ [reg]Type ID[type] ]]Append[","]]Append[Escape Rhope Name[method,[reg]Escape Pattern >>]]]Append[","]]Append[Escape Rhope Name[type,[reg]Escape Pattern >>]]]Append[")\n"]
1466 }
1467
1468 Method Dispatch[text, types, method, reg: out]
1469 {
1470 out <- [[[Fold[_Method Dispatch[?, ?, method, reg], [[[text]Append["Method("]]Append[ Escape Rhope Name[method,[reg]Escape Pattern >>] ]]Append[")\n"], types]
1471 ]Append["EndMethod("]
1472 ]Append[Escape Rhope Name[method,[reg]Escape Pattern >>]]
1473 ]Append[")\n\n"]
1474 }
1475
1476 Init Type Names[text,typeid,name,reg:out]
1477 {
1478 [reg]Defined?[name]
1479 { out <- [text]Append[ [[[["\tregistered_types["]Append[typeid]]Append["]->name = "]]Append[Const Construct JS[name, reg]]]Append[";\n"] ] }
1480 { out <- text }
1481 }
1482
1483 Text@JS Program[program:out]
1484 {
1485 p <- [program]Escape Pattern >>
1486 type defs <- [[program]Type Registry >>]Definitions >>
1487 constants <- Fold[Combine Consts[?], Dictionary[], [program]Functions >>]
1488 all methods <- Fold[Field to Types[?], Fold[Method to Types[?], Dictionary[], type defs], type defs]
1489 headers <- "#include <stdio.h>
1490 #include <stdlib.h>
1491 #include \"builtin.h\"
1492 #include \"object.h\"
1493 #include \"context.h\"
1494 #include \"func.h\"
1495 #include \"integer.h\"
1496 #include \"blueprint.h\"
1497 #include \"array.h\"
1498 #include \"worker.h\"
1499 #include \"bool.h\"
1500 #include <sys/time.h>\n\n"
1501 out <- [[[[[[[[[[[[[[[[[[headers
1502 ]Append[[program]Dispatch[all methods]]
1503 ]Append[[[program]Type Registry >>]Type Defs]
1504 ]Append[Fold[_Consts JS Program[?,?,?,p],
1505 Fold[_Defs JS Program[?], "", [program]Functions >>],
1506 constants]]
1507 ]Append[Fold[_Text JS Program[?, ?, [program]Type Registry >>], "", Filter[[program]Functions >>, Not Native[?]]]]
1508 ]Append["\n
1509 #ifdef ENABLE_PROFILING
1510 uint64_t profile_counts[END];
1511 uint64_t profile_nestedcounts[END];
1512 uint64_t profile_totals[END];
1513 uint64_t profile_selftotals[END];
1514 uint64_t profile_activationlevel[END];
1515 #endif
1516
1517 int32_t rhope(uint32_t func, object ** params, uint16_t numparams, uint16_t callspace)
1518 {
1519 #ifdef ENABLE_PROFILING
1520 struct timeval time;
1521 #endif
1522 uint16_t resume,idx, vcparam_offset, last_vcparam;
1523 context * ct;
1524 calldata * cdata, *temp_cdata, *my_cdata;
1525 DispatchVar
1526 FuncDef(Build)
1527 FuncDef(BlueprintSP_Of)
1528 FuncDef(ID)
1529 FuncDef(BlueprintSP_FromSP_ID)\n"]
1530 ]Append[Fold[Local Pointers[?], "", [program]Functions >>]]
1531 ]Append["
1532 ct = new_context();
1533 cdata = alloc_cdata(ct, NULL, callspace);
1534 cdata->num_params = numparams;
1535 for(idx = 0; idx < numparams; ++idx)
1536 cdata->params[idx] = params[idx];
1537 cdata->func = END;
1538 DISPATCH\n"]
1539 ]Append[Fold[Method Dispatch[?, ?, ?, [program]Type Registry >>], "", all methods]]
1540 ]Append["
1541 Func(Build,
1542 NumParams 1)
1543
1544 Param(0, TYPE_BLUEPRINT)
1545
1546 lv_Build->bp = ((t_Blueprint *)(cdata->params[0]))->bp;
1547 release_ref(cdata->params[0]);
1548
1549 Ret(0, new_object_bp(lv_Build->bp))
1550 EndFunc(Build)
1551 DISPATCH
1552
1553 Func(BlueprintSP_Of,
1554 NumParams 1)
1555
1556 lv_BlueprintSP_Of->bp = get_blueprint(cdata->params[0]);
1557 release_ref(cdata->params[0]);
1558
1559 Ret(0, new_object(TYPE_BLUEPRINT))
1560 ((t_Blueprint *)cdata->params[0])->bp = lv_BlueprintSP_Of->bp;
1561 EndFunc(BlueprintSP_Of)
1562 DISPATCH
1563
1564 Func(ID, NumParams 1)
1565
1566 Param(0, TYPE_BLUEPRINT)
1567
1568 lv_ID->id = new_object(TYPE_UINT32);
1569 ((t_UInt32 *)lv_ID->id)->Num = ((t_Blueprint *)cdata->params[0])->bp->type_id;
1570 release_ref(cdata->params[0]);
1571 Ret(0, lv_ID->id)
1572 EndFunc(ID)
1573 DISPATCH
1574
1575 Func(BlueprintSP_FromSP_ID, NumParams 1)
1576
1577 Param(0, TYPE_UINT32)
1578
1579 lv_BlueprintSP_FromSP_ID->type = ((t_UInt32 *)cdata->params[0])->Num;
1580 if (lv_BlueprintSP_FromSP_ID->type >= max_registered_type || !registered_types[lv_BlueprintSP_FromSP_ID->type]) {
1581 Ret(1, cdata->params[0])
1582 Ret(0, NULL)
1583 } else {
1584 release_ref(cdata->params[0]);
1585 Ret(0, new_object(TYPE_BLUEPRINT))
1586 ((t_Blueprint *)cdata->params[0])->bp = registered_types[lv_BlueprintSP_FromSP_ID->type];
1587 Ret(1, NULL)
1588 }
1589
1590 EndFunc(BlueprintSP_FromSP_ID)
1591 DISPATCH\n"]
1592 ]Append[Fold[_Text JS Program[?, ?, [program]Type Registry >>], "", Filter[[program]Functions >>, Native[?]]]]
1593 ]Append["
1594 DO_END:
1595 for(idx = 0; idx < cdata->num_params; ++idx)
1596 params[idx] = cdata->params[idx];
1597 free_context(ct);
1598 return cdata->num_params;
1599
1600 _exception:
1601 puts(\"Exception! Trace follows:\");
1602 while(cdata && cdata->func != END)
1603 {
1604 printf(\"%d\\n\", cdata->func);
1605 cdata = cdata->lastframe;
1606 }
1607 return -1;
1608 }
1609
1610 #include \"builtin.c\"
1611 #include \"array.c\"
1612 #include \"worker.c\"
1613
1614 int main(int argc, char **argv)
1615 {
1616 blueprint * bp;
1617 int numret;
1618 int idx;
1619 object * inout[3];
1620 register_builtin_types();\n\n"]
1621 ]Append[ [[program]Type Registry >>]Type Inits[[program]Method Registry >>, [program]Field Registry >>] ]
1622 ]Append[Fold[_Set Consts JS Program[?, ?, ?, [program]Type Registry >>], "", constants]]
1623 ]Append[Fold[_Set Late Consts JS[?, ?, ?, [program]Type Registry >>], "", constants]]
1624 ]Append[Fold[Init Type Names[?, ?, ?, [program]Type Registry >>], "", [[program]Type Registry >>]Lookup >>]]
1625 ]Append["
1626 rhope(FUNC_List, inout, 0, 1);
1627 for (idx = 0; idx < argc; ++idx)
1628 {
1629 inout[1] = make_String(argv[idx]);
1630 rhope(FUNC_Append, inout, 2, 2);
1631 }
1632 numret = rhope(FUNC_Main, inout, 1, 1);"]
1633 ]Append[Fold[_Consts JS Release[?, ?, ?, p], "", constants]]
1634 ]Append[
1635 "
1636 print_mem_info(manager);
1637 print_live_object_types(manager);
1638
1639 #ifdef ENABLE_PROFILING
1640 for (idx = 0; idx < END; ++idx)
1641 {
1642 if(profile_counts[idx])
1643 printf(\"Func: %d\tCount: %llu\tTime: %llu\tAvg: %f\tSelf: %llu\tAvg: %f\tNested Count: %llu\\n\", idx, profile_counts[idx], profile_totals[idx], ((double)profile_totals[idx])/((double)profile_counts[idx]), profile_selftotals[idx], ((double)profile_selftotals[idx])/((double)profile_counts[idx]), profile_nestedcounts[idx]);
1644 }
1645 #endif
1646 if (!numret)
1647 return 0;
1648 if (numret < 0)
1649 return numret;
1650 if (get_blueprint(inout[0])->type_id == TYPE_INT32)
1651 return ((t_Int32 *)inout[0])->Num;
1652
1653 rhope(FUNC_If, inout, 1, 2);
1654 if (inout[0])
1655 return 0;
1656 return 1;
1657 }\n\n"]
1658
1659 }
1660
1661