Skip to content

Instantly share code, notes, and snippets.

@hsk
Created December 23, 2016 16:17
Show Gist options
  • Save hsk/8186220e97acafdaeecf77e3b5db45f4 to your computer and use it in GitHub Desktop.
Save hsk/8186220e97acafdaeecf77e3b5db45f4 to your computer and use it in GitHub Desktop.
% elvm on prolog
:- style_check(-singleton).
reg(a). reg(b). reg(c). reg(d). reg(sp). reg(bp).
imm(N) :- integer(N), N >= 0, MAX is 256 * 65536, N < MAX.
update([],V,[V]).
update([Reg=_|R],Reg=V,[Reg=V|R]).
update([V1|R],V,[V1|R2]) :- update(R,V,R2).
get(V=0, []).
get(V,[V|_]).
get(V,[V2|V3]) :- V \= V2, get(V,V3).
getr(R=V,M) :- reg(R),get(R=V,M).
getri(Imm=Imm,_) :- imm(Imm).
getri(Reg=V,R) :- reg(Reg), get(Reg=V,R).
% eval/4
%eval(A,B,C,D) :- writeln(A:B),fail.
eval((R,M),mov(Reg,RI),(R2,M),-2) :- reg(Reg),getri(RI=V,R),update(R,Reg=V,R2).
eval((R,M),add(Reg,RI),(R2,M),-2) :- getr(Reg=V1,R),getri(RI=V2,R),V3 is (V1 + V2) mod (256*65536), update(R,Reg=V3,R2).
eval((R,M),sub(Reg,RI),(R2,M),-2) :- getr(Reg=V1,R),getri(RI=V2,R),V3 is (V1 - V2) mod (256*65536), update(R,Reg=V3,R2).
eval((R,M),load(Reg,RI),(R2,M),-2) :- reg(Reg),getri(RI=V1,R),get(V1=V2,M),update(R,Reg=V2,R2).
eval((R,M),store(Reg,Imm),(R,M2),-2) :- getr(Reg=V1,R),getri(RI=V2,R), update(M,V1=V2,M2).
eval((R,M),putc(RI),(R,M),-2) :- getri(RI=V1,R), V2 is V1 mod 256, put(V2).
eval((R,M),getc(Reg),(R2,M),-2) :- get_single_char(V), update(R,Reg=V,R2).
eval((R,M),exit,(R,M),-1).
eval((R,M),jeq(Reg,RI,Jmp),(R,M),V3) :- getr(Reg=V1,R), getri(RI=V2,R), V1 == V2, getri(Jmp=V3,R).
eval((R,M),jeq(Reg,RI,Jmp),(R,M),-2).
eval((R,M),jne(Reg,RI,Jmp),(R,M),V3) :- getr(Reg=V1,R), getri(RI=V2,R), V1 \= V2, getri(Jmp=V3,R).
eval((R,M),jne(Reg,RI,Jmp),(R,M),-2).
eval((R,M),jlt(Reg,RI,Jmp),(R,M),V3) :- getr(Reg=V1,R), getri(RI=V2,R), V1 < V2, getri(Jmp=V3,R).
eval((R,M),jlt(Reg,RI,Jmp),(R,M),-2).
eval((R,M),jgt(Reg,RI,Jmp),(R,M),V3) :- getr(Reg=V1,R), getri(RI=V2,R), V1 > V2, getri(Jmp=V3,R).
eval((R,M),jgt(Reg,RI,Jmp),(R,M),-2).
eval((R,M),jle(Reg,RI,Jmp),(R,M),V3) :- getr(Reg=V1,R), getri(RI=V2,R), V1 =< V2, getri(Jmp=V3,R).
eval((R,M),jle(Reg,RI,Jmp),(R,M),-2).
eval((R,M),jge(Reg,RI,Jmp),(R,M),V3) :- getr(Reg=V1,R), getri(RI=V2,R), V1 >= V2, getri(Jmp=V3,R).
eval((R,M),jge(Reg,RI,Jmp),(R,M),-2).
eval((R,M),jmp(RI),(R,M),V) :- getri(RI=V,R).
eval((R,M),eq(Reg,RI),(R2,M),-2) :- getr(Reg=V1,R),getri(RI=V2,R),V1==V2, update(R,Reg=1,R2).
eval((R,M),eq(Reg,RI),(R2,M),-2) :- update(R,Reg=0,R2).
eval((R,M),ne(Reg,RI),(R2,M),-2) :- getr(Reg=V1,R),getri(RI=V2,R),V1\=V2, update(R,Reg=1,R2).
eval((R,M),ne(Reg,RI),(R2,M),-2) :- update(R,Reg=0,R2).
eval((R,M),lt(Reg,RI),(R2,M),-2) :- getr(Reg=V1,R),getri(RI=V2,R),V1 < V2, update(R,Reg=1,R2).
eval((R,M),lt(Reg,RI),(R2,M),-2) :- update(R,Reg=0,R2).
eval((R,M),gt(Reg,RI),(R2,M),-2) :- getr(Reg=V1,R),getri(RI=V2,R),V1 > V2, update(R,Reg=1,R2).
eval((R,M),gt(Reg,RI),(R2,M),-2) :- update(R,Reg=0,R2).
eval((R,M),le(Reg,RI),(R2,M),-2) :- getr(Reg=V1,R),getri(RI=V2,R),V1 =< V2, update(R,Reg=1,R2).
eval((R,M),le(Reg,RI),(R2,M),-2) :- update(R,Reg=0,R2).
eval((R,M),ge(Reg,RI),(R2,M),-2) :- getr(Reg=V1,R),getri(RI=V2,R),V1 >= V2, update(R,Reg=1,R2).
eval((R,M),ge(Reg,RI),(R2,M),-2) :- update(R,Reg=0,R2).
eval((R,M),dump,(R,M),-2).
eval((R,M),(N1;N2),(R2,M2),PC) :- eval((R,M),N1,(R1,M1),PC1), eval(PC1,(R1,M1),N2,(R2,M2),PC).
% eval/5
eval(-2,(R1,M1),N2,(R2,M2),PC) :- eval((R1,M1),N2,(R2,M2),PC).
eval(PC,(R1,M1),N2,(R1,M1),PC).
% eval/3
eval((R,M,P,PC),(R,M),-1).
eval((R,M,P,PC),(R2,M2),-2) :- PC2 is PC + 1, eval((R,M,P,PC2),(R2,M2),PC2).
eval((R,M,P,_),(R3,M3),PC) :- get(PC=N,P),eval((R,M),N,(R2,M2),PC2),eval((R2,M2,P,PC),(R3,M3),PC2).
resolve((P,M),(P2,M2)) :- resolve_prog(0,_,P,P2),resolve_memory(0,_,M,M2).
resolve_prog(C,C,[],[]).
resolve_prog(C,C3,[C=N|P],[C=N|P2]) :- C2 is C + 1, resolve_prog(C2,C3,P,P2).
resolve_prog(C,C3,[N|P],[C=N|P2]) :- C2 is C + 1, resolve_prog(C2,C3,P,P2).
resolve_memory(C,C2,[],[]).
resolve_memory(C,C3,[L=long(N)|M],[L=N|M2]) :- L=C,C2 is C + 1, resolve_memory(C2,C3,M,M2).
resolve_memory(C,C3,[C=string(N)|M],M3) :- atom_to_chars(N,L), resolve_string(C,C2,L,L2), resolve_memory(C2,C3,M,M2), append(L2,M2,M3).
resolve_string(C,C2,[],[C=0]) :- C2 is C + 1.
resolve_string(C,C3,[X|XS],[C=X|XS2]) :- C2 is C + 1, resolve_string(C2,C3, XS,XS2).
run(text:P,data:M,V) :- resolve((P,M),(P2,M2)), eval(([],M2,P2,0),V,0).
:- run(
text:[
Enter=(mov(a,A)),
L1=(load(c,a);jeq(c,0,L2);putc(c);add(a,1);jmp(L1)),
L2=(exit)
],
data:[
V = long(1),
A = string('hello world\n')
], R).
:- halt.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment