Freeing registers before using them is simpler.
https://todo.sr.ht/~sforman/thun-der/3
This commit is contained in:
parent
400cc7dcde
commit
3d1c9bab95
56
thun/thun.pl
56
thun/thun.pl
|
|
@ -24,8 +24,22 @@
|
||||||
You should have received a copy of the GNU General Public License
|
You should have received a copy of the GNU General Public License
|
||||||
along with Thun. If not see <http://www.gnu.org/licenses/>.
|
along with Thun. If not see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
(Big fonts are from Figlet "ANSI Shadow" http://www.patorjk.com/software/taag/#p=display&f=ANSI%20Shadow&t=formatter
|
||||||
|
and "Small".)
|
||||||
|
|
||||||
(Big fonts are from Figlet ANSI Shadow http://www.patorjk.com/software/taag/#p=display&f=ANSI%20Shadow&t=formatter )
|
Table of Contents
|
||||||
|
Parser & Grammar
|
||||||
|
Semantics
|
||||||
|
Functions
|
||||||
|
Combinators
|
||||||
|
Definitions
|
||||||
|
Compiler
|
||||||
|
to Prolog
|
||||||
|
to Machine Code
|
||||||
|
Meta-Programming
|
||||||
|
Expand/Contract Definitions
|
||||||
|
Formatter
|
||||||
|
Partial Reducer
|
||||||
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
@ -171,7 +185,9 @@ thun(symbol(A), C, B, G) :- combo(A, B, F, C, [D|E]), thun(D, E, F, G).
|
||||||
% expression and we don't want to process combo/5 twice just to
|
% expression and we don't want to process combo/5 twice just to
|
||||||
% notice that, eh? Swap the rules and add green cuts after combo/5
|
% notice that, eh? Swap the rules and add green cuts after combo/5
|
||||||
% and that should make it more efficient.
|
% and that should make it more efficient.
|
||||||
%
|
|
||||||
|
% Ach! THe "green" cuts would mess up multi-rule combinators! D'oh!
|
||||||
|
|
||||||
% Neither functions nor definitions can affect the expression so we
|
% Neither functions nor definitions can affect the expression so we
|
||||||
% don't need to do similar gardening to those rules. The unification
|
% don't need to do similar gardening to those rules. The unification
|
||||||
% of the head clauses will distinguish the cases for them.
|
% of the head clauses will distinguish the cases for them.
|
||||||
|
|
@ -788,17 +804,13 @@ non_alloc(rolldown).
|
||||||
% Functions delegate to a per-function compilation relation.
|
% Functions delegate to a per-function compilation relation.
|
||||||
|
|
||||||
func_compile(+, E, [A, B|S], So, FP0, FP) --> !,
|
func_compile(+, E, [A, B|S], So, FP0, FP) --> !,
|
||||||
% If either register A or B is only used once we can reuse it.
|
free_reg(A, FP0, FP1),
|
||||||
( {reg_used_once(B, FP0)} -> [add(B, A, B)], free_reg(A, FP0, FP4), {Si=[B|S]}
|
free_reg(B, FP1, FP2),
|
||||||
; {reg_used_once(A, FP0)} -> [add(A, A, B)], free_reg(B, FP0, FP4), {Si=[A|S]}
|
get_reg(R, FP2, FP3),
|
||||||
; get_reg(R, FP0, FP1), [add(R, A, B)],
|
assoc_reg(R, int(_), FP3, FP4),
|
||||||
assoc_reg(R, int(_), FP1, FP2),
|
[add(R, A, B)],
|
||||||
free_reg(A, FP2, FP3),
|
|
||||||
free_reg(B, FP3, FP4),
|
|
||||||
{Si=[R|S]} % Can all this be simplified by freeing first?
|
|
||||||
),
|
|
||||||
% Update value in the context?
|
% Update value in the context?
|
||||||
thun_compile(E, Si, So, FP4, FP).
|
thun_compile(E, [R|S], So, FP4, FP).
|
||||||
|
|
||||||
func_compile(dup, E, [A|S], So, FP0, FP) --> !,
|
func_compile(dup, E, [A|S], So, FP0, FP) --> !,
|
||||||
add_ref(A, FP0, FP1),
|
add_ref(A, FP0, FP1),
|
||||||
|
|
@ -810,10 +822,11 @@ func_compile(pop, E, [A|S], So, FP0, FP) --> !,
|
||||||
|
|
||||||
func_compile(cons, E, [List, Item|S], So, FP0, FP) --> !,
|
func_compile(cons, E, [List, Item|S], So, FP0, FP) --> !,
|
||||||
% allocate a cons cell
|
% allocate a cons cell
|
||||||
|
% https://mitpress.mit.edu/sites/default/files/sicp/full-text/book/book-Z-H-33.html#%_sec_5.3
|
||||||
thun_compile(E, S, So, FP0, FP).
|
thun_compile(E, S, So, FP0, FP).
|
||||||
|
|
||||||
func_compile(Func, E, Si, So, FP0, FP) -->
|
func_compile(Func, E, Si, So, FP0, FP) --> { non_alloc(Func), !,
|
||||||
{ non_alloc(Func), !, func(Func, Si, S) },
|
func(Func, Si, S) },
|
||||||
thun_compile(E, S, So, FP0, FP).
|
thun_compile(E, S, So, FP0, FP).
|
||||||
|
|
||||||
func_compile(_Func, E, Si, So, FP0, FP) -->
|
func_compile(_Func, E, Si, So, FP0, FP) -->
|
||||||
|
|
@ -933,6 +946,21 @@ add(r1, r2, r1).
|
||||||
|
|
||||||
Fun!
|
Fun!
|
||||||
|
|
||||||
|
- - - -
|
||||||
|
|
||||||
|
Test that returning registers before asking for new ones
|
||||||
|
does reuse registers that are unused and preserve registers
|
||||||
|
that are still in use.
|
||||||
|
|
||||||
|
?- show_compiler(`1 dup 2 + swap 3 +`, StackIn, StackOut).
|
||||||
|
mov_imm(r0, int(1)).
|
||||||
|
mov_imm(r1, int(2)).
|
||||||
|
add(r1, r1, r0).
|
||||||
|
mov_imm(r2, int(3)).
|
||||||
|
add(r0, r2, r0).
|
||||||
|
[r0-int(_), r1-int(_)].
|
||||||
|
StackOut = [r0, r1|StackIn] .
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue