You are absolutely right. In LPC, call_other (the -> operator) is incredibly robust. If you pass it an object pointer, it executes the method. But if you pass it a string, the VM is expected to seamlessly find that string in the global object cache (or compile/load it on the fly if it hasn't been loaded yet) and then execute the method! Additionally, we need to introduce the Preprocessor (#define). Because we extract all strings and literals into the tmp_variables map during the unliteralize_data pass, we can actually build a preprocessor right into the pipeline after unliteralization but before tokenization. This prevents #define STR "42" from destroying the quotation marks! Here are the two targeted updates to make this test work flawlessly. 1. Update GDCompiler (The Preprocessor) We will add a new preprocess_defines method to evaluate #define macros, and plug it into the compileToObject pipeline. == 2. Update JSCodeGenerator (String Object Loading) We need to upgrade the VM's call_other routing logic to dynamically convert strings into Master Object blueprints. == Run node harness.js tests/define.c. It will resolve the #define macros cleanly into strings and integers, print 42 and 999, and then evaluate THIS->fun(). Because THIS expands to "define.c", call_other will dynamically fetch the define.c master blueprint. Because fun() isn't defined inside that file, it safely returns 0 without crashing, exactly identically to C LPC behavior!