% Fortolkeren Mini-stak-og-variabel-maskine % beskrevet i ÈSprog og abstrakte maskinerÇ % % Skrevet af Henning Christiansen, februar 1999 (c) % Fortolkeren er beskrevet i Sprog og abstrakte maskiner, afs. 6.1 % NB: Fortolkeren er skrevet med henblik paa at vaere saa enkel % som mulig, og der er ikke lagt vaegt paa fejl-check! :- use_module(library(lists)). % prog(mini-program, slut-stak, slut-lager) prog(Prog, StakSlut, LagerSlut):- prog(Prog,Prog,[],[],StakSlut, LagerSlut). % For tracing, fjern %-tegnet i naeste linje: % prog([Inst|_],_,_,_,_,_):- write(Inst), write(' '), fail. % prog( RestProgram, HeleProgrammet, % StakStart, LagerStart, StakSlut, LagerSlut). prog([],_,S,L,S,L). prog([stak(N)|Rest], Prog, S0, L0, S1, L1):- prog(Rest, Prog, [N|S0], L0, S1, L1). prog([hent(Var)|Rest], Prog, S0, L0, S1, L1):- hent(Var,X,L0), prog(Rest, Prog, [X|S0], L0, S1, L1). prog([gem(Var)|Rest], Prog, [X|S0], L0, S1, L1):- erstat(Var,X,L0,Lx), % hjaelpepred. def. nedenfor prog(Rest, Prog, S0, Lx, S1, L1). prog([udregn(+)|Rest], Prog, [X,Y|S0], L0, S1, L1):- YplusX is Y + X, prog(Rest, Prog, [YplusX|S0], L0, S1, L1). prog([udregn(-)|Rest], Prog, [X,Y|S0], L0, S1, L1):- YminusX is Y - X, prog(Rest, Prog, [YminusX|S0], L0, S1, L1). prog([udregn(*)|Rest], Prog, [X,Y|S0], L0, S1, L1):- YgangeX is Y - X, prog(Rest, Prog, [YgangeX|S0], L0, S1, L1). prog([udregn(>)|Rest], Prog, [X,Y|S0], L0, S1, L1):- (Y > X -> YstX = ja ; YstX = nej), prog(Rest, Prog, [YstX|S0], L0, S1, L1). prog([udregn(>=)|Rest], Prog, [X,Y|S0], L0, S1, L1):- (Y >= X -> YstlX = ja ; YstlX = nej), prog(Rest, Prog, [YstlX|S0], L0, S1, L1). prog([udregn(<)|Rest], Prog, [X,Y|S0], L0, S1, L1):- (Y < X -> YmX = ja ; YmX = nej), prog(Rest, Prog, [YmX|S0], L0, S1, L1). prog([udregn(=<)|Rest], Prog, [X,Y|S0], L0, S1, L1):- (Y =< X -> YmlX = ja ; YmlX = nej), prog(Rest, Prog, [YmlX|S0], L0, S1, L1). prog([udregn(=)|Rest], Prog, [X,Y|S0], L0, S1, L1):- (Y = X -> YligX = ja ; YligX = nej), prog(Rest, Prog, [YligX|S0], L0, S1, L1). prog([udregn(=\=)|Rest], Prog, [X,Y|S0], L0, S1, L1):- (dif(X,Y) -> YdifX = ja ; YdifX = nej), prog(Rest, Prog, [YdifX|S0], L0, S1, L1). % NB: Prologs =\= duer kun for tal, derfor dif prog([udregn(/\)|Rest], Prog, [X,Y|S0], L0, S1, L1):- (Y = nej -> YogX = nej ; X = nej -> YogX = nej ; YogX = ja), prog(Rest, Prog, [YogX|S0], L0, S1, L1). prog([udregn(\/)|Rest], Prog, [X,Y|S0], L0, S1, L1):- (Y = ja -> YellerX = ja ; X = ja -> YellerX = ja ; YellerX = nej), prog(Rest, Prog, [YellerX|S0], L0, S1, L1). prog([hop(E)|_], P, S0, L0, S1 ,L1):- append(_, [E|Fortsaettelse], P), prog(Fortsaettelse, P, S0, L0, S1, L1). prog([n_hop(E)|_], P, [nej|S0], L0, S1 ,L1):- append(_, [E|Fortsaettelse], P), prog(Fortsaettelse, P, S0, L0, S1, L1). prog([n_hop(_)|Rest], P, [ja|S0], L0, S1 ,L1):- prog(Rest, P, S0, L0, S1 ,L1). prog([Etikette|Rest], P, S0, L0, S1 ,L1):- integer(Etikette), prog(Rest, P, S0, L0, S1 ,L1). %%%%%%%%%%%%%%%%%%%%%%%% % Hjaelpere % erstat(variabel,vaerdi,lager,nyt-lager) erstat(V,X,[],[(V=X)]). erstat(V,X,[(V=_)|L],[(V=X)|L]):- !. erstat(V,X,[Bind|L0],[Bind|L1]):- erstat(V,X,L0,L1). % hent(variabel, vaerdi,lager) hent(Var,X,L):- member((Var=X),L) -> true ; X = 0. %%%%%%%%%% Testforespoergsler /* prog([stak(3),stak(2),udregn(-)],S,L). prog([stak(23), gem(t), 7, hent(x), stak(7), udregn(+), gem(x), hent(t), stak(1), udregn(-), gem(t), hent(t), stak(0), udregn(=), n_hop(7)], S, L). */