Skip to content

Commit

Permalink
problematic test case
Browse files Browse the repository at this point in the history
git-svn-id: https://slps.svn.sourceforge.net/svnroot/slps@699 ab42f6e0-554d-0410-b580-99e487e6eeb2
  • Loading branch information
grammarware committed Nov 6, 2009
1 parent eebd9a9 commit 3abaf04
Show file tree
Hide file tree
Showing 6 changed files with 192 additions and 12 deletions.
9 changes: 9 additions & 0 deletions topics/exercises/while3/Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
test:
swipl -f RunEvaluator.pro -t "main('input.txt')"

debug:
cat input.txt
swipl -s RunEvaluator.pro

clean:
rm -rf *~
98 changes: 98 additions & 0 deletions topics/exercises/while3/Parser.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
% Program is a list of statements
program(S) --> statements(S).

% Non-empty list
statements(slist(H,T)) -->
statement(H),
keyword(";"),
statements(T).

% Empty list
statements(S) --> statement(S).

% Statements
% Skip statement
statement(skip) -->
keyword("skip").

% Assign statement
statement(assign(identifier(V),E)) -->
identifier(V),
keyword(":="),
aexpression(E).

% Conditional statement
statement(ifthenelse(E,S1,S2)) -->
keyword("if"),
bexpression(E),
keyword("then"),
statement(S1),
keyword("else"),
statement(S2).

% Expressions
% Number is a an arithmetic expression
aexpression(number(N)) --> number(N).

% Variable reference is a an arithmetic expression
aexpression(identifier(V)) --> identifier(V).

% A sum of arithmetic expressions is also an arithmetic expression
aexpression(add(E1,E2)) -->
keyword("("),
aexpression(E1),
keyword("+"),
aexpression(E2),
keyword(")").

% Boolean primitives are boolean expressions
bexpression(true) --> keyword("true").
bexpression(false) --> keyword("false").

% Comparison is a boolean expression: equality
bexpression(equals(E1,E2)) -->
aexpression(E1),
keyword("="),
aexpression(E2).

% Comparison is a boolean expression: less than or equal to
bexpression(lte(E1,E2)) -->
aexpression(E1),
keyword("≤"),
aexpression(E2).

% Dealing with spaces
spaces --> [0' ], spaces. %'
spaces --> [].

% Keywords are space-consuming strings
keyword(X) -->
spaces,
string(X).

% Bare strings
string([],X,X).
string([H|T1],[H|T2],X) :- string(T1,T2,X).

% Numbers are space-consuming digits
number(N) -->
spaces,
digit(H), digits(T),
{ number_chars(N,[H|T]) }.

% Bare digits
digits([H|T]) --> digit(H), digits(T).
digits([]) --> [].
digit(H,[H|T],T) :- H >= 0'0, H =< 0'9.

% Identifiers are space-consuming letters
identifier(V) -->
spaces,
letter(H), letters(T),
{ atom_chars(V,[H|T]) }.

% Bare letters
letters([H|T]) --> letter(H), letters(T).
letters([]) --> [].
letter(H,[H|T],T) :- H >= 0'a, H =< 0'z.

19 changes: 19 additions & 0 deletions topics/exercises/while3/RunEvaluator.pro
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
:- ['Parser.pro','mappings.pro','compExpr.pro','bigStm.pro'].

main(File) :-
parseFile(File,program,S),
write(S),nl,nl,
execute(S,[],M),
write(M),nl.

parseFile(File,P,R) :-
open(File,read,Stream,[]),
read_stream_to_codes(Stream, Contents),
close(Stream),
apply(P,[R,Contents,Rest]),
eof(Rest,_).

eof([],[]).
eof([0' |T],R) :- eof(T,R). %'
eof([10|T],R) :- eof(T,R).

19 changes: 18 additions & 1 deletion topics/exercises/while3/bigStm.pro
Original file line number Diff line number Diff line change
Expand Up @@ -2,5 +2,22 @@

execute(skip,M,M).

execute(assign(X,A),M1,M2) :- evala(A,M1,Y), update(M1,X,Y,M2).
execute(slist(S1,S2),M1,M3) :-
execute(S1,M1,M2),
execute(S2,M2,M3).

execute(assign(identifier(X),A),M1,M2) :-
evala(A,M1,Y),
update(M1,X,Y,M2).

execute(ifthenelse(B,S1,S2),M1,M2) :-
evalb(B,M1,X),
(
X == tt,
execute(S1,M1,M2)
;
X == ff,
execute(S2,M1,M2)
).


58 changes: 47 additions & 11 deletions topics/exercises/while3/compExpr.pro
Original file line number Diff line number Diff line change
@@ -1,23 +1,59 @@
% Evaluate Boolean expressions
%% Evaluate arithmetic expressions

evalb(true,_,tt).
% Number is evaluated to its value
evala(number(V),_,V).

evalb(false,_,ff).
% Variable reference is evaluated to its current value
evala(identifier(X),M,Y) :- lookup(M,X,Y).

evalb(equal(A1,A2),M,V) :-
% Adddition
evala(add(A1,A2),M,V) :-
evala(A1,M,V1),
evala(A2,M,V2),
equal(V1,V2,V).
V is V1 + V2.

% Subtraction
evala(sub(A1,A2),M,V) :-
evala(A1,M,V1),
evala(A2,M,V2),
V is V1 - V2.

% Evaluate arithmetic expressions
% Multiplication
evala(mul(A1,A2),M,V) :-
evala(A1,M,V1),
evala(A2,M,V2),
V is V1 * V2.

evala(const(V),_,V).
%% Evaluate Boolean expressions

evala(var(X),M,Y) :- lookup(M,X,Y).
% True is tt
evalb(true,_,tt).

% False is ff
evalb(false,_,ff).

% Negation
evalb(not(B),M,V) :-
evalb(B,M,V1),
not(V1,V).

% Test for equality
evalb(equals(A1,A2),M,V) :-
evala(A1,M,V1),
evala(A2,M,V2),
equals(V1,V2,V).

% Test for equality
evalb(lte(A1,A2),M,V) :-
evala(A1,M,V1),
evala(A2,M,V2),
lte(V1,V2,V).

% Basic operations
%% Basic operations
equals(V1,V2,tt) :- V1 == V2.
equals(V1,V2,ff) :- \+ V1 == V2.
lte(V1,V2,tt) :- V1 =< V2.
lte(V1,V2,ff) :- \+ V1 =< V2.
not(tt,ff).
not(ff,tt).

equal(V1,V2,tt) :- V1 == V2.
equal(V1,V2,ff) :- \+ V1 == V2.
1 change: 1 addition & 0 deletions topics/exercises/while3/input.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
y:=2; if y = 3 then z := y else z := 1000

0 comments on commit 3abaf04

Please sign in to comment.