Created
December 23, 2016 16:17
-
-
Save hsk/8186220e97acafdaeecf77e3b5db45f4 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| % 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