Add some comments, minor rearrangement.
This commit is contained in:
parent
ece12bac00
commit
12fadfb573
|
|
@ -44,26 +44,21 @@ compile_program(Program, Binary) :-
|
||||||
phrase(asm(EnumeratedASM), Binary).
|
phrase(asm(EnumeratedASM), Binary).
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
This first stage ⦾//2 converts the Joy description into a kind of intermediate
|
||||||
|
representation that models the Joy interpreter on top of the machine but doesn't
|
||||||
|
actually use assembly instructions. It also manages the named registers and
|
||||||
|
memory locations so thet don't appear in the program.
|
||||||
|
|
||||||
|
The idea here is to extract the low-level "primitives" needed to define the Joy
|
||||||
|
interpreter to make it easier to think about (and maybe eventually retarget other
|
||||||
|
CPUs.)
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
⦾([], []) --> [].
|
⦾([], []) --> [].
|
||||||
|
|
||||||
⦾([Body, ≡(NameAtom)|Terms], [defi(Name, B, Prev, I, SP, TOS)|Ts]) -->
|
|
||||||
get(dict, Prev), set(dict, Name), get(sp, SP), get(tos, TOS),
|
|
||||||
inscribe(NameAtom, Name), ⦾(Terms, Ts), lookup(i, I), lookup(Body, B).
|
|
||||||
|
|
||||||
⦾([Body, ヮ(NameAtom)|Terms], [definition(Name, DONE, B, Prev)|Ts]) -->
|
|
||||||
get(dict, Prev), set(dict, Name), inscribe(NameAtom, Name),
|
|
||||||
get(done, DONE), ⦾([Body, Terms], [B, Ts]).
|
|
||||||
|
|
||||||
⦾([Body, ワ(NameAtom)|Terms], [definition(Name, MAIN, B, Prev)|Ts]) -->
|
|
||||||
get(dict, Prev), set(dict, Name), inscribe(NameAtom, Name),
|
|
||||||
get(main, MAIN), ⦾([Body, Terms], [B, Ts]).
|
|
||||||
|
|
||||||
⦾([P, T, E, ヰ|Terms], [br(Predicate, Then, Else)|Ts]) -->
|
|
||||||
⦾([P, T, E, Terms], [Predicate, Then, Else, Ts]).
|
|
||||||
|
|
||||||
⦾([P, B, ヱ|Terms], [repeat_until(Predicate, Body)|Ts]) -->
|
|
||||||
⦾([P, B, Terms], [Predicate, Body, Ts]).
|
|
||||||
|
|
||||||
⦾([ヲ|Terms], Ts) --> % Preamble.
|
⦾([ヲ|Terms], Ts) --> % Preamble.
|
||||||
set(dict, 0), set(done, _DONE),
|
set(dict, 0), set(done, _DONE),
|
||||||
set(temp0, 6), set(temp1, 7),
|
set(temp0, 6), set(temp1, 7),
|
||||||
|
|
@ -106,6 +101,24 @@ compile_program(Program, Binary) :-
|
||||||
(sp, SP), (term, TERM), (tos, TOS)]),
|
(sp, SP), (term, TERM), (tos, TOS)]),
|
||||||
⦾(Terms, Ts).
|
⦾(Terms, Ts).
|
||||||
|
|
||||||
|
⦾([Body, ≡(NameAtom)|Terms], [defi(Name, B, Prev, I, SP, TOS)|Ts]) -->
|
||||||
|
get(dict, Prev), set(dict, Name), get(sp, SP), get(tos, TOS),
|
||||||
|
inscribe(NameAtom, Name), ⦾(Terms, Ts), lookup(i, I), lookup(Body, B).
|
||||||
|
|
||||||
|
⦾([Body, ヮ(NameAtom)|Terms], [definition(Name, DONE, B, Prev)|Ts]) -->
|
||||||
|
get(dict, Prev), set(dict, Name), inscribe(NameAtom, Name),
|
||||||
|
get(done, DONE), ⦾([Body, Terms], [B, Ts]).
|
||||||
|
|
||||||
|
⦾([Body, ワ(NameAtom)|Terms], [definition(Name, MAIN, B, Prev)|Ts]) -->
|
||||||
|
get(dict, Prev), set(dict, Name), inscribe(NameAtom, Name),
|
||||||
|
get(main, MAIN), ⦾([Body, Terms], [B, Ts]).
|
||||||
|
|
||||||
|
⦾([P, T, E, ヰ|Terms], [br(Predicate, Then, Else)|Ts]) -->
|
||||||
|
⦾([P, T, E, Terms], [Predicate, Then, Else, Ts]).
|
||||||
|
|
||||||
|
⦾([P, B, ヱ|Terms], [repeat_until(Predicate, Body)|Ts]) -->
|
||||||
|
⦾([P, B, Terms], [Predicate, Body, Ts]).
|
||||||
|
|
||||||
⦾([Term|Terms], [T|Ts]) --> ⦾(Term, T), ⦾(Terms, Ts).
|
⦾([Term|Terms], [T|Ts]) --> ⦾(Term, T), ⦾(Terms, Ts).
|
||||||
|
|
||||||
⦾(∅, dw(0)) --> [].
|
⦾(∅, dw(0)) --> [].
|
||||||
|
|
@ -145,7 +158,7 @@ Context (state) manipulation for the ⦾//2 relation.
|
||||||
Association lists are used to keep a kind of symbol table as well as a dictionary
|
Association lists are used to keep a kind of symbol table as well as a dictionary
|
||||||
of name atoms to address logic variables for defined Joy functions.
|
of name atoms to address logic variables for defined Joy functions.
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
init, [Context] -->
|
init, [Context] -->
|
||||||
{empty_assoc(C), empty_assoc(Dictionary),
|
{empty_assoc(C), empty_assoc(Dictionary),
|
||||||
|
|
@ -172,6 +185,13 @@ state(S), [S] --> [S].
|
||||||
state(S0, S), [S] --> [S0].
|
state(S0, S), [S] --> [S0].
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
This second stage ⟐//1 converts the intermediate representation to assembly
|
||||||
|
language.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
⟐([]) --> [].
|
⟐([]) --> [].
|
||||||
⟐([Term|Terms]) --> ⟐(Term), ⟐(Terms).
|
⟐([Term|Terms]) --> ⟐(Term), ⟐(Terms).
|
||||||
|
|
||||||
|
|
@ -283,21 +303,50 @@ state(S0, S), [S] --> [S0].
|
||||||
|
|
||||||
⟐(pop(Reg, TOS)) --> ⟐([split_word(Reg, TOS), deref(TOS)]).
|
⟐(pop(Reg, TOS)) --> ⟐([split_word(Reg, TOS), deref(TOS)]).
|
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Support for ⟐//1 second stage.
|
||||||
|
|
||||||
|
The dexpr//2 DCG establishes a sequence of labeled expr_cell/2 pseudo-assembly
|
||||||
|
memory locations as a linked list that encodes a Prolog list of Joy function
|
||||||
|
labels comprising e.g. the body of some Joy definition.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
dexpr([], 0) --> [].
|
dexpr([], 0) --> [].
|
||||||
dexpr([Func|Rest], ThisCell) -->
|
dexpr([Func|Rest], ThisCell) -->
|
||||||
[label(ThisCell), expr_cell(Func, NextCell)],
|
[label(ThisCell), expr_cell(Func, NextCell)],
|
||||||
dexpr(Rest, NextCell).
|
dexpr(Rest, NextCell).
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
The add_label/3 relation is a meta-logical construct that accepts a comparision
|
||||||
|
predicate (e.g. if_zero/2) and "patches" it by adding the Label logic variable
|
||||||
|
to the end.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
add_label(CmpIn, Label, CmpOut) :-
|
add_label(CmpIn, Label, CmpOut) :-
|
||||||
CmpIn =.. F,
|
CmpIn =.. F,
|
||||||
append(F, [Label], G),
|
append(F, [Label], G),
|
||||||
CmpOut =.. G.
|
CmpOut =.. G.
|
||||||
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Two simple masking predicates.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
high_half_word(I, HighHalf) :- HighHalf is I >> 16 /\ 0xFFFF.
|
high_half_word(I, HighHalf) :- HighHalf is I >> 16 /\ 0xFFFF.
|
||||||
low_half_word( I, LowHalf) :- LowHalf is I /\ 0xFFFF.
|
low_half_word( I, LowHalf) :- LowHalf is I /\ 0xFFFF.
|
||||||
|
|
||||||
|
|
||||||
% Linker
|
/*
|
||||||
|
|
||||||
|
Linker
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
linker(IntermediateRepresentation) --> enumerate_asm(IntermediateRepresentation, 0, _).
|
linker(IntermediateRepresentation) --> enumerate_asm(IntermediateRepresentation, 0, _).
|
||||||
|
|
||||||
|
|
@ -312,7 +361,12 @@ align(N, 1, M) :- !, M is N + 1.
|
||||||
align(N, Bytes, M) :- N mod 4 =:= 0, !, M is N + Bytes.
|
align(N, Bytes, M) :- N mod 4 =:= 0, !, M is N + Bytes.
|
||||||
align(N, Bytes, M) :- Padding is 4 - (N mod 4), M is N + Bytes + Padding.
|
align(N, Bytes, M) :- Padding is 4 - (N mod 4), M is N + Bytes + Padding.
|
||||||
|
|
||||||
% Assembler
|
|
||||||
|
/*
|
||||||
|
|
||||||
|
Assembler
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
asm([]) --> !, [].
|
asm([]) --> !, [].
|
||||||
asm([ skip(Bits)|Rest]) --> !, skip(Bits), asm(Rest).
|
asm([ skip(Bits)|Rest]) --> !, skip(Bits), asm(Rest).
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue