You literally need to have a strong background in maths and physics to make heads and tails of the system specs, whereas creating a VM that runs bytecode instructions is a much more self-contained job, that would get you tons of functionality without having to be/come a spaceflight expert, in a fraction of the time, requiring a fraction of the skills (a bytecode interpreter is commonly implemented by CS students in their 1st or 2nd year); leaving you with much more time to become an expert in the remaining areas for which the bytecode/VM approach does not suffice (think your example).
Anyway, it's kinda academical to discuss this for the time being, because as far as I know, the corresponding source code (or even just bytecode/firmware) is not readily available in any suitable form - so that what you are doing is the only feasible option, regardless of the barrier to entry and steep learning curve this involves.
Don't get me wrong, I absolutely admire your dedication - but the question posted above is valid, even though theoretical.
Even just coding "Pacman" from scratch is more work than coming up with an emulator to run the real thing (think ~20-30 essential CPU instructions), the other/added work (mapping I/O to/from the virtual screen/keyboard) should not distract from that fact.
My earlier comments/proposal to actually use a tokenizer and create a parse tree to process these command streams is unrelated to the VM/emulation discussion, and like I said, I never really looked at the code in question, the comment was merely in response to the challenges you mentioned, which are unlikely to remain challenges if a tokenizer and a parse tree are used - as a matter of fact, the whole many-to-one and one-to-many mapping is also a common issue for Nasal code, just imagine how many valid syntax trees there are to create a func expression:
- Code: Select all
var x = func() {};
var x = func() {}
var x = func {};
var x = func {nil};
var x = func {nil;};
var x = func {return nil};
var x = func {return;};
var x = func {return};
var x = func return;
Under the hood, the parser (and codegen( will internally patch up the abstract syntax tree (AST) to end up with the same syntax tree representation.
Depending on how you are currently parsing the grammar of the IDP (?), your approach would also work for this grammar (Nasal funcs) requiring very minor changes, or not work at all.
If the latter is true, it's likely that you are using tons of nested conditionals to implement state machine-like functionality.
Basically, the point of a EBNF grammar is to come up with recursively defined rules forming the grammar of your "language", and provide callbacks that check for these rules, and build a syntax tree, which is then either interpreted directly, or used by a code generator to create bytecode (which is how Java, JavaScript, but also Nasal works).