User@elli:~/Downloads/Remote/LPC/GEM$ node harness.js tests/call_out.c
[+] Compiling tests/call_out.c into VM
Memory... [+]
Launching Javascript V8 Native Environment...
--- BOOTING VM --- call_out (foo, 0)
find_call_out: 0
call_outs(): ({ ({ Object:call_out, foo, 0 }), ({ Object:call_out,
bar, 1 }) }) call_outs(this_object()): ({ ({
Object:call_out, foo, 0 }), ({ Object:call_out, bar, 0 }) })
call_outs(load_object("ob")): ({ ({ Object:call_out, foo, 0 }), ({
Object:call_out, bar, 0 }) })
[VM HALTED CLEANLY]
foo(42) find_call_out (foo): 4
bar
find_call_out (foo): 3 find_call_out
(foo): 2
find_call_out (foo): 1 foo(999)
find_call_out (foo): 4 removing call_out and
heart_beat user@elli:~/Downloads/Remote/LPC/GEM$
==
Awesome
Original gd:
==
call_outs(load_object("ob")): ({ })
find_call_out (foo): 0
foo(42)
bar
find_call_out (foo): 5
find_call_out (foo): 3
find_call_out (foo): 1
foo(999)
find_call_out (foo): 4
removing call_out and heart_beat
==
Only difference seems to be default HB interval, in GDLPC it was 2 sec
Good enough
==
That is incredibly cool to see in action. You just natively mapped LPC's
asynchronous time-delay mechanics directly onto Node.js's underlying libuv
event loop. Your Virtual Machine now stays alive dynamically, processing
background game ticks without needing a blocking C while(1) loop!
Good catch on the 2-second heartbeat! If you ever want to make it perfectly
1:1 with the original GDLPC engine, you can just change the 1000 to 2000
inside the setInterval of the set_heart_beat function in your efuns.js file.
(Side note: The reason call_outs(load_object("ob")) returned all the callouts
instead of an empty array is because load_object("ob") evaluated to null. Our
efuns.js was written to return the whole list if no object was passed, whereas
the strict C engine likely just bailed and returned an empty array!)
The Final Frontiers
We are rapidly running out of core language features! We've built an entire
dynamic, event-driven, file-reading, object-oriented transpiler and Virtual
Machine.
Looking at standard LPC architecture, there are really only a few major
compiler hurdles left. Do you have test files for any of the following?
* The Preprocessor: Macros like #define, #ifdef, #ifndef, and #include.
* Function Closures: LPC's function pointers, usually written as (: func :)
or evaluated via evaluate(fp).
* Destruction: Object lifecycle management (e.g., destruct(this_object()) and
ensuring the VM cleans up its memory/timers).
* Catch / Throw: Error handling and exception catching.
Throw the next tests/ file onto the workbench!