3 ms·
The thing that is fascinating——and only possible in Lisp——is that by extending the DSL that he started as the assembly language he could, eventually, actually p
by yason 12y ago
The thing that is fascinating——and only possible in Lisp——is that by extending the DSL that he started as the assembly language he could, eventually, actually program his 6502 in... Lisp.
A typical assembler reads the program in assembly language syntax and translates the lines into binary instructions. And you could write a Lisp compiler that reads in Lisp and produces maybe C which is then compiled into assembly language which is finally fed to the assembler. But he started by writing the assembler in Lisp and instead of parsing and translating assembly language he wrote his assembly program by calling Lisp functions such as (inc) (txa) (lsr) which just emitted the appropriate instruction codes.
However, at this point there was no barrier left between his host-side Lisp and target-side machine code. He could write constructs in Lisp that, by running the Lisp program, expand to the corresponding machine code. And given some well-chosen Lisp constructs he could elevate the code into a much higher level but still output 6502 machine code. He could write Lisp macros to produce Lisp code that produces 6502 code.
And because everything was still tightly integrated in a single running Lisp program, he could keep doing the low-level stuff as well because he was still in control of what machine code instructions would be written out.
This IMHO is a much better way to write assembly language than the usual syntax that assemblers parse. But it's not possible unless code is data is code.
- segmondy 12y agoThis is not only possible in Lisp, this is also possible in Prolog. In Prolog, Data is code. LISP can be viewed as a specialization of Prolog, where the data structure just lists. Prolog has more complex data structure compounds, where a list is nothing more but one type of said compound structure. One can write Prolog code to emit 6502 code or any code as well, and I suspect with as much ease as he did. Here is a sample of code generation in Prolog for register machines, https://github.com/segmond/PrologThingz/blob/master/clause_and_effect/compilation/cg_flatten.pl https://github.com/segmond/PrologThingz/blob/master/clause_a... An example for accumulator based machines which the 6502 https://github.com/segmond/PrologThingz/blob/master/clause_and_effect/compilation/cg_single_accumulator.pl https://github.com/segmond/PrologThingz/blob/master/clause_a... The examples I posted is from an awesome Prolog book I read called "Clause and Effect"
- agentultra 12y agoI came to the same revelations when writing my own 6502 assembler in CL. You even get access to the reader in CL which allowed me to write a parser that could read 6502 assembler source files and compile them. You can start writing a debugger on top, disassembler, and an emulator. You're not restricted in Lisp from doing low-level bit-twiddling of this sort.