R0
,
R1
, etc...LDI Ri cte
LDR Ri etiq
,
où etiq
désigne une adresse en
mémoire, ici ce sera simplement un nomADD
Ri
Rj Rk
<==> Ri := Rj+Rk
ADD, MUL
,
SUB
, DIV
.
PSH Ri
&
POP
Rj
.?- try0(1-(b*b-4*(a*c))/2). |
?- try1(1-(b*b-4*(a*c))/2). |
?- try2(1-(b*b-4*(a*c))/2). |
mnem(+, 'ADD').
mnem(-, 'SUB').
mnem(*, 'MUL').
mnem(/, 'DIV').
registre(3,
R3
) - on rappelle
que 82 = ascii('R').registre(Num, Nom) :- name(Num, Chn), name(Nom, [82
|
Chn]).
Lcode
, clmu(Lcode, T-[Inst|Q], T-Q) :- Inst =.. Lcode.
?- clmu(['MUL', 'R0', 'R1', 'R0'], X-X, Y).
X = ['MUL'('R0', 'R1', 'R0')|_G322],
Y = ['MUL'('R0', 'R1', 'R0')|_G322]-_G322.
nonvar(X)
" dans la défnition du
prédicat plmu
vlmu(Linst-Q) :- maplist(plmu, Linst).
plmu(X) :- nonvar(X), tab(8), X =.. Lcode, slmu(Lcode).
slmu([]) :- nl.
slmu([T | Q]) :- write(T), tab(2), slmu(Q).
genexp0(Exp) --> {number(Exp), !},
clmu(['LDI',
'R0', Exp]).
genexp0(Exp) --> {atomic(Exp), !}, clmu(['LDR', 'R0', Exp]).
genexp0(Exp) --> {functor(Exp, Op, 2),
arg(1,
Exp, Ag), arg(2, Exp, Ad)},
genexp0(Ag), clmu(['PSH', 'R0']),
genexp0(Ad), clmu(['POP', 'R1']),
{mnem(Op,
Codop)},
clmu([Codop, 'R0', 'R1', 'R0']).
Appel par :try0(E) :- genexp0(E, X-X, Y), vlmu(Y).
genaux1
pour avoir une définition en deux clauses, maxreg(3).
% seule manière de déclarer une
constante en Prolog !
genexp1(Exp, PRL) --> {number(Exp), !, registre(PRL, RPRL)}, %
PRL = Premier Registre Libre
clmu(['LDI', RPRL, Exp]).
genexp1(Exp, PRL) --> {atomic(Exp), !, registre(PRL, RPRL)},
clmu(['LDR', RPRL, Exp]).
genexp1(Exp, PRL) --> {functor(Exp, Op, 2), arg(1, Exp, Ag),
arg(2, Exp, Ad),
mnem(Op, Codop),
registre(PRL, RPRL)},
genaux1(Codop, Ag,
Ad, PRL, RPRL).
genaux1(Codop, Ag, Ad, PRL, RPRL) --> {maxreg(MR), PRL
< MR, !, % on ne déborde pas
PRL1
is PRL+1, registre(PRL1, RPRL1)},
genexp1(Ag, PRL), genexp1(Ad, PRL1),
clmu([Codop, RPRL, RPRL, RPRL1]).
genaux1(Codop, Ag, Ad, PRL, RPRL) --> {PRL1 is PRL-1,
registre(PRL1, RPRL1)},
clmu(['PSH', RPRL1]), %
on déborde
genexp1(Ag, PRL1), genexp1(Ad, PRL),
clmu([Codop, RPRL, RPRL1, RPRL]),
clmu(['POP',
RPRL1]).
Appel par :try1(E) :- genexp1(E, 0, X-X, Y), vlmu(Y).
nmrn(Exp, Liste)
contrôlant cette
construction est défini ci-après. genopt(Exp, PRL) :- {nmrn(Exp, A)}, genexp2(Exp, A,
PRL).
nmrn(Exp, [1]) :- number(Exp), !.
nmrn(Exp, [1]) :- atomic(Exp), !.
nmrn(Exp, [R | [G | D]]) :- functor(Exp, Op, 2),
arg(1,
Exp, Ag), arg(2, Exp, Ad),
nmrn(Ag,
G), nmrn(Ad, D), resrn(G, D, R).
resrn([NG |_], [ND |_], R) :- NG=ND, !, R is NG+1.
resrn([NG |_], [ND |_], NG ) :- NG>ND, !.
resrn([NG |_], [ND |_], ND) .
?- nmrn(x*3-(y+3-(x*(y-1))), A).
A = [3, [2, [1], 1], 3, [2, [1], 1], 2, [1], 2, [1], 1].
genexp1.
Comme ci-devant, un auxiliaire genaux2
va gérer le débordement dans la pile.genexp2(Exp, ARN, PRL) --> {number(Exp), !,
registre(PRL, RPRL)},
clmu(['LDI', RPRL, Exp]).
genexp2(Exp, ARN, PRL) --> {atomic(Exp), !, registre(PRL,
RPRL)},
clmu(['LDR', RPRL, Exp]).
genexp2(Exp, [_ | [ARG | ARD]], PRL)
-->
{functor(Exp, Op, 2), arg(1, Exp, Ag), arg(2, Exp, Ad),
mnem(Op,
Codop), registre(PRL, RPRL)},
genaux2(Codop, Ag, Ad, ARG, ARD, PRL, RPRL).
genexp2
va demander un
intermédiaire de plus genaux21
,
genaux2(Codop, Ag, Ad, ARG, ARD, PRL, RPRL) -->
{maxreg(MR), PRL < MR, !,
%
on ne déborde pas
PRL1 is PRL+1, registre(PRL1, RPRL1),
ARG =
[NRG | _], ARD = [NRD | _]},
genaux21(Codop,
Ag, Ad, ARG, ARD, NRG, NRD,
PRL, RPRL, PRL1, RPRL1).
genaux2(Codop, Ag, Ad, ARG, ARD, PRL, RPRL) -->
{PRL1 is
PRL-1, registre(PRL1, RPRL1)},
clmu(['PSH',
RPRL1]),
% on déborde
genexp2(Ag, ARG, PRL1), genexp2(Ad, ARD,
PRL),
clmu([Codop, RPRL, RPRL1, RPRL]),
clmu(['POP',
RPRL1]).
genaux21(Codop, Ag, Ad, ARG, ARD, NRG, NRD,
PRL, RPRL, PRL1, RPRL1) -->
{NRG
> NRD, !}, % le sous-arbre gauche d'abord
genexp2(Ag, ARG, PRL), genexp2(Ad, ARD, PRL1),
clmu([Codop, RPRL, RPRL, RPRL1]).
genaux21(Codop, Ag, Ad, ARG, ARD, NRG, NRD,
PRL, RPRL, PRL1, RPRL1) -->
% le sous-arbre droit d'abord
genexp2(Ad, ARD, PRL), genexp2(Ag, ARG, PRL1),
clmu([Codop, RPRL, RPRL1, RPRL]).