Spaces:
Runtime error
Runtime error
karthik1019
commited on
Commit
•
16f1442
1
Parent(s):
86ce59b
Upload 25 files
Browse files- Digit_Fifth_Power.txt +30 -0
- IncrementDecrement_testcases.txt +16 -0
- Parser.py +677 -0
- String_op_testcases.txt +16 -0
- app.py +53 -0
- automat.py +174 -0
- dataclasses_sim.py +273 -0
- error_in_sim +4 -0
- eval.txt +1 -0
- fizz_buzz.txt +46 -0
- for_loop_testing_cases.txt +55 -0
- input.txt +779 -0
- int_array_test.txt +28 -0
- lexer.py +427 -0
- lexer_input.txt +25 -0
- lexer_test.py +16 -0
- requirements.txt +2 -0
- resolved_tree +5 -0
- resolver.py +243 -0
- sim.py +893 -0
- solution.txt +35 -0
- sum_of_two_million_primes.txt +32 -0
- testing.py +90 -0
- type_checking.py +97 -0
- unresolved_tree +5 -0
Digit_Fifth_Power.txt
ADDED
@@ -0,0 +1,30 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
BEGIN
|
2 |
+
sum := 0;
|
3 |
+
FOR i := 2; i <= 3720087; i := i + 1
|
4 |
+
DO
|
5 |
+
BEGIN
|
6 |
+
newsum := 0;
|
7 |
+
reduce := i;
|
8 |
+
WHILE reduce > 0
|
9 |
+
DO
|
10 |
+
BEGIN
|
11 |
+
digit := reduce%10;
|
12 |
+
reduce := reduce/10;
|
13 |
+
PRINT reduce END;
|
14 |
+
power := 1;
|
15 |
+
FOR j := 1; j <= 5; j := j + 1
|
16 |
+
DO
|
17 |
+
BEGIN
|
18 |
+
power := power * digit;
|
19 |
+
END
|
20 |
+
END;
|
21 |
+
newsum := newsum + power;
|
22 |
+
END
|
23 |
+
END;
|
24 |
+
IF newsum = i
|
25 |
+
THEN sum := sum + i
|
26 |
+
ELSE END;
|
27 |
+
END
|
28 |
+
END;
|
29 |
+
PRINT sum END;
|
30 |
+
END
|
IncrementDecrement_testcases.txt
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
{1. Increment and Decrement}
|
3 |
+
BEGIN
|
4 |
+
i := 10;
|
5 |
+
PRINT i END;
|
6 |
+
INC(i);
|
7 |
+
PRINT i END;
|
8 |
+
DEC(i);
|
9 |
+
PRINT i END;
|
10 |
+
DEC(i);
|
11 |
+
PRINT i END;
|
12 |
+
PRINT "...." END;
|
13 |
+
PRINT END;
|
14 |
+
PRINT "...." END;
|
15 |
+
END
|
16 |
+
|
Parser.py
ADDED
@@ -0,0 +1,677 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from dataclasses import dataclass
|
2 |
+
import sys
|
3 |
+
|
4 |
+
from lexer import *
|
5 |
+
# import sim
|
6 |
+
from dataclasses_sim import *
|
7 |
+
|
8 |
+
@dataclass
|
9 |
+
class Parser(object):
|
10 |
+
def __init__(self, lexer):
|
11 |
+
self.lexer = lexer
|
12 |
+
self.curr_token = self.lexer.get_token()
|
13 |
+
self.lexer.lineNum = 0
|
14 |
+
|
15 |
+
def check_type(self, Type):
|
16 |
+
if self.curr_token.type == Type:
|
17 |
+
self.curr_token = self.lexer.get_token()
|
18 |
+
else:
|
19 |
+
print("Expected Token Type: ", Type)
|
20 |
+
print("Got Token: ", self.curr_token)
|
21 |
+
print("At line number:", self.lexer.lineNum)
|
22 |
+
print(self.lexer.curLine)
|
23 |
+
print(" "*(self.lexer.curLinePos-1),"^")
|
24 |
+
sys.exit('Invalid character')
|
25 |
+
|
26 |
+
|
27 |
+
|
28 |
+
def parse_if(self):
|
29 |
+
|
30 |
+
self.check_type(IF)
|
31 |
+
condition = self.logical()
|
32 |
+
self.check_type(THEN)
|
33 |
+
if self.curr_token.type != BEGIN and self.curr_token.type != IF and self.curr_token.type != WHILE and self.curr_token.type != FOR and self.curr_token.type != FUNCTION:
|
34 |
+
true = self.parse()
|
35 |
+
self.check_type(SEMI)
|
36 |
+
else:
|
37 |
+
true = self.parse()
|
38 |
+
self.check_type(ELSE)
|
39 |
+
while self.curr_token.type == IF:
|
40 |
+
self.check_type(IF)
|
41 |
+
condition = self.logical()
|
42 |
+
self.check_type(THEN)
|
43 |
+
if self.curr_token.type != BEGIN and self.curr_token.type != IF and self.curr_token.type != WHILE and self.curr_token.type != FOR and self.curr_token.type != FUNCTION:
|
44 |
+
true = self.parse()
|
45 |
+
self.check_type(SEMI)
|
46 |
+
else:
|
47 |
+
true = self.parse()
|
48 |
+
self.check_type(ELSE)
|
49 |
+
if self.curr_token.type != END:
|
50 |
+
if self.curr_token.type != BEGIN and self.curr_token.type != IF and self.curr_token.type != WHILE and self.curr_token.type != FOR and self.curr_token.type != FUNCTION:
|
51 |
+
false = self.parse()
|
52 |
+
self.check_type(SEMI)
|
53 |
+
else:
|
54 |
+
false = self.parse()
|
55 |
+
else:
|
56 |
+
false = None
|
57 |
+
self.check_type(END)
|
58 |
+
node = IfElse(condition, true, false)
|
59 |
+
return node
|
60 |
+
|
61 |
+
|
62 |
+
def parse_begin(self):
|
63 |
+
"""parse_begin : """
|
64 |
+
self.check_type(BEGIN)
|
65 |
+
if self.curr_token.type == END:
|
66 |
+
self.check_type(END)
|
67 |
+
return Seq([])
|
68 |
+
# s = self.parse_list()
|
69 |
+
ignoreSEMI = False
|
70 |
+
if self.curr_token.type == IF or self.curr_token.type == WHILE or self.curr_token.type == FOR or self.curr_token.type == FUNCTION or self.curr_token.type == BEGIN:
|
71 |
+
ignoreSEMI = True
|
72 |
+
e = self.parse()
|
73 |
+
token = self.curr_token
|
74 |
+
Type = token.type
|
75 |
+
seq = [e]
|
76 |
+
|
77 |
+
while Type != END:
|
78 |
+
if not ignoreSEMI:
|
79 |
+
self.check_type(SEMI)
|
80 |
+
ignoreSEMI = False
|
81 |
+
if self.curr_token.type == END:
|
82 |
+
break
|
83 |
+
if self.curr_token.type == IF or self.curr_token.type == WHILE or self.curr_token.type == FOR or self.curr_token.type == FUNCTION or self.curr_token.type == BEGIN:
|
84 |
+
ignoreSEMI = True
|
85 |
+
e = self.parse()
|
86 |
+
|
87 |
+
seq.append(e)
|
88 |
+
token = self.curr_token
|
89 |
+
Type = token.type
|
90 |
+
|
91 |
+
# if Type == SEMI:
|
92 |
+
# self.check_type(SEMI)
|
93 |
+
self.check_type(END)
|
94 |
+
return Seq(seq)
|
95 |
+
# return s
|
96 |
+
|
97 |
+
def parse_for(self):
|
98 |
+
self.check_type(FOR)
|
99 |
+
start = self.parse()
|
100 |
+
# print("Hi", start)
|
101 |
+
self.check_type(SEMI)
|
102 |
+
condition = self.logical()
|
103 |
+
# print("Hi2", end)
|
104 |
+
self.check_type(SEMI)
|
105 |
+
increment = self.parse()
|
106 |
+
# print("Hi3",jump)
|
107 |
+
self.check_type(DO)
|
108 |
+
if self.curr_token.type != BEGIN and self.curr_token.type != IF and self.curr_token.type != WHILE and self.curr_token.type != FOR and self.curr_token.type != FUNCTION:
|
109 |
+
body = self.parse()
|
110 |
+
self.check_type(SEMI)
|
111 |
+
self.check_type(END)
|
112 |
+
return ForLoop(start, condition, increment, body)
|
113 |
+
body = self.parse()
|
114 |
+
self.check_type(END)
|
115 |
+
return ForLoop(start, condition, increment, body)
|
116 |
+
|
117 |
+
def parse_while(self):
|
118 |
+
self.check_type(WHILE)
|
119 |
+
c = self.logical()
|
120 |
+
self.check_type(DO)
|
121 |
+
if self.curr_token.type != BEGIN and self.curr_token.type != IF and self.curr_token.type != WHILE and self.curr_token.type != FOR and self.curr_token.type != FUNCTION:
|
122 |
+
b = self.parse()
|
123 |
+
self.check_type(SEMI)
|
124 |
+
self.check_type(END)
|
125 |
+
return While(c, b)
|
126 |
+
b = self.parse()
|
127 |
+
self.check_type(END)
|
128 |
+
return While(c, b)
|
129 |
+
|
130 |
+
def parse_list_append(self):
|
131 |
+
self.check_type(APPEND)
|
132 |
+
self.check_type(LPAREN)
|
133 |
+
var = self.variable()
|
134 |
+
self.check_type(COMMA)
|
135 |
+
item = self.parse()
|
136 |
+
self.check_type(RPAREN)
|
137 |
+
return list_append(var, item)
|
138 |
+
|
139 |
+
|
140 |
+
|
141 |
+
def parse_list_slice(self, c):
|
142 |
+
|
143 |
+
self.check_type(LSPAREN)
|
144 |
+
if self.curr_token.type==COMMA:
|
145 |
+
start = NumLiteral(0)
|
146 |
+
else:
|
147 |
+
start = self.parse()
|
148 |
+
|
149 |
+
if self.curr_token.type==RSPAREN:
|
150 |
+
index_type = True
|
151 |
+
self.check_type(RSPAREN)
|
152 |
+
|
153 |
+
elif self.curr_token.type==COMMA:
|
154 |
+
index_type = False
|
155 |
+
self.check_type(COMMA)
|
156 |
+
end = self.parse()
|
157 |
+
else:
|
158 |
+
index_type = False
|
159 |
+
end = self.parse()
|
160 |
+
|
161 |
+
|
162 |
+
if index_type==False:
|
163 |
+
if self.curr_token.type==COMMA:
|
164 |
+
self.check_type(COMMA)
|
165 |
+
if self.curr_token.type!=RSPAREN:
|
166 |
+
jump = self.parse()
|
167 |
+
else:
|
168 |
+
jump = NumLiteral(1)
|
169 |
+
|
170 |
+
else:
|
171 |
+
jump = NumLiteral(1)
|
172 |
+
self.check_type(RSPAREN)
|
173 |
+
else:
|
174 |
+
end = None
|
175 |
+
jump = None
|
176 |
+
return list_Slicing(c, start, end, jump)
|
177 |
+
|
178 |
+
|
179 |
+
|
180 |
+
def parse_inc(self):
|
181 |
+
self.check_type(INC)
|
182 |
+
self.check_type(LPAREN)
|
183 |
+
c = self.parse()
|
184 |
+
self.check_type(RPAREN)
|
185 |
+
return Increment(c)
|
186 |
+
|
187 |
+
def parse_dec(self):
|
188 |
+
self.check_type(DEC)
|
189 |
+
self.check_type(LPAREN)
|
190 |
+
c = self.parse()
|
191 |
+
|
192 |
+
self.check_type(RPAREN)
|
193 |
+
return Decrement(c)
|
194 |
+
|
195 |
+
def parse_len(self):
|
196 |
+
|
197 |
+
self.check_type(LPAREN)
|
198 |
+
c = self.parse()
|
199 |
+
self.check_type(RPAREN)
|
200 |
+
return length(c)
|
201 |
+
|
202 |
+
def parse_head(self):
|
203 |
+
|
204 |
+
self.check_type(LPAREN)
|
205 |
+
c = self.parse()
|
206 |
+
self.check_type(RPAREN)
|
207 |
+
return list_head(c)
|
208 |
+
|
209 |
+
def parse_tail(self):
|
210 |
+
|
211 |
+
self.check_type(LPAREN)
|
212 |
+
c = self.parse()
|
213 |
+
self.check_type(RPAREN)
|
214 |
+
return list_tail(c)
|
215 |
+
|
216 |
+
def parse_isempty(self):
|
217 |
+
|
218 |
+
self.check_type(LPAREN)
|
219 |
+
c = self.parse()
|
220 |
+
self.check_type(RPAREN)
|
221 |
+
return list_isempty(c)
|
222 |
+
|
223 |
+
|
224 |
+
def parse_slice(self, c):
|
225 |
+
|
226 |
+
self.check_type(LSPAREN)
|
227 |
+
if self.curr_token.type==COMMA:
|
228 |
+
# self.check_type(COMMA)
|
229 |
+
start = NumLiteral(0)
|
230 |
+
else:
|
231 |
+
start = self.parse()
|
232 |
+
|
233 |
+
if self.curr_token.type==RSPAREN:
|
234 |
+
index_type = True
|
235 |
+
self.check_type(RSPAREN)
|
236 |
+
|
237 |
+
elif self.curr_token.type==COMMA:
|
238 |
+
index_type = False
|
239 |
+
self.check_type(COMMA)
|
240 |
+
if self.curr_token.type!=COMMA:
|
241 |
+
end = self.parse()
|
242 |
+
else:
|
243 |
+
end = None
|
244 |
+
else:
|
245 |
+
index_type = False
|
246 |
+
end = self.parse()
|
247 |
+
|
248 |
+
|
249 |
+
if index_type==False:
|
250 |
+
if self.curr_token.type==COMMA:
|
251 |
+
self.check_type(COMMA)
|
252 |
+
if self.curr_token.type!=RSPAREN:
|
253 |
+
jump = self.parse()
|
254 |
+
else:
|
255 |
+
jump = NumLiteral(1)
|
256 |
+
|
257 |
+
else:
|
258 |
+
jump = NumLiteral(1)
|
259 |
+
self.check_type(RSPAREN)
|
260 |
+
else:
|
261 |
+
end = None
|
262 |
+
jump = None
|
263 |
+
return Slicing(c, start, end, jump)
|
264 |
+
|
265 |
+
|
266 |
+
def parse_print(self):
|
267 |
+
self.check_type(PRINT)
|
268 |
+
self.check_type(LPAREN)
|
269 |
+
if self.curr_token.type != RPAREN:
|
270 |
+
e = self.logical()
|
271 |
+
else:
|
272 |
+
e = None
|
273 |
+
# print(e)
|
274 |
+
self.check_type(RPAREN)
|
275 |
+
# if self.curr_token.type != END:
|
276 |
+
# e = self.logical()
|
277 |
+
# else:
|
278 |
+
# e = None
|
279 |
+
# # print(e)
|
280 |
+
# self.check_type(END)
|
281 |
+
return Statement("print", e)
|
282 |
+
|
283 |
+
def parse_return(self):
|
284 |
+
self.check_type(RETURN)
|
285 |
+
|
286 |
+
e = self.logical()
|
287 |
+
return Statement("return", e)
|
288 |
+
|
289 |
+
def parse_list(self, Type):
|
290 |
+
if Type != LSPAREN:
|
291 |
+
# print("ENTER")
|
292 |
+
self.check_type(COLON)
|
293 |
+
|
294 |
+
token = self.curr_token
|
295 |
+
self.check_type(INTEGER)
|
296 |
+
Type = token.type
|
297 |
+
datatype = Type
|
298 |
+
|
299 |
+
# print(datatype)
|
300 |
+
|
301 |
+
else:
|
302 |
+
datatype = NONE
|
303 |
+
|
304 |
+
|
305 |
+
self.check_type(LSPAREN)
|
306 |
+
ele = self.parse()
|
307 |
+
value =[ele]
|
308 |
+
token = self.curr_token
|
309 |
+
Type = token.type
|
310 |
+
|
311 |
+
while Type!= RSPAREN:
|
312 |
+
self.check_type(COMMA)
|
313 |
+
ele = self.parse()
|
314 |
+
value.append(ele)
|
315 |
+
token = self.curr_token
|
316 |
+
# print(token)
|
317 |
+
Type = token.type
|
318 |
+
self.check_type(RSPAREN)
|
319 |
+
# print(type(datatype))
|
320 |
+
|
321 |
+
# print("done and dusted")
|
322 |
+
|
323 |
+
return Listing(value, datatype)
|
324 |
+
|
325 |
+
|
326 |
+
|
327 |
+
|
328 |
+
def parse_func(self):
|
329 |
+
self.check_type(FUNCTION)
|
330 |
+
# name = self.variable("Variable")
|
331 |
+
name = self.variable()
|
332 |
+
self.check_type(LPAREN)
|
333 |
+
# var = self.variable("Variable")
|
334 |
+
var = self.variable()
|
335 |
+
token = self.curr_token
|
336 |
+
Type = token.type
|
337 |
+
params = [var] if var != None else []
|
338 |
+
|
339 |
+
while Type != RPAREN:
|
340 |
+
self.check_type(COMMA)
|
341 |
+
if self.curr_token.type == RPAREN:
|
342 |
+
break
|
343 |
+
# var = self.variable("Variable")
|
344 |
+
var = self.variable()
|
345 |
+
|
346 |
+
params.append(var)
|
347 |
+
token = self.curr_token
|
348 |
+
Type = token.type
|
349 |
+
|
350 |
+
self.check_type(RPAREN)
|
351 |
+
if self.curr_token.type == BEGIN:
|
352 |
+
body = self.parse()
|
353 |
+
else:
|
354 |
+
self.check_type(BEGIN)
|
355 |
+
|
356 |
+
|
357 |
+
|
358 |
+
|
359 |
+
return Function(name, params, body)
|
360 |
+
|
361 |
+
def parse_func_call(self, n):
|
362 |
+
node = n
|
363 |
+
self.check_type(LPAREN)
|
364 |
+
if self.curr_token.type == RPAREN:
|
365 |
+
self.check_type(RPAREN)
|
366 |
+
if self.curr_token.type == LPAREN:
|
367 |
+
return self.parse_func_call(FunCall(node, []))
|
368 |
+
return FunCall(node, [])
|
369 |
+
var = self.logical()
|
370 |
+
token = self.curr_token
|
371 |
+
Type = token.type
|
372 |
+
params = [var] if var != None else []
|
373 |
+
|
374 |
+
while Type != RPAREN:
|
375 |
+
self.check_type(COMMA)
|
376 |
+
if self.curr_token.type == RPAREN:
|
377 |
+
break
|
378 |
+
var = self.logical()
|
379 |
+
|
380 |
+
params.append(var)
|
381 |
+
token = self.curr_token
|
382 |
+
Type = token.type
|
383 |
+
|
384 |
+
self.check_type(RPAREN)
|
385 |
+
if self.curr_token.type == LPAREN:
|
386 |
+
return self.parse_func_call(FunCall(node, params))
|
387 |
+
|
388 |
+
return FunCall(node, params)
|
389 |
+
|
390 |
+
def variable(self, ASTtype=None):
|
391 |
+
token = self.curr_token
|
392 |
+
Type = token.type
|
393 |
+
if Type == ID:
|
394 |
+
self.check_type(ID)
|
395 |
+
if ASTtype=="Variable":
|
396 |
+
token = self.curr_token
|
397 |
+
Type = token.type
|
398 |
+
#self.parse_slice(Variable(token.value), Type)
|
399 |
+
return Variable(token.value)
|
400 |
+
|
401 |
+
else:
|
402 |
+
return MutVar(token.value)
|
403 |
+
|
404 |
+
|
405 |
+
|
406 |
+
def precedence3(self):
|
407 |
+
'''precedence3 : INTEGER | LPAREN precedence1 RPAREN | BoolLiteral | Indentifier| (+/-)precedence3 | StringLiteral'''
|
408 |
+
token = self.curr_token
|
409 |
+
Type = token.type
|
410 |
+
if Type == PLUS:
|
411 |
+
self.check_type(PLUS)
|
412 |
+
node = UnOp(operator=token.value, mid=self.precedence3())
|
413 |
+
return node
|
414 |
+
elif Type == MINUS:
|
415 |
+
self.check_type(MINUS)
|
416 |
+
node = UnOp(operator=token.value, mid=self.precedence3())
|
417 |
+
return node
|
418 |
+
elif Type == LPAREN:
|
419 |
+
self.check_type(LPAREN)
|
420 |
+
# node = self.precedence1()
|
421 |
+
node = self.logical()
|
422 |
+
self.check_type(RPAREN)
|
423 |
+
return node
|
424 |
+
elif Type == FRACTION_CONST:
|
425 |
+
self.check_type(FRACTION_CONST)
|
426 |
+
return NumLiteral(token.value)
|
427 |
+
elif Type == REAL_CONST:
|
428 |
+
self.check_type(REAL_CONST)
|
429 |
+
return FloatLiteral(token.value)
|
430 |
+
elif Type == INTEGER_CONST:
|
431 |
+
self.check_type(INTEGER_CONST)
|
432 |
+
return IntLiteral(token.value)
|
433 |
+
elif Type == TRUE or Type == FALSE:
|
434 |
+
self.check_type(Type)
|
435 |
+
return BoolLiteral(token.value)
|
436 |
+
elif Type == LEN:
|
437 |
+
self.check_type(LEN)
|
438 |
+
return self.parse_len()
|
439 |
+
elif Type == HEAD:
|
440 |
+
self.check_type(HEAD)
|
441 |
+
return self.parse_head
|
442 |
+
elif Type == TAIL:
|
443 |
+
self.check_type(TAIL)
|
444 |
+
return self.parse_tail
|
445 |
+
elif Type == ISEMPTY:
|
446 |
+
self.check_type(ISEMPTY)
|
447 |
+
return self.parse_isempty
|
448 |
+
elif Type == LIST:
|
449 |
+
self.check_type(LIST)
|
450 |
+
if self.curr_token.type == COLON:
|
451 |
+
return self.parse_list(self.curr_token.type)
|
452 |
+
return self.parse_list(self.curr_token.type)
|
453 |
+
elif Type == ID:
|
454 |
+
self.check_type(ID)
|
455 |
+
if self.curr_token.type == LPAREN:
|
456 |
+
return self.parse_func_call(MutVar(token.value))
|
457 |
+
elif self.curr_token.type == LSPAREN:
|
458 |
+
return self.parse_slice(MutVar(token.value))
|
459 |
+
return (MutVar(token.value))
|
460 |
+
elif Type == STRING:
|
461 |
+
# Nothing new here, just eat the STRING token and return the String() AST.
|
462 |
+
self.check_type(STRING)
|
463 |
+
return StringLiteral(token.value)
|
464 |
+
|
465 |
+
else:
|
466 |
+
# if Type == END:
|
467 |
+
# self.check_type(END)
|
468 |
+
# return
|
469 |
+
print("None of the suggested tokens found:", INTEGER_CONST, ID, LPAREN, STRING, TRUE, FALSE, "...")
|
470 |
+
self.check_type(INTEGER_CONST)
|
471 |
+
|
472 |
+
|
473 |
+
|
474 |
+
|
475 |
+
def exponential(self):
|
476 |
+
"""exponential : precedence3 | precedence3 POWER precedence3"""
|
477 |
+
node = self.precedence3()
|
478 |
+
token = self.curr_token
|
479 |
+
Type = token.type
|
480 |
+
l = [node]
|
481 |
+
if Type == POWER:
|
482 |
+
while (Type == POWER):
|
483 |
+
token = self.curr_token
|
484 |
+
if token.type == POWER:
|
485 |
+
self.check_type(POWER)
|
486 |
+
e = self.precedence3()
|
487 |
+
# print(e)
|
488 |
+
l.append(e)
|
489 |
+
Type = self.curr_token.type
|
490 |
+
# e = self.precedence3()
|
491 |
+
# print(l)
|
492 |
+
|
493 |
+
i = 1
|
494 |
+
while len(l) > 0 :
|
495 |
+
e = l.pop()
|
496 |
+
if i==1:
|
497 |
+
|
498 |
+
node = BinOp(left=l.pop(), operator=token.value, right=e)
|
499 |
+
else:
|
500 |
+
node = BinOp(left=e, operator=token.value, right=node)
|
501 |
+
i+=1
|
502 |
+
|
503 |
+
return node
|
504 |
+
|
505 |
+
|
506 |
+
def precedence2(self):
|
507 |
+
"""precedence2 : precedence3 | precedence3 MUL/DIV precedence3"""
|
508 |
+
node = self.exponential()
|
509 |
+
token = self.curr_token
|
510 |
+
Type = token.type
|
511 |
+
while (Type == MUL or Type ==FLOAT_DIV or Type == MODULO or Type == INT_DIV):
|
512 |
+
token = self.curr_token
|
513 |
+
if token.type == MUL:
|
514 |
+
self.check_type(MUL)
|
515 |
+
elif token.type == FLOAT_DIV:
|
516 |
+
self.check_type(FLOAT_DIV)
|
517 |
+
elif token.type == INT_DIV:
|
518 |
+
self.check_type(INT_DIV)
|
519 |
+
elif token.type == MODULO:
|
520 |
+
self.check_type(MODULO)
|
521 |
+
elif token.type == INT_DIV:
|
522 |
+
self.check_type(INT_DIV)
|
523 |
+
node = BinOp(left=node, operator=token.value, right=self.exponential())
|
524 |
+
Type = self.curr_token.type
|
525 |
+
return node
|
526 |
+
|
527 |
+
def precedence1(self):
|
528 |
+
"""precedence1 : precedence2 | precedence2 PLUS/MINUS precedence2"""
|
529 |
+
node = self.precedence2()
|
530 |
+
Type = self.curr_token.type
|
531 |
+
while (Type == PLUS or Type ==MINUS):
|
532 |
+
token = self.curr_token
|
533 |
+
if token.type == PLUS:
|
534 |
+
self.check_type(PLUS)
|
535 |
+
elif token.type == MINUS:
|
536 |
+
self.check_type(MINUS)
|
537 |
+
node = BinOp(left=node, operator=token.value, right=self.precedence2())
|
538 |
+
Type = self.curr_token.type
|
539 |
+
return node
|
540 |
+
|
541 |
+
# def parse(self):
|
542 |
+
# return self.precedence1()
|
543 |
+
def relational(self, n=None):
|
544 |
+
"""relational : precedence1 | precedence1 relationalOperator precedence1"""
|
545 |
+
if n == None:
|
546 |
+
node = self.precedence1()
|
547 |
+
else:
|
548 |
+
node = n
|
549 |
+
Type = self.curr_token.type
|
550 |
+
# print(Type)
|
551 |
+
# while(Type == GT or Type == GTEQ or Type == LT or Type == LTEQ):
|
552 |
+
if(Type == GT or Type == GTEQ or Type == LT or Type == LTEQ or Type == EQEQ or Type == NOTEQ):
|
553 |
+
token = self.curr_token
|
554 |
+
if token.type == GT:
|
555 |
+
self.check_type(GT)
|
556 |
+
elif token.type == GTEQ:
|
557 |
+
self.check_type(GTEQ)
|
558 |
+
elif token.type == LT:
|
559 |
+
self.check_type(LT)
|
560 |
+
elif token.type == LTEQ:
|
561 |
+
self.check_type(LTEQ)
|
562 |
+
elif token.type == EQEQ:
|
563 |
+
self.check_type(EQEQ)
|
564 |
+
elif token.type == NOTEQ:
|
565 |
+
self.check_type(NOTEQ)
|
566 |
+
node = BinOp(left=node, operator=token.value, right=self.precedence1())
|
567 |
+
# Type = self.curr_token.type
|
568 |
+
return node
|
569 |
+
|
570 |
+
def logical(self, n=None):
|
571 |
+
"""logical : relational | relational logicalOperator relational"""
|
572 |
+
if n == None:
|
573 |
+
node = self.relational()
|
574 |
+
else:
|
575 |
+
node = n
|
576 |
+
# node = self.relational()
|
577 |
+
Type = self.curr_token.type
|
578 |
+
if(Type == OR or Type == AND):
|
579 |
+
token = self.curr_token
|
580 |
+
if token.type == AND:
|
581 |
+
self.check_type(AND)
|
582 |
+
elif token.type == OR:
|
583 |
+
self.check_type(OR)
|
584 |
+
node = BinOp(left=node, operator= token.value, right=self.relational())
|
585 |
+
return node
|
586 |
+
|
587 |
+
def assignment(self, n=None):
|
588 |
+
"""assignment : variable ASSIGN relational"""
|
589 |
+
if n == None:
|
590 |
+
node = self.variable()
|
591 |
+
else:
|
592 |
+
node = n
|
593 |
+
Type = self.curr_token.type
|
594 |
+
# token = self.curr_token
|
595 |
+
# print(Type)
|
596 |
+
|
597 |
+
|
598 |
+
# if Type == ASSIGN:
|
599 |
+
# self.check_type(ASSIGN)
|
600 |
+
# token = self.curr_token
|
601 |
+
# node = BinOp(left=node, operator=token.value, right=self.logical())
|
602 |
+
# else:
|
603 |
+
# if isinstance(node,MutVar):
|
604 |
+
# node = self.logical(Get(node))
|
605 |
+
# else:
|
606 |
+
# node = self.logical()
|
607 |
+
|
608 |
+
if(Type == ASSIGN or Type == PLUSEQ or Type == MINUSEQ or Type == FLOAT_DIVEQ or Type == MULEQ or Type == POWEREQ):
|
609 |
+
token = self.curr_token
|
610 |
+
if Type == ASSIGN:
|
611 |
+
self.check_type(ASSIGN)
|
612 |
+
node = BinOp(left=node, operator= token.value, right=self.logical())
|
613 |
+
elif Type == MULEQ:
|
614 |
+
self.check_type(MULEQ)
|
615 |
+
# print(self.curr_token)
|
616 |
+
node = BinOp(left=node, operator= token.value, right=self.logical())
|
617 |
+
elif Type == MINUSEQ:
|
618 |
+
self.check_type(MINUSEQ)
|
619 |
+
# print(self.curr_token)
|
620 |
+
node = BinOp(left=node, operator= token.value, right=self.logical())
|
621 |
+
elif Type == FLOAT_DIVEQ:
|
622 |
+
self.check_type(FLOAT_DIVEQ)
|
623 |
+
# print(self.curr_token)
|
624 |
+
node = BinOp(left=node, operator= token.value, right=self.logical())
|
625 |
+
elif Type == PLUSEQ:
|
626 |
+
self.check_type(PLUSEQ)
|
627 |
+
# print(self.curr_token)
|
628 |
+
node = BinOp(left=node, operator= token.value, right=self.logical())
|
629 |
+
elif Type == POWEREQ:
|
630 |
+
self.check_type(POWEREQ)
|
631 |
+
# print(self.curr_token)
|
632 |
+
node = BinOp(left=node, operator= token.value, right=self.logical())
|
633 |
+
else:
|
634 |
+
if isinstance(node,MutVar):
|
635 |
+
node = self.logical(node)
|
636 |
+
else:
|
637 |
+
node = self.logical()
|
638 |
+
|
639 |
+
return node
|
640 |
+
|
641 |
+
|
642 |
+
def parse(self):
|
643 |
+
"""parse : parse_if | parse_print | parse_begin | assignment"""
|
644 |
+
match self.curr_token.type:
|
645 |
+
case 'IF':
|
646 |
+
return self.parse_if()
|
647 |
+
case 'WHILE':
|
648 |
+
return self.parse_while()
|
649 |
+
case 'FOR':
|
650 |
+
return self.parse_for()
|
651 |
+
case 'PRINT':
|
652 |
+
return self.parse_print()
|
653 |
+
case 'RETURN':
|
654 |
+
return self.parse_return()
|
655 |
+
case 'BEGIN':
|
656 |
+
return self.parse_begin()
|
657 |
+
case 'FUNCTION':
|
658 |
+
return self.parse_func()
|
659 |
+
case 'BREAK':
|
660 |
+
self.check_type(BREAK)
|
661 |
+
return Statement("break",NumLiteral(0))
|
662 |
+
case 'INC':
|
663 |
+
return self.parse_inc()
|
664 |
+
case 'DEC':
|
665 |
+
return self.parse_dec()
|
666 |
+
case 'APPEND':
|
667 |
+
return self.parse_list_append()
|
668 |
+
# case 'SEMI':
|
669 |
+
# return
|
670 |
+
# return self.parse()
|
671 |
+
case _:
|
672 |
+
node = self.variable()
|
673 |
+
if self.curr_token.type == LPAREN:
|
674 |
+
return self.parse_func_call(node)
|
675 |
+
|
676 |
+
# node = MutVar(node.name)
|
677 |
+
return self.assignment(node)
|
String_op_testcases.txt
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{String Operations}
|
2 |
+
|
3 |
+
BEGIN
|
4 |
+
str := "String Checking";
|
5 |
+
PRINT str END;
|
6 |
+
PRINT LEN(str) END;
|
7 |
+
x := 2;
|
8 |
+
y := 13;
|
9 |
+
z := 3;
|
10 |
+
PRINT str[x,y,z] END;
|
11 |
+
PRINT str[14] END;
|
12 |
+
PRINT str[1,5] END;
|
13 |
+
PRINT str[,,] END;
|
14 |
+
{PRINT "bisbciwi"[4] END;}
|
15 |
+
|
16 |
+
END
|
app.py
ADDED
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
import time
|
3 |
+
import lexer as lex
|
4 |
+
# import Parser as prs
|
5 |
+
from io import StringIO
|
6 |
+
from sim import *
|
7 |
+
import time
|
8 |
+
from streamlit.components.v1 import html
|
9 |
+
|
10 |
+
# import sys
|
11 |
+
|
12 |
+
st.write("""AZKABAN language""")
|
13 |
+
|
14 |
+
|
15 |
+
file = st.file_uploader("Pick a file")
|
16 |
+
|
17 |
+
if file is not None:
|
18 |
+
stringio = StringIO(file.getvalue().decode("utf-8"))
|
19 |
+
# st.write(stringio)
|
20 |
+
string_data = stringio.read()
|
21 |
+
# st.write(string_data)
|
22 |
+
text = st.text_area('Please Enter Your Code Here', string_data)
|
23 |
+
else:
|
24 |
+
text = st.text_area('Please Enter Your Code Here', "PRINT(3+4);")
|
25 |
+
# print(text)
|
26 |
+
start = time.time()
|
27 |
+
# text = "PRINT 3@(1/2) END"
|
28 |
+
# text = "3 > 4"
|
29 |
+
# text = "-2*(1---2)"
|
30 |
+
# text = "PRINT 2-+ +3 END"
|
31 |
+
# if len(text) != 0:
|
32 |
+
text = "BEGIN "+text+" END"
|
33 |
+
|
34 |
+
l = lex.Lexer(text)
|
35 |
+
p = prs.Parser(l)
|
36 |
+
i = Interpreter(p)
|
37 |
+
# print(eval(i))
|
38 |
+
|
39 |
+
|
40 |
+
eval(i)
|
41 |
+
st.write("Output:")
|
42 |
+
|
43 |
+
# html(open("eval.txt").read(), height=100, scrolling=True)
|
44 |
+
|
45 |
+
st.write(open("eval.txt","r").readlines())
|
46 |
+
|
47 |
+
st.write("Time taken", time.time()-start)
|
48 |
+
print("Time taken", time.time()-start)
|
49 |
+
|
50 |
+
|
51 |
+
|
52 |
+
|
53 |
+
|
automat.py
ADDED
@@ -0,0 +1,174 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import os
|
2 |
+
import lexer as lex
|
3 |
+
from sim import *
|
4 |
+
import sys
|
5 |
+
import re
|
6 |
+
import platform
|
7 |
+
|
8 |
+
def run_test_cases(dir_path):
|
9 |
+
while True:
|
10 |
+
sys.stdout = sys.__stdout__
|
11 |
+
command = input("Enter command : ")
|
12 |
+
match command:
|
13 |
+
case "all":
|
14 |
+
dir = giveFilesWithFolders(dir_path)
|
15 |
+
# for file in os.listdir(dir_path):
|
16 |
+
for file in dir:
|
17 |
+
if file.endswith(".txt"):
|
18 |
+
|
19 |
+
# print("Running test case: " + file)
|
20 |
+
# with open(os.path.join(dir_path, file)) as f:
|
21 |
+
with open(file) as f:
|
22 |
+
text = f.read()
|
23 |
+
text = "BEGIN "+text+" END"
|
24 |
+
l = lex.Lexer(text)
|
25 |
+
p = prs.Parser(l)
|
26 |
+
i = Interpreter(p)
|
27 |
+
eval(i)
|
28 |
+
sys.stdout = sys.__stdout__
|
29 |
+
|
30 |
+
|
31 |
+
# with open('tempt2.txt', 'r') as f:
|
32 |
+
# print(f.read())
|
33 |
+
|
34 |
+
# print('------------------------')
|
35 |
+
|
36 |
+
# with open(os.path.join(dir_path, 'tempt.txt')) as f:
|
37 |
+
# print(f.read())
|
38 |
+
# if platform.platform().startswith('Windows'):
|
39 |
+
# output = os.popen('fc eval.txt solution.txt').read()
|
40 |
+
# else:
|
41 |
+
# output = os.popen('diff eval.txt solution.txt').read()
|
42 |
+
# print(output, len(output))
|
43 |
+
|
44 |
+
# print(output)
|
45 |
+
# if output == "":
|
46 |
+
# compare two text files
|
47 |
+
|
48 |
+
if open('eval.txt').read() == open('solution.txt').read():
|
49 |
+
print("Test passed: " + file)
|
50 |
+
else:
|
51 |
+
print("Test failed: " + file)
|
52 |
+
# output = os.popen('').read()
|
53 |
+
# for line in lines[1:]:
|
54 |
+
# print(line)
|
55 |
+
# continue
|
56 |
+
|
57 |
+
case "exit":
|
58 |
+
break
|
59 |
+
case default:
|
60 |
+
try:
|
61 |
+
dir = giveFilesWithFolders(dir_path)
|
62 |
+
# with open(os.path.join(dir_path, default)) as f:
|
63 |
+
flag = 1
|
64 |
+
# if re.search(".", default) != None:
|
65 |
+
if default.find(".")>=0:
|
66 |
+
# print("e111")
|
67 |
+
|
68 |
+
for file in dir:
|
69 |
+
if file.endswith(default):
|
70 |
+
flag = 0
|
71 |
+
with open(file) as f:
|
72 |
+
text = f.read()
|
73 |
+
text = "BEGIN "+text+" END"
|
74 |
+
l = lex.Lexer(text)
|
75 |
+
p = prs.Parser(l)
|
76 |
+
i = Interpreter(p)
|
77 |
+
eval(i)
|
78 |
+
sys.stdout = sys.__stdout__
|
79 |
+
|
80 |
+
# if platform.platform().startswith('Windows'):
|
81 |
+
# output = os.popen('fc eval.txt solution.txt').read()
|
82 |
+
# else:
|
83 |
+
# output = os.popen('diff eval.txt solution.txt').read()
|
84 |
+
|
85 |
+
|
86 |
+
# print(output)
|
87 |
+
# if output == "":
|
88 |
+
if open('eval.txt').read() == open('solution.txt').read():
|
89 |
+
print("Test passed: " + file)
|
90 |
+
else:
|
91 |
+
print("Test failed: " + file)
|
92 |
+
if flag == 1:
|
93 |
+
print("File or Folder not found")
|
94 |
+
|
95 |
+
else:
|
96 |
+
# print("f222")
|
97 |
+
# run all files in folder
|
98 |
+
for file in dir:
|
99 |
+
# print(default)
|
100 |
+
|
101 |
+
if file.startswith(default) or (file.find(default+"\\")>=0):
|
102 |
+
# print("entering")
|
103 |
+
flag = 0
|
104 |
+
with open(file) as f:
|
105 |
+
text = f.read()
|
106 |
+
|
107 |
+
text = "BEGIN "+text+" END"
|
108 |
+
l = lex.Lexer(text)
|
109 |
+
p = prs.Parser(l)
|
110 |
+
i = Interpreter(p)
|
111 |
+
eval(i)
|
112 |
+
sys.stdout = sys.__stdout__
|
113 |
+
# if platform.platform().startswith('Windows'):
|
114 |
+
# output = os.popen('fc eval.txt solution.txt').read()
|
115 |
+
# else:
|
116 |
+
# output = os.popen('diff eval.txt solution.txt').read()
|
117 |
+
|
118 |
+
|
119 |
+
# print(output)
|
120 |
+
# if output == "":
|
121 |
+
if open('eval.txt').read() == open('solution.txt').read():
|
122 |
+
print("Test passed: " + file)
|
123 |
+
else:
|
124 |
+
print("Test failed: " + file)
|
125 |
+
if flag == 1:
|
126 |
+
print("File or Folder not found")
|
127 |
+
|
128 |
+
except:
|
129 |
+
print("File or Folder not found")
|
130 |
+
# if f == None:
|
131 |
+
# print("File not found")
|
132 |
+
# continue
|
133 |
+
|
134 |
+
def giveFilesWithFolders(dir_path):
|
135 |
+
files = []
|
136 |
+
for file in os.listdir(dir_path):
|
137 |
+
if os.path.isdir(os.path.join(dir_path, file)):
|
138 |
+
|
139 |
+
# files.append(file)
|
140 |
+
files.extend(giveFilesWithFolders(os.path.join(dir_path, file)))
|
141 |
+
else:
|
142 |
+
files.append(dir_path+"\\"+file)
|
143 |
+
return files
|
144 |
+
|
145 |
+
|
146 |
+
if __name__ == "__main__":
|
147 |
+
# start = time.time()
|
148 |
+
# run_test_cases("test_cases")
|
149 |
+
dir = os.listdir("test_cases")
|
150 |
+
dir.append("")
|
151 |
+
print(dir)
|
152 |
+
dir = giveFilesWithFolders("test_cases")
|
153 |
+
print(dir)
|
154 |
+
# default = input("Enter folder")
|
155 |
+
# for i in dir:
|
156 |
+
# x = re.search(".", i)
|
157 |
+
|
158 |
+
# print(i.startswith(default) or (i.find(default+"\\")>=0))
|
159 |
+
|
160 |
+
run_test_cases("test_cases")
|
161 |
+
# print("hi")
|
162 |
+
# print(x)
|
163 |
+
# if not x:
|
164 |
+
# print("hi")
|
165 |
+
# run_test_cases("test_cases/" + i)
|
166 |
+
# print("Time taken", time.time()-start)
|
167 |
+
|
168 |
+
|
169 |
+
# import platform
|
170 |
+
|
171 |
+
# print(platform.platform())
|
172 |
+
|
173 |
+
|
174 |
+
# code to write in file
|
dataclasses_sim.py
ADDED
@@ -0,0 +1,273 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from dataclasses import dataclass
|
2 |
+
from fractions import Fraction
|
3 |
+
from typing import Union, Mapping, Optional, NewType, List
|
4 |
+
|
5 |
+
# Resolver On/Off
|
6 |
+
resolverOn = True #False ; Turn to False if not using resolver
|
7 |
+
currentID = 0
|
8 |
+
|
9 |
+
def fresh():
|
10 |
+
global currentID
|
11 |
+
currentID = currentID + 1
|
12 |
+
return currentID
|
13 |
+
@dataclass
|
14 |
+
class BoolLiteral:
|
15 |
+
value: bool
|
16 |
+
def __init__(self, *args):
|
17 |
+
self.value = bool(*args)
|
18 |
+
# type: SimType = BoolType()
|
19 |
+
|
20 |
+
@dataclass
|
21 |
+
class NumLiteral:
|
22 |
+
value: Fraction
|
23 |
+
# type: SimType = NumType()
|
24 |
+
def __init__(self, *args):
|
25 |
+
self.value = Fraction(*args)
|
26 |
+
|
27 |
+
@dataclass
|
28 |
+
class IntLiteral:
|
29 |
+
value: Fraction
|
30 |
+
# type: SimType = NumType()
|
31 |
+
def __init__(self, *args):
|
32 |
+
self.value = int(*args)
|
33 |
+
|
34 |
+
|
35 |
+
@dataclass
|
36 |
+
class FloatLiteral:
|
37 |
+
value: Fraction
|
38 |
+
# type: SimType = NumType()
|
39 |
+
def __init__(self, *args):
|
40 |
+
self.value = float(*args)
|
41 |
+
|
42 |
+
@dataclass
|
43 |
+
class StringLiteral:
|
44 |
+
value : str
|
45 |
+
def __init__(self, *args):
|
46 |
+
self.value = str(*args)
|
47 |
+
|
48 |
+
@dataclass
|
49 |
+
class BinOp:
|
50 |
+
operator: str
|
51 |
+
left: 'AST'
|
52 |
+
right: 'AST'
|
53 |
+
def get_left(self):
|
54 |
+
return self.left
|
55 |
+
def get_right(self):
|
56 |
+
return self.right
|
57 |
+
|
58 |
+
|
59 |
+
@dataclass
|
60 |
+
class UnOp:
|
61 |
+
operator: str
|
62 |
+
mid: 'AST'
|
63 |
+
def get_mid(self):
|
64 |
+
return self.mid
|
65 |
+
|
66 |
+
@dataclass
|
67 |
+
class Variable:
|
68 |
+
name: str
|
69 |
+
|
70 |
+
@dataclass
|
71 |
+
class Let:
|
72 |
+
var: 'AST'
|
73 |
+
e1: 'AST'
|
74 |
+
e2: 'AST'
|
75 |
+
|
76 |
+
@dataclass
|
77 |
+
class LetMut:
|
78 |
+
var: 'AST'
|
79 |
+
e1: 'AST'
|
80 |
+
e2: 'AST'
|
81 |
+
|
82 |
+
@dataclass
|
83 |
+
class Put:
|
84 |
+
var: 'AST'
|
85 |
+
e1: 'AST'
|
86 |
+
|
87 |
+
@dataclass
|
88 |
+
class Get:
|
89 |
+
var: 'AST'
|
90 |
+
|
91 |
+
@dataclass
|
92 |
+
class LetFun:
|
93 |
+
name: 'AST'
|
94 |
+
params: List['AST']
|
95 |
+
body: 'AST'
|
96 |
+
expr: 'AST'
|
97 |
+
|
98 |
+
@dataclass
|
99 |
+
class FunCall:
|
100 |
+
fn: 'AST'
|
101 |
+
args: List['AST']
|
102 |
+
|
103 |
+
|
104 |
+
@dataclass
|
105 |
+
class Statement:
|
106 |
+
command: str
|
107 |
+
statement : "AST"
|
108 |
+
|
109 |
+
@dataclass
|
110 |
+
class IfElse:
|
111 |
+
condition: 'AST'
|
112 |
+
then_body: 'AST'
|
113 |
+
else_body: 'AST'
|
114 |
+
|
115 |
+
@dataclass
|
116 |
+
class Seq:
|
117 |
+
statements: List['AST']
|
118 |
+
|
119 |
+
@dataclass
|
120 |
+
class MutVar:
|
121 |
+
name: str
|
122 |
+
value: 'AST'
|
123 |
+
id: int #Final[int] #comment it if not using resolver
|
124 |
+
def __init__(self, name) -> None:
|
125 |
+
self.value = None
|
126 |
+
self.name = name
|
127 |
+
self.id = fresh() if resolverOn else 0
|
128 |
+
def get(self):
|
129 |
+
return self.value
|
130 |
+
def put(self, val):
|
131 |
+
self.value = val
|
132 |
+
|
133 |
+
@dataclass
|
134 |
+
class ForLoop:
|
135 |
+
start : 'AST'
|
136 |
+
end : 'AST'
|
137 |
+
increment : 'AST'
|
138 |
+
body : 'AST'
|
139 |
+
|
140 |
+
@dataclass
|
141 |
+
class While:
|
142 |
+
condition: 'AST'
|
143 |
+
body: 'AST'
|
144 |
+
|
145 |
+
@dataclass
|
146 |
+
class Function:
|
147 |
+
name: 'AST'
|
148 |
+
params: List['AST']
|
149 |
+
body: 'AST'
|
150 |
+
|
151 |
+
|
152 |
+
@dataclass
|
153 |
+
class CallStack:
|
154 |
+
clstk: List
|
155 |
+
|
156 |
+
@dataclass
|
157 |
+
class Increment:
|
158 |
+
var_literal : 'AST'
|
159 |
+
|
160 |
+
@dataclass
|
161 |
+
class Decrement:
|
162 |
+
var_literal : 'AST'
|
163 |
+
|
164 |
+
|
165 |
+
@dataclass
|
166 |
+
class Slicing:
|
167 |
+
name : 'AST'
|
168 |
+
start : 'AST'
|
169 |
+
end : 'AST'
|
170 |
+
jump : 'AST'
|
171 |
+
|
172 |
+
@dataclass
|
173 |
+
class list_Slicing:
|
174 |
+
name : 'AST'
|
175 |
+
start : 'AST'
|
176 |
+
end : 'AST'
|
177 |
+
jump : 'AST'
|
178 |
+
|
179 |
+
|
180 |
+
@dataclass
|
181 |
+
class Listing:
|
182 |
+
value : List['AST']
|
183 |
+
datatype : 'AST'
|
184 |
+
|
185 |
+
@dataclass
|
186 |
+
class list_append:
|
187 |
+
var : 'AST'
|
188 |
+
item : 'AST'
|
189 |
+
|
190 |
+
|
191 |
+
@dataclass
|
192 |
+
class list_head:
|
193 |
+
name: 'AST'
|
194 |
+
|
195 |
+
|
196 |
+
@dataclass
|
197 |
+
class list_tail:
|
198 |
+
name: 'AST'
|
199 |
+
|
200 |
+
@dataclass
|
201 |
+
class list_isempty:
|
202 |
+
name: 'AST'
|
203 |
+
|
204 |
+
|
205 |
+
@dataclass
|
206 |
+
class length:
|
207 |
+
name: 'AST'
|
208 |
+
|
209 |
+
class Environment:
|
210 |
+
envs: List
|
211 |
+
|
212 |
+
def __init__(self):
|
213 |
+
self.envs = [{}]
|
214 |
+
|
215 |
+
def enter_scope(self):
|
216 |
+
self.envs.append({})
|
217 |
+
|
218 |
+
def exit_scope(self):
|
219 |
+
assert self.envs
|
220 |
+
self.envs.pop()
|
221 |
+
|
222 |
+
def add(self, name, value):
|
223 |
+
assert name not in self.envs[-1]
|
224 |
+
self.envs[-1][name] = value
|
225 |
+
|
226 |
+
def get(self, name):
|
227 |
+
for env in reversed(self.envs):
|
228 |
+
if name in env:
|
229 |
+
return env[name]
|
230 |
+
print("Current Environment", self.envs)
|
231 |
+
print("Current AST", self.program)
|
232 |
+
raise KeyError()
|
233 |
+
|
234 |
+
def update(self, name, value):
|
235 |
+
for env in reversed(self.envs):
|
236 |
+
if name in env:
|
237 |
+
env[name] = value
|
238 |
+
return
|
239 |
+
print("Current AST", self.program)
|
240 |
+
print("Current Environment", self.envs)
|
241 |
+
raise KeyError()
|
242 |
+
|
243 |
+
def check(self, name):
|
244 |
+
for env in reversed(self.envs):
|
245 |
+
|
246 |
+
if name in env:
|
247 |
+
return True
|
248 |
+
else:
|
249 |
+
return False
|
250 |
+
# raise KeyError()
|
251 |
+
def addWithOther(self, n1, n2, v2):
|
252 |
+
for env in reversed(self.envs):
|
253 |
+
if n1 in env:
|
254 |
+
env[n2] = v2
|
255 |
+
|
256 |
+
AST = NumLiteral | BinOp | Variable | Let | BoolLiteral | UnOp | StringLiteral | IfElse | MutVar | While | Seq | Function | LetFun | FunCall | Slicing
|
257 |
+
|
258 |
+
@dataclass
|
259 |
+
class FnObject:
|
260 |
+
params: List['AST']
|
261 |
+
body: 'AST'
|
262 |
+
def get(self):
|
263 |
+
return self#FnObject(self.params, self.body)
|
264 |
+
Value = Fraction
|
265 |
+
Val = bool
|
266 |
+
|
267 |
+
|
268 |
+
|
269 |
+
# Val_string = string
|
270 |
+
|
271 |
+
@dataclass
|
272 |
+
class InvalidProgram(Exception):
|
273 |
+
pass
|
error_in_sim
ADDED
@@ -0,0 +1,4 @@
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Current AST
|
2 |
+
None
|
3 |
+
Current Environment:
|
4 |
+
[{}, {'i': MutVar(name='i', value=Fraction(10, 1), id=47)}]
|
eval.txt
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
7
|
fizz_buzz.txt
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{FIZZZ BUZZ code}
|
2 |
+
|
3 |
+
BEGIN
|
4 |
+
|
5 |
+
n:=35;
|
6 |
+
i:=1;
|
7 |
+
|
8 |
+
WHILE i<=n
|
9 |
+
DO
|
10 |
+
BEGIN
|
11 |
+
IF i%3=0 && i%5=0
|
12 |
+
THEN
|
13 |
+
BEGIN
|
14 |
+
PRINT "FIZZ BUZZ" END;
|
15 |
+
END
|
16 |
+
ELSE
|
17 |
+
END;
|
18 |
+
IF i%3=0 && i%5<>0
|
19 |
+
THEN
|
20 |
+
BEGIN
|
21 |
+
PRINT "FIZZ" END;
|
22 |
+
END
|
23 |
+
ELSE
|
24 |
+
END;
|
25 |
+
IF i%3<>0 && i%5=0
|
26 |
+
THEN
|
27 |
+
BEGIN
|
28 |
+
PRINT "BUZZ" END;
|
29 |
+
END
|
30 |
+
ELSE
|
31 |
+
END;
|
32 |
+
IF i%3<>0 && i%5<>0
|
33 |
+
THEN
|
34 |
+
BEGIN
|
35 |
+
PRINT i END;
|
36 |
+
END
|
37 |
+
ELSE
|
38 |
+
END;
|
39 |
+
|
40 |
+
i:=i+1;
|
41 |
+
|
42 |
+
END
|
43 |
+
END;
|
44 |
+
END
|
45 |
+
|
46 |
+
|
for_loop_testing_cases.txt
ADDED
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{case 1}
|
2 |
+
{BEGIN
|
3 |
+
p:=1;
|
4 |
+
q:=1;
|
5 |
+
FOR i:= 1 ; i < 126 ; i := i + 1
|
6 |
+
DO
|
7 |
+
BEGIN
|
8 |
+
q:=q*p;
|
9 |
+
p:=p+1;
|
10 |
+
{PRINT p END;}
|
11 |
+
PRINT q END;
|
12 |
+
PRINT i END;
|
13 |
+
END
|
14 |
+
END;
|
15 |
+
END
|
16 |
+
}
|
17 |
+
|
18 |
+
{case 2}
|
19 |
+
{BEGIN
|
20 |
+
p:=1;
|
21 |
+
q:=1;
|
22 |
+
FOR i:= 125 ; i > 0 ; i := i - 1
|
23 |
+
DO
|
24 |
+
BEGIN
|
25 |
+
q:=q*p;
|
26 |
+
p:=p+1;
|
27 |
+
{PRINT p END;}
|
28 |
+
PRINT q END;
|
29 |
+
PRINT i END;
|
30 |
+
END
|
31 |
+
END;
|
32 |
+
END}
|
33 |
+
|
34 |
+
{case 3}
|
35 |
+
BEGIN
|
36 |
+
p:=1;
|
37 |
+
q:=1;
|
38 |
+
FOR i:= 10 ; ; i := i - 1
|
39 |
+
DO
|
40 |
+
BEGIN
|
41 |
+
q:=q*p;
|
42 |
+
p:=p+1;
|
43 |
+
{PRINT p END;}
|
44 |
+
PRINT q END;
|
45 |
+
PRINT i END;
|
46 |
+
IF i <= 0
|
47 |
+
THEN
|
48 |
+
BEGIN
|
49 |
+
BREAK;
|
50 |
+
END
|
51 |
+
ELSE
|
52 |
+
END
|
53 |
+
END
|
54 |
+
END;
|
55 |
+
END
|
input.txt
ADDED
@@ -0,0 +1,779 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{Factorial of n}{
|
2 |
+
BEGIN
|
3 |
+
i:=1;
|
4 |
+
p:=1;
|
5 |
+
n:=1559; {when while used python ifelse, max limit=494 }
|
6 |
+
WHILE i<n
|
7 |
+
DO
|
8 |
+
BEGIN
|
9 |
+
p:=p*i;
|
10 |
+
i:=i+1;{
|
11 |
+
PRINT i END;
|
12 |
+
PRINT p END;}
|
13 |
+
END
|
14 |
+
END;
|
15 |
+
|
16 |
+
PRINT i END;
|
17 |
+
PRINT p END;
|
18 |
+
END}
|
19 |
+
{Fibonacci upto n numbers}{
|
20 |
+
BEGIN
|
21 |
+
n:=20577; {when while used python ifelse, max limit=495; 10000 time taken 29.94s, 15000->60.9s, 20577(max limit)->118.23s print takes time }
|
22 |
+
f:=0;
|
23 |
+
s:=1;
|
24 |
+
PRINT f END;
|
25 |
+
PRINT s END;
|
26 |
+
i:=2;
|
27 |
+
WHILE i<n
|
28 |
+
DO
|
29 |
+
BEGIN
|
30 |
+
t:=s;
|
31 |
+
s:=s+f;
|
32 |
+
f:=t;
|
33 |
+
PRINT s END;
|
34 |
+
PRINT i END;
|
35 |
+
i:=i+1;
|
36 |
+
END
|
37 |
+
END;
|
38 |
+
END}
|
39 |
+
{Function Testing}{
|
40 |
+
BEGIN
|
41 |
+
PRINT 2+3 END;
|
42 |
+
FUNCTION add(a,b)
|
43 |
+
BEGIN
|
44 |
+
c:=a+b;
|
45 |
+
RETURN c;
|
46 |
+
END;
|
47 |
+
PRINT add(2,5) END;
|
48 |
+
END}
|
49 |
+
{Recursive Function Testing (Factorial)}{
|
50 |
+
BEGIN
|
51 |
+
FUNCTION fact(n)
|
52 |
+
BEGIN
|
53 |
+
IF n<=1
|
54 |
+
THEN RETURN 1
|
55 |
+
ELSE RETURN n*fact(n-1)
|
56 |
+
END;
|
57 |
+
END;
|
58 |
+
PRINT fact(98) END;
|
59 |
+
END}
|
60 |
+
{Recursive Fibonacci}{
|
61 |
+
BEGIN
|
62 |
+
f:=0;
|
63 |
+
s:=1;
|
64 |
+
FUNCTION fibo(n)
|
65 |
+
BEGIN
|
66 |
+
IF n<=1
|
67 |
+
THEN RETURN f
|
68 |
+
ELSE
|
69 |
+
BEGIN
|
70 |
+
t:=s;
|
71 |
+
s:=s+f;
|
72 |
+
f:=t;
|
73 |
+
fibo(n-1);
|
74 |
+
END
|
75 |
+
END;
|
76 |
+
|
77 |
+
END;
|
78 |
+
PRINT fibo(123) END;
|
79 |
+
END}
|
80 |
+
{Project Euler Problem 1 Multiples of 3 or 5}{
|
81 |
+
BEGIN
|
82 |
+
sum:=0;
|
83 |
+
n:=1000; {233168}
|
84 |
+
i:=1;
|
85 |
+
WHILE i<n
|
86 |
+
DO
|
87 |
+
BEGIN
|
88 |
+
IF i%3=0 || i%5=0
|
89 |
+
THEN
|
90 |
+
BEGIN
|
91 |
+
sum:=sum+i;
|
92 |
+
PRINT i END;
|
93 |
+
END
|
94 |
+
ELSE
|
95 |
+
END;
|
96 |
+
i:=i+1;
|
97 |
+
END
|
98 |
+
END;
|
99 |
+
PRINT "SUM=" END;
|
100 |
+
PRINT sum END;
|
101 |
+
|
102 |
+
END}
|
103 |
+
{Project Euler Problem 2 Even Fibonacci numbers}{
|
104 |
+
BEGIN
|
105 |
+
sum:=0;
|
106 |
+
n:=4000000; {4613732}
|
107 |
+
f:=1;
|
108 |
+
s:=2;
|
109 |
+
WHILE f<=n
|
110 |
+
DO
|
111 |
+
BEGIN
|
112 |
+
t:=s;
|
113 |
+
s:=s+f;
|
114 |
+
f:=t;
|
115 |
+
IF f%2=0
|
116 |
+
THEN
|
117 |
+
BEGIN
|
118 |
+
sum+=f;
|
119 |
+
PRINT f END;
|
120 |
+
END
|
121 |
+
ELSE
|
122 |
+
END;
|
123 |
+
END
|
124 |
+
END;
|
125 |
+
PRINT "SUM=" END;
|
126 |
+
PRINT sum END;
|
127 |
+
END}
|
128 |
+
{Project Euler Problem 3 Largest prime factor}{
|
129 |
+
BEGIN
|
130 |
+
n:=600851475143; {13195->5,7,13,29->0.38s, after optimize/actual better soln->0.014s; 600851475143->71,839,1471,6857->0.23s}
|
131 |
+
i:=2;
|
132 |
+
maxPrimeFactor:=0;
|
133 |
+
FUNCTION findFirstPrimeFactor(num, ini)
|
134 |
+
BEGIN
|
135 |
+
j:=ini;
|
136 |
+
flag:=0;
|
137 |
+
WHILE j<=num/2
|
138 |
+
DO
|
139 |
+
BEGIN
|
140 |
+
IF num%j=0
|
141 |
+
THEN
|
142 |
+
BEGIN
|
143 |
+
flag:=1;
|
144 |
+
{i:=j;
|
145 |
+
PRINT j END;}
|
146 |
+
BREAK;
|
147 |
+
END
|
148 |
+
ELSE END;
|
149 |
+
j+=1;
|
150 |
+
END
|
151 |
+
END;
|
152 |
+
|
153 |
+
IF flag=0
|
154 |
+
THEN RETURN num
|
155 |
+
ELSE RETURN j
|
156 |
+
END;
|
157 |
+
END;
|
158 |
+
|
159 |
+
{IF isPrime(n)=FALSE
|
160 |
+
THEN
|
161 |
+
BEGIN}
|
162 |
+
WHILE i<n
|
163 |
+
DO
|
164 |
+
BEGIN
|
165 |
+
i:=findFirstPrimeFactor(n, i);
|
166 |
+
{IF isPrime(i)
|
167 |
+
THEN
|
168 |
+
BEGIN}
|
169 |
+
prevN:=n;
|
170 |
+
WHILE n%i=0
|
171 |
+
DO
|
172 |
+
BEGIN
|
173 |
+
|
174 |
+
n:=n/i;
|
175 |
+
|
176 |
+
END
|
177 |
+
END;
|
178 |
+
IF prevN<>n
|
179 |
+
THEN
|
180 |
+
BEGIN
|
181 |
+
maxPrimeFactor:=i;
|
182 |
+
PRINT i END;
|
183 |
+
END
|
184 |
+
ELSE END;
|
185 |
+
|
186 |
+
|
187 |
+
{ END
|
188 |
+
ELSE END;
|
189 |
+
i+=1;}
|
190 |
+
END
|
191 |
+
END;
|
192 |
+
|
193 |
+
{END
|
194 |
+
ELSE
|
195 |
+
|
196 |
+
|
197 |
+
|
198 |
+
END;}
|
199 |
+
{maxPrimeFactor:=n;}
|
200 |
+
PRINT "Max Prime Factor of n:" END;
|
201 |
+
PRINT maxPrimeFactor END;
|
202 |
+
END}
|
203 |
+
{Project Euler Problem 4 Largest palindrome product}{
|
204 |
+
{7 second execution time}
|
205 |
+
BEGIN
|
206 |
+
FUNCTION isPalin(num)
|
207 |
+
BEGIN
|
208 |
+
|
209 |
+
pnum:=num;
|
210 |
+
sum:=0;
|
211 |
+
WHILE pnum>0
|
212 |
+
DO
|
213 |
+
BEGIN
|
214 |
+
sum := sum*10+pnum%10;
|
215 |
+
pnum:=pnum//10;
|
216 |
+
END
|
217 |
+
END;
|
218 |
+
RETURN sum=num;
|
219 |
+
|
220 |
+
END;
|
221 |
+
|
222 |
+
i:=999;
|
223 |
+
max:=0;
|
224 |
+
first:=0;second:=0;
|
225 |
+
WHILE i>=900
|
226 |
+
DO
|
227 |
+
BEGIN
|
228 |
+
j:=i;
|
229 |
+
WHILE j>=900
|
230 |
+
DO
|
231 |
+
BEGIN
|
232 |
+
IF isPalin(i*j) && max<i*j
|
233 |
+
THEN
|
234 |
+
BEGIN
|
235 |
+
max:=i*j;
|
236 |
+
first:=i;
|
237 |
+
second:=j;
|
238 |
+
{PRINT max END;}
|
239 |
+
END
|
240 |
+
ELSE END;
|
241 |
+
j:=j-1;
|
242 |
+
END
|
243 |
+
END;
|
244 |
+
i:=i-1;
|
245 |
+
END
|
246 |
+
END;
|
247 |
+
PRINT "Max Palindrome:" END;
|
248 |
+
PRINT max END;
|
249 |
+
PRINT "Constituent Numbers:" END;
|
250 |
+
PRINT first END;
|
251 |
+
PRINT second END;
|
252 |
+
END}
|
253 |
+
{Project Euler Problem 5 Smallest multiple}{
|
254 |
+
BEGIN
|
255 |
+
FUNCTION HCF(first,second)
|
256 |
+
BEGIN
|
257 |
+
IF first<second {first should be kept bigger}
|
258 |
+
THEN
|
259 |
+
BEGIN
|
260 |
+
t:=second;
|
261 |
+
second:=first;
|
262 |
+
first:=t;
|
263 |
+
END
|
264 |
+
ELSE END;
|
265 |
+
WHILE first%second<>0
|
266 |
+
DO
|
267 |
+
BEGIN
|
268 |
+
t:=second;
|
269 |
+
second:=first%second;
|
270 |
+
first:=t;
|
271 |
+
END
|
272 |
+
END;
|
273 |
+
RETURN second;
|
274 |
+
|
275 |
+
END;
|
276 |
+
FUNCTION LCM(f,s)
|
277 |
+
BEGIN
|
278 |
+
RETURN f*s/HCF(f,s);
|
279 |
+
END;
|
280 |
+
i:=2;
|
281 |
+
n:=20; {10->2520; 20->232792560}
|
282 |
+
lcm:=i;
|
283 |
+
WHILE i<n
|
284 |
+
DO
|
285 |
+
BEGIN
|
286 |
+
i+=1;
|
287 |
+
lcm:=LCM(lcm, i);
|
288 |
+
END
|
289 |
+
END;
|
290 |
+
PRINT "Required Smallest Product:" END;
|
291 |
+
PRINT lcm END;
|
292 |
+
|
293 |
+
END}
|
294 |
+
{Project Euler Problem 6 Sum square difference}{
|
295 |
+
BEGIN
|
296 |
+
n:=100; {10->2640; 100->25164150}
|
297 |
+
squareOfSum:=n*(n+1)*n*(n+1)/4;
|
298 |
+
sumOfSquare:=n*(n+1)*(2*n+1)/6;
|
299 |
+
PRINT "Resultant Difference" END;
|
300 |
+
PRINT squareOfSum-sumOfSquare END;
|
301 |
+
END}
|
302 |
+
{Project Euler Problem 9 Special Pythagorean triplet}{
|
303 |
+
BEGIN
|
304 |
+
a:=1;b:=0;c:=0;
|
305 |
+
WHILE a<1000
|
306 |
+
DO
|
307 |
+
BEGIN
|
308 |
+
IF a*a%(1000-a)=0
|
309 |
+
THEN
|
310 |
+
BEGIN
|
311 |
+
b:=((1000-a)-a*a/(1000-a))/2;
|
312 |
+
c:=((1000-a)+a*a/(1000-a))/2;
|
313 |
+
BREAK;
|
314 |
+
END
|
315 |
+
ELSE END;
|
316 |
+
a+=1;
|
317 |
+
END
|
318 |
+
END;
|
319 |
+
PRINT "a,b,c are:" END; {200, 375, 425}
|
320 |
+
PRINT a END;
|
321 |
+
PRINT b END;
|
322 |
+
PRINT c END;
|
323 |
+
END}
|
324 |
+
{Function Testing: Define function within another function, return, use it; almost first class}{
|
325 |
+
BEGIN
|
326 |
+
FUNCTION f2(n)
|
327 |
+
BEGIN
|
328 |
+
RETURN n*n;
|
329 |
+
END;
|
330 |
+
FUNCTION f4(n)
|
331 |
+
BEGIN
|
332 |
+
RETURN n@n;
|
333 |
+
END;
|
334 |
+
FUNCTION f1(f3)
|
335 |
+
BEGIN
|
336 |
+
FUNCTION f11(n)
|
337 |
+
BEGIN
|
338 |
+
RETURN f3(n)*(n-1);
|
339 |
+
{PRINT "f11" END;}
|
340 |
+
END;
|
341 |
+
{PRINT "f1" END;}
|
342 |
+
RETURN f11;
|
343 |
+
END;
|
344 |
+
rf11:=f1(f2);
|
345 |
+
rf12:=f1(f4);
|
346 |
+
rf13:=f2(4);
|
347 |
+
rf14:=6;
|
348 |
+
PRINT rf14 END; {6}
|
349 |
+
PRINT rf13 END; {16}
|
350 |
+
PRINT rf11(5) END; {100}
|
351 |
+
PRINT rf12(3) END; {54}
|
352 |
+
{PRINT f3(3) END; {error}}
|
353 |
+
|
354 |
+
END}
|
355 |
+
{First Class Function Test 2}{
|
356 |
+
BEGIN
|
357 |
+
FUNCTION f4(n)
|
358 |
+
BEGIN
|
359 |
+
RETURN n@n;
|
360 |
+
END;
|
361 |
+
FUNCTION f1(f3)
|
362 |
+
BEGIN
|
363 |
+
FUNCTION f11(n)
|
364 |
+
BEGIN
|
365 |
+
RETURN f3(n)*(n-1);
|
366 |
+
{PRINT "f11" END;}
|
367 |
+
END;
|
368 |
+
{PRINT "f1" END;}
|
369 |
+
RETURN f11;
|
370 |
+
END;
|
371 |
+
|
372 |
+
rf12:=f1(f4);
|
373 |
+
PRINT rf12(3) END; {54}
|
374 |
+
PRINT f1(f4)(3) END; {54}
|
375 |
+
|
376 |
+
END}
|
377 |
+
{First Class Function Test 3}{
|
378 |
+
{BEGIN}
|
379 |
+
FUNCTION f2(n)
|
380 |
+
BEGIN
|
381 |
+
RETURN n*n;
|
382 |
+
END{;}
|
383 |
+
FUNCTION f4(n)
|
384 |
+
BEGIN
|
385 |
+
RETURN n@n;
|
386 |
+
END{;}
|
387 |
+
FUNCTION f5()BEGIN
|
388 |
+
|
389 |
+
FUNCTION f1(f3)
|
390 |
+
BEGIN
|
391 |
+
FUNCTION f11(n)
|
392 |
+
BEGIN
|
393 |
+
RETURN f3(n)*(n-1);
|
394 |
+
{PRINT "f11" END;}
|
395 |
+
END{;}
|
396 |
+
{PRINT "f1" END;}
|
397 |
+
RETURN f11;
|
398 |
+
END{;}
|
399 |
+
RETURN f1;
|
400 |
+
END{;}
|
401 |
+
rf5:=f5();
|
402 |
+
rf51:=rf5(f2);
|
403 |
+
PRINT( rf51(5)) {END}; {100}
|
404 |
+
rf11:=f5()(f4);
|
405 |
+
rf22:=f5();
|
406 |
+
PRINT( rf11(4)) {END}; {768}
|
407 |
+
PRINT (rf22(f4)(3)) {END}; {54}
|
408 |
+
PRINT (f5()(f2)(5)) {END}; {100}
|
409 |
+
|
410 |
+
{END}}
|
411 |
+
{Resolver test; inspired from sir's class }{
|
412 |
+
BEGIN
|
413 |
+
FUNCTION foo(a)
|
414 |
+
BEGIN
|
415 |
+
IF FALSE
|
416 |
+
THEN RETURN foo(a) {infinite loop}
|
417 |
+
ELSE RETURN a-2
|
418 |
+
END;
|
419 |
+
END;
|
420 |
+
g:=foo;
|
421 |
+
FUNCTION foo(a)
|
422 |
+
BEGIN
|
423 |
+
RETURN a+5;
|
424 |
+
END;
|
425 |
+
h:=foo;
|
426 |
+
PRINT g(0) END;
|
427 |
+
PRINT h(1) END;
|
428 |
+
|
429 |
+
END}
|
430 |
+
{resolver test 2}{
|
431 |
+
BEGIN
|
432 |
+
i:=1;
|
433 |
+
s:=i; {1}
|
434 |
+
a:=2;
|
435 |
+
i:=a; {2}
|
436 |
+
s:=a@i@a; {16}
|
437 |
+
n:=s; {16}
|
438 |
+
IF i< n
|
439 |
+
THEN BEGIN
|
440 |
+
b:=n;
|
441 |
+
PRINT n END;
|
442 |
+
WHILE i+b-25 < 10
|
443 |
+
DO
|
444 |
+
BEGIN
|
445 |
+
n:=i*b/a-n%i;
|
446 |
+
PRINT n END;
|
447 |
+
i+=i;
|
448 |
+
END
|
449 |
+
END;
|
450 |
+
END
|
451 |
+
ELSE
|
452 |
+
{n:=a;}
|
453 |
+
PRINT n END
|
454 |
+
|
455 |
+
END;
|
456 |
+
PRINT i END;
|
457 |
+
PRINT a END;
|
458 |
+
PRINT s END;
|
459 |
+
END}
|
460 |
+
{Mutual Recursion Testing}{
|
461 |
+
BEGIN
|
462 |
+
FUNCTION even(n)
|
463 |
+
BEGIN
|
464 |
+
IF n = 0
|
465 |
+
THEN RETURN TRUE
|
466 |
+
ELSE END;
|
467 |
+
IF n = 1
|
468 |
+
THEN RETURN FALSE
|
469 |
+
ELSE END;
|
470 |
+
RETURN odd(n-1);
|
471 |
+
END;
|
472 |
+
FUNCTION odd(m)
|
473 |
+
BEGIN
|
474 |
+
IF m = 0
|
475 |
+
THEN RETURN FALSE
|
476 |
+
ELSE END;
|
477 |
+
IF m = 1
|
478 |
+
THEN RETURN TRUE
|
479 |
+
ELSE END;
|
480 |
+
RETURN even(m-1);
|
481 |
+
END;
|
482 |
+
PRINT even(5) END;
|
483 |
+
PRINT odd(4) END;
|
484 |
+
END}
|
485 |
+
{Mutual Recursion Testing 2}{
|
486 |
+
|
487 |
+
FUNCTION even(n)
|
488 |
+
BEGIN
|
489 |
+
IF n = 0
|
490 |
+
THEN RETURN TRUE;
|
491 |
+
ELSE END
|
492 |
+
IF n = 1
|
493 |
+
THEN RETURN FALSE;
|
494 |
+
ELSE END
|
495 |
+
RETURN odd(n-1);
|
496 |
+
END
|
497 |
+
FUNCTION odd(m)
|
498 |
+
BEGIN
|
499 |
+
PRINT ("1st Odd") ;
|
500 |
+
IF m = 0
|
501 |
+
THEN RETURN FALSE;
|
502 |
+
ELSE END
|
503 |
+
IF m = 1
|
504 |
+
THEN RETURN TRUE;
|
505 |
+
ELSE END
|
506 |
+
RETURN even(m-1);
|
507 |
+
END
|
508 |
+
PRINT (even(42)) ;
|
509 |
+
PRINT (odd(157)) ;
|
510 |
+
FUNCTION odd(m)
|
511 |
+
BEGIN
|
512 |
+
PRINT ("2nd Odd") ;
|
513 |
+
IF m = 0
|
514 |
+
THEN RETURN FALSE;
|
515 |
+
ELSE END
|
516 |
+
IF m = 1
|
517 |
+
THEN RETURN TRUE;
|
518 |
+
ELSE END
|
519 |
+
RETURN even(m-1);
|
520 |
+
END
|
521 |
+
PRINT (even(5)) ;
|
522 |
+
PRINT (odd(4)) ;
|
523 |
+
}
|
524 |
+
{Function binding Testing}{
|
525 |
+
BEGIN
|
526 |
+
FUNCTION add(a,b)
|
527 |
+
BEGIN
|
528 |
+
c:=a+b;
|
529 |
+
RETURN dummy(c);
|
530 |
+
END;
|
531 |
+
FUNCTION dummy(a)
|
532 |
+
BEGIN
|
533 |
+
RETURN a;
|
534 |
+
END;
|
535 |
+
PRINT add(7,5) END;
|
536 |
+
END}
|
537 |
+
{print test}{
|
538 |
+
BEGIN
|
539 |
+
a:=1;
|
540 |
+
PRINT a END;
|
541 |
+
END}
|
542 |
+
|
543 |
+
{multiple ifelse testing}{
|
544 |
+
BEGIN
|
545 |
+
n:=0;
|
546 |
+
a:=0;
|
547 |
+
IF n = 0
|
548 |
+
THEN a:=1
|
549 |
+
ELSE END;
|
550 |
+
IF n = 1
|
551 |
+
THEN a:=0
|
552 |
+
ELSE END;
|
553 |
+
IF n = 2
|
554 |
+
THEN a:=2
|
555 |
+
ELSE END;
|
556 |
+
PRINT a END;
|
557 |
+
END}
|
558 |
+
|
559 |
+
{multiple ifelse to test return working}{
|
560 |
+
BEGIN
|
561 |
+
FUNCTION add(n)
|
562 |
+
BEGIN
|
563 |
+
IF n = 0
|
564 |
+
THEN RETURN 1
|
565 |
+
ELSE END;
|
566 |
+
IF n = 1
|
567 |
+
THEN RETURN 0
|
568 |
+
ELSE END;
|
569 |
+
IF n = 2
|
570 |
+
THEN RETURN 2
|
571 |
+
ELSE END;
|
572 |
+
END;
|
573 |
+
PRINT add(0) END;
|
574 |
+
END}
|
575 |
+
|
576 |
+
{case 3}{
|
577 |
+
BEGIN
|
578 |
+
p:=1;
|
579 |
+
q:=1;
|
580 |
+
FOR i:= 10 ; ; i := i - 1
|
581 |
+
DO
|
582 |
+
BEGIN
|
583 |
+
q:=q*p;
|
584 |
+
p:=p+1;
|
585 |
+
{PRINT p END;}
|
586 |
+
PRINT q END;
|
587 |
+
PRINT i END;
|
588 |
+
IF i <= 0
|
589 |
+
THEN
|
590 |
+
BEGIN
|
591 |
+
BREAK;
|
592 |
+
END
|
593 |
+
ELSE
|
594 |
+
END
|
595 |
+
END
|
596 |
+
END;
|
597 |
+
END}
|
598 |
+
{Project Euler Problem 12 Highly divisible triangular number}{
|
599 |
+
BEGIN
|
600 |
+
|
601 |
+
n:=500; {5->28,6, time: 0.018s ; 500->}
|
602 |
+
sum:=0;
|
603 |
+
max:=sum;
|
604 |
+
i:=1;
|
605 |
+
num:=1;
|
606 |
+
WHILE sum<=n
|
607 |
+
DO
|
608 |
+
BEGIN
|
609 |
+
sum:=1;
|
610 |
+
num:=i*(i+1)/2;
|
611 |
+
j:=1;
|
612 |
+
WHILE {j<num@(1/2)} j<=num/2
|
613 |
+
DO
|
614 |
+
BEGIN
|
615 |
+
IF num%j = 0
|
616 |
+
THEN
|
617 |
+
BEGIN
|
618 |
+
sum+=1;
|
619 |
+
END
|
620 |
+
ELSE END;
|
621 |
+
j+=1;
|
622 |
+
END
|
623 |
+
END;
|
624 |
+
|
625 |
+
{IF num = num@(1/2) * num@(1/2)
|
626 |
+
THEN
|
627 |
+
BEGIN
|
628 |
+
sum+=1;
|
629 |
+
END
|
630 |
+
ELSE END;}
|
631 |
+
|
632 |
+
IF max<sum
|
633 |
+
THEN
|
634 |
+
BEGIN
|
635 |
+
max:=sum;
|
636 |
+
PRINT i END;
|
637 |
+
PRINT sum END;
|
638 |
+
END
|
639 |
+
ELSE END;
|
640 |
+
i+=1;
|
641 |
+
|
642 |
+
END
|
643 |
+
END;
|
644 |
+
PRINT "Required Number:" END;
|
645 |
+
PRINT num END;
|
646 |
+
PRINT "No of factors of above number:" END;
|
647 |
+
PRINT sum END;
|
648 |
+
PRINT "No of factors to be exceeded:" END;
|
649 |
+
PRINT n END;
|
650 |
+
END}
|
651 |
+
{Token/Parser Test for not accepting ** and other such operators/tokens}{
|
652 |
+
BEGIN
|
653 |
+
a:=1;
|
654 |
+
b:=2;
|
655 |
+
c:=b**03;
|
656 |
+
PRINT c END;
|
657 |
+
END}
|
658 |
+
{Project Euler Problem 30 Digit fifth powers}{
|
659 |
+
BEGIN
|
660 |
+
sum := 0;
|
661 |
+
FOR i := 0; i <= 7*9*9*9*9*9*9; i := i + 1
|
662 |
+
DO
|
663 |
+
BEGIN
|
664 |
+
newsum := 0;
|
665 |
+
reduce := i;
|
666 |
+
WHILE reduce > 0
|
667 |
+
DO
|
668 |
+
BEGIN
|
669 |
+
digit := reduce % 10;
|
670 |
+
reduce := reduce // 10;
|
671 |
+
power := 1;
|
672 |
+
FOR j := 1; j <= 5; j+=1
|
673 |
+
DO
|
674 |
+
BEGIN
|
675 |
+
power := power * digit;
|
676 |
+
END
|
677 |
+
END;
|
678 |
+
newsum := newsum + power;
|
679 |
+
END
|
680 |
+
END;
|
681 |
+
IF newsum = i
|
682 |
+
THEN sum := sum + i
|
683 |
+
ELSE END;
|
684 |
+
END
|
685 |
+
END;
|
686 |
+
PRINT sum END;
|
687 |
+
END}
|
688 |
+
|
689 |
+
|
690 |
+
{test1}{
|
691 |
+
BEGIN
|
692 |
+
a:=0;
|
693 |
+
BEGIN
|
694 |
+
a:=1;
|
695 |
+
PRINT a END;
|
696 |
+
END;
|
697 |
+
PRINT a END;
|
698 |
+
END}
|
699 |
+
{output: 1,1}
|
700 |
+
|
701 |
+
{test2}{
|
702 |
+
BEGIN
|
703 |
+
FUNCTION foo()
|
704 |
+
BEGIN
|
705 |
+
PRINT a END;
|
706 |
+
END;
|
707 |
+
a:=1;
|
708 |
+
PRINT foo() END;
|
709 |
+
END}
|
710 |
+
{output: 1}
|
711 |
+
{Looks matter}{
|
712 |
+
a:=1;
|
713 |
+
PRINT("1st");
|
714 |
+
PRINT (a) ;
|
715 |
+
|
716 |
+
IF a = 1
|
717 |
+
THEN
|
718 |
+
BEGIN
|
719 |
+
PRINT("2nd");
|
720 |
+
PRINT (a) ;
|
721 |
+
END
|
722 |
+
ELSE
|
723 |
+
END
|
724 |
+
WHILE a < 10
|
725 |
+
DO
|
726 |
+
BEGIN
|
727 |
+
|
728 |
+
a:=a+1;
|
729 |
+
|
730 |
+
END
|
731 |
+
|
732 |
+
END
|
733 |
+
PRINT("3rd");
|
734 |
+
PRINT( a);
|
735 |
+
FUNCTION foo()
|
736 |
+
BEGIN
|
737 |
+
PRINT (a) ;
|
738 |
+
END
|
739 |
+
PRINT("4th");
|
740 |
+
{PRINT (foo()) ;}
|
741 |
+
foo();
|
742 |
+
BEGIN
|
743 |
+
a:=4;
|
744 |
+
PRINT("5th");
|
745 |
+
PRINT (a) ;
|
746 |
+
|
747 |
+
END}
|
748 |
+
{Looks matter 2}{
|
749 |
+
|
750 |
+
a:=1;
|
751 |
+
PRINT("1st");
|
752 |
+
PRINT (a) ;
|
753 |
+
IF a = 1
|
754 |
+
THEN
|
755 |
+
BEGIN
|
756 |
+
PRINT("2nd");
|
757 |
+
PRINT (a) ;
|
758 |
+
END
|
759 |
+
ELSE IF a = 2
|
760 |
+
THEN
|
761 |
+
PRINT("2.5nd");
|
762 |
+
ELSE
|
763 |
+
PRINT("2.75nd");
|
764 |
+
|
765 |
+
END
|
766 |
+
WHILE a < 10
|
767 |
+
DO
|
768 |
+
a:=a+1;
|
769 |
+
END
|
770 |
+
PRINT("3rd");
|
771 |
+
PRINT( a);
|
772 |
+
c:=1;
|
773 |
+
b:=c+1;
|
774 |
+
PRINT(b);
|
775 |
+
b:=b+1;
|
776 |
+
PRINT(b);
|
777 |
+
}
|
778 |
+
|
779 |
+
|
int_array_test.txt
ADDED
@@ -0,0 +1,28 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{BEGIN
|
2 |
+
|
3 |
+
x:= " BHAVINI";
|
4 |
+
T := LIST:INTEGER[~1,~3,~4, ~2, ~7];
|
5 |
+
PRINT T END;
|
6 |
+
|
7 |
+
APPEND(T, ~8);
|
8 |
+
|
9 |
+
PRINT LEN(T) END;
|
10 |
+
|
11 |
+
y := T[0];
|
12 |
+
|
13 |
+
PRINT T END;
|
14 |
+
PRINT y END;
|
15 |
+
|
16 |
+
END}
|
17 |
+
x:= " BHAVINI";
|
18 |
+
T := LIST:INTEGER[~1,~3,~4, ~2, ~7];
|
19 |
+
PRINT (T );
|
20 |
+
|
21 |
+
APPEND(T, ~8);
|
22 |
+
|
23 |
+
PRINT( LEN(T)) ;
|
24 |
+
|
25 |
+
y := T[0];
|
26 |
+
|
27 |
+
PRINT (T );
|
28 |
+
PRINT (y );
|
lexer.py
ADDED
@@ -0,0 +1,427 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from dataclasses import dataclass
|
2 |
+
import sys
|
3 |
+
|
4 |
+
# punctuators
|
5 |
+
EOF = 'EOF'
|
6 |
+
ID = 'ID'
|
7 |
+
FRACTION_CONST= 'FRACTION_CONST'
|
8 |
+
INTEGER_CONST = 'INTEGER_CONST'
|
9 |
+
REAL_CONST = 'REAL_CONST'
|
10 |
+
LPAREN = 'LPAREN'
|
11 |
+
RPAREN = 'RPAREN'
|
12 |
+
SEMI = 'SEMI'
|
13 |
+
DOT = 'DOT'
|
14 |
+
COLON = 'COLON'
|
15 |
+
COMMA = 'COMMA'
|
16 |
+
LSPAREN = "LSPAREN"
|
17 |
+
RSPAREN = "RSPAREN"
|
18 |
+
|
19 |
+
# operators
|
20 |
+
ASSIGN = 'ASSIGN'
|
21 |
+
PLUS = 'PLUS'
|
22 |
+
MINUS = 'MINUS'
|
23 |
+
MUL = 'MUL'
|
24 |
+
FLOAT_DIV = 'FLOAT_DIV'
|
25 |
+
INT_DIV = 'INT_DIV'
|
26 |
+
EQEQ = 'EQEQ'
|
27 |
+
NOTEQ = 'NOTEQ'
|
28 |
+
GT = 'GT'
|
29 |
+
LT = 'LT'
|
30 |
+
GTEQ = 'GTEQ'
|
31 |
+
LTEQ = 'LTEQ'
|
32 |
+
MODULO = 'MODULO'
|
33 |
+
AND = "AND"
|
34 |
+
OR = "OR"
|
35 |
+
PLUSEQ = 'PLUSEQ'
|
36 |
+
MINUSEQ = 'MINUSEQ'
|
37 |
+
POWEREQ = 'POWEREQ'
|
38 |
+
MULEQ = 'MULEQ'
|
39 |
+
FLOAT_DIVEQ = "FLOAT_DIVEQ"
|
40 |
+
POWER = 'POWER'
|
41 |
+
|
42 |
+
# keywords
|
43 |
+
PROGRAM = 'PROGRAM'
|
44 |
+
VAR = 'VAR'
|
45 |
+
INTEGER = 'INTEGER'
|
46 |
+
REAL = 'REAL'
|
47 |
+
INTEGER_DIV = 'INTEGER_DIV'
|
48 |
+
NONE = 'NONE'
|
49 |
+
READ = 'READ'
|
50 |
+
WRITE = 'WRITE'
|
51 |
+
BEGIN = 'BEGIN'
|
52 |
+
END = 'END'
|
53 |
+
IF = 'IF'
|
54 |
+
THEN = 'THEN'
|
55 |
+
ELSE = 'ELSE'
|
56 |
+
WHILE = 'WHILE'
|
57 |
+
DO = 'DO'
|
58 |
+
PRINT = 'PRINT'
|
59 |
+
STRING = 'STRING'
|
60 |
+
FUNCTION = 'FUNCTION'
|
61 |
+
RETURN = 'RETURN'
|
62 |
+
FOR = 'FOR'
|
63 |
+
RANGE = "RANGE"
|
64 |
+
BY = "BY"
|
65 |
+
TO = "TO"
|
66 |
+
BREAK = "BREAK"
|
67 |
+
INC = "INC"
|
68 |
+
DEC = "DEC"
|
69 |
+
LEN = "LEN"
|
70 |
+
LIST = "LIST"
|
71 |
+
APPEND = "APPEND"
|
72 |
+
POP = "POP"
|
73 |
+
HEAD = "HEAD"
|
74 |
+
TAIL = "TAIL"
|
75 |
+
ISEMPTY = "ISEMPTY"
|
76 |
+
|
77 |
+
|
78 |
+
# literals
|
79 |
+
TRUE = "TRUE"
|
80 |
+
FALSE = "FALSE"
|
81 |
+
|
82 |
+
@dataclass
|
83 |
+
# class to store the token types and values
|
84 |
+
class Token:
|
85 |
+
type: str
|
86 |
+
value: object
|
87 |
+
|
88 |
+
def __str__(self):
|
89 |
+
return 'Token({type}, {value})'.format(
|
90 |
+
type=self.type,
|
91 |
+
value=repr(self.value)
|
92 |
+
)
|
93 |
+
|
94 |
+
def __repr__(self):
|
95 |
+
return self.__str__()
|
96 |
+
|
97 |
+
KEYWORDS = {
|
98 |
+
'PROGRAM': Token('PROGRAM', 'PROGRAM'),
|
99 |
+
'VAR': Token('VAR', 'VAR'),
|
100 |
+
'INTEGER': Token('INTEGER', 'INTEGER'),
|
101 |
+
'REAL': Token('REAL', 'REAL'),
|
102 |
+
'DIV': Token('INTEGER_DIV', 'DIV'),
|
103 |
+
'BEGIN': Token('BEGIN', 'BEGIN'),
|
104 |
+
'END': Token('END', 'END'),
|
105 |
+
'FOR': Token('FOR', 'FOR'),
|
106 |
+
'TRUE': Token('TRUE', True),
|
107 |
+
'FALSE': Token('FALSE', False),
|
108 |
+
'IF': Token('IF', 'IF'),
|
109 |
+
'THEN': Token('THEN', 'THEN'),
|
110 |
+
'ELSE': Token('ELSE', 'ELSE'),
|
111 |
+
'PRINT': Token('PRINT', 'PRINT'),
|
112 |
+
'WHILE': Token('WHILE', 'WHILE'),
|
113 |
+
'DO': Token('DO', 'DO'),
|
114 |
+
'STRING': Token('STRING', 'STRING'),
|
115 |
+
'FUNCTION': Token('FUNCTION', 'FUNCTION'),
|
116 |
+
'RETURN': Token('RETURN', 'RETURN'),
|
117 |
+
'BY': Token('BY', 'BY'),
|
118 |
+
'TO': Token("TO", "TO"),
|
119 |
+
'BREAK': Token("BREAK", "BREAK"),
|
120 |
+
"INC" : Token("INC", "INC"),
|
121 |
+
"DEC" : Token("DEC","DEC"),
|
122 |
+
"LEN" : Token("LEN", "LEN"),
|
123 |
+
"LIST" : Token("LIST", "LIST"),
|
124 |
+
"NONE" : Token("NONE", "NONE"),
|
125 |
+
"APPEND" : Token("APPEND", "APPEND"),
|
126 |
+
"POP" : Token("POP", "POP"),
|
127 |
+
"HEAD" : Token("HEAD", "HEAD"),
|
128 |
+
"TAIL" : Token("TAIL", "TAIL"),
|
129 |
+
"ISEMPTY" : Token("ISEMPTY", "ISEMPTY")
|
130 |
+
# 'PRINT': Token('PRINT', ';'),
|
131 |
+
|
132 |
+
}
|
133 |
+
|
134 |
+
|
135 |
+
class Lexer(object):
|
136 |
+
def __init__(self, text):
|
137 |
+
|
138 |
+
self.text = text # stream of input
|
139 |
+
self.pos = 0 # current position in the stream
|
140 |
+
self.lineNum = 1 # line number in code
|
141 |
+
self.curLinePos = 0 # current position in current line of program
|
142 |
+
if text == "":
|
143 |
+
print("Empty Program")
|
144 |
+
self.curChar = None
|
145 |
+
|
146 |
+
else:
|
147 |
+
self.curChar = self.text[self.pos] # current character in the stream
|
148 |
+
self.curLine = self.curChar # current line of program read till now
|
149 |
+
|
150 |
+
|
151 |
+
def error(self):
|
152 |
+
print("Current Character", self.curChar)
|
153 |
+
sys.exit('Invalid character')
|
154 |
+
|
155 |
+
def nextChar(self): # advances the pos pointer
|
156 |
+
self.pos += 1
|
157 |
+
self.curLinePos += 1
|
158 |
+
|
159 |
+
if self.pos > len(self.text) - 1: # end of input stream
|
160 |
+
self.curChar = None
|
161 |
+
else:
|
162 |
+
self.curChar = self.text[self.pos]
|
163 |
+
self.curLine += self.curChar
|
164 |
+
if self.curChar == '\n':
|
165 |
+
self.lineNum+=1
|
166 |
+
self.curLine=""
|
167 |
+
self.curLinePos=0
|
168 |
+
|
169 |
+
|
170 |
+
def peek(self): # returns the lookahead character
|
171 |
+
if self.pos + 1 > len(self.text) - 1:
|
172 |
+
return None
|
173 |
+
else:
|
174 |
+
return self.text[self.pos + 1]
|
175 |
+
|
176 |
+
def skipSpaces(self): # to skip white spacses
|
177 |
+
while self.curChar is not None and self.curChar.isspace():
|
178 |
+
# if self.curChar == '\n':
|
179 |
+
# self.lineNum+=1
|
180 |
+
# self.curLine=""
|
181 |
+
# self.curLinePos=0
|
182 |
+
self.nextChar()
|
183 |
+
|
184 |
+
def skipComments(self):
|
185 |
+
# while self.curChar != '}':
|
186 |
+
# self.nextChar()
|
187 |
+
# self.nextChar() # to skip the closing curly brace as well
|
188 |
+
noOfstartBraces = 1
|
189 |
+
while noOfstartBraces != 0 :
|
190 |
+
self.nextChar()
|
191 |
+
if self.curChar == '{':
|
192 |
+
noOfstartBraces+=1
|
193 |
+
elif self.curChar == '}':
|
194 |
+
noOfstartBraces-=1
|
195 |
+
# self.skipSpaces()
|
196 |
+
|
197 |
+
self.nextChar() # to skip the closing curly brace as well
|
198 |
+
|
199 |
+
def scanSolution(self):
|
200 |
+
result = ''
|
201 |
+
while self.curChar != '$':
|
202 |
+
result += self.curChar
|
203 |
+
self.nextChar()
|
204 |
+
sys.stdout = open("solution.txt", "w")
|
205 |
+
print(result)
|
206 |
+
sys.stdout = sys.__stdout__
|
207 |
+
self.nextChar()
|
208 |
+
|
209 |
+
def intlex(self):
|
210 |
+
# Consume all the consecutive digits and decimal if present.
|
211 |
+
result = ''
|
212 |
+
while self.curChar is not None and self.curChar.isdigit():
|
213 |
+
result += self.curChar
|
214 |
+
self.nextChar()
|
215 |
+
|
216 |
+
token = Token('INTEGER_CONST', int(result))
|
217 |
+
return token
|
218 |
+
|
219 |
+
def number(self):
|
220 |
+
# Consume all the consecutive digits and decimal if present.
|
221 |
+
result = ''
|
222 |
+
while self.curChar is not None and self.curChar.isdigit():
|
223 |
+
result += self.curChar
|
224 |
+
self.nextChar()
|
225 |
+
|
226 |
+
if self.curChar == '.':
|
227 |
+
result += self.curChar
|
228 |
+
self.nextChar()
|
229 |
+
|
230 |
+
while (
|
231 |
+
self.curChar is not None and
|
232 |
+
self.curChar.isdigit()
|
233 |
+
):
|
234 |
+
result += self.curChar
|
235 |
+
self.nextChar()
|
236 |
+
|
237 |
+
token = Token('REAL_CONST', float(result))
|
238 |
+
else:
|
239 |
+
token = Token('FRACTION_CONST', int(result))
|
240 |
+
|
241 |
+
return token
|
242 |
+
|
243 |
+
def _id(self):
|
244 |
+
# Handles identifiers and reserved keywords
|
245 |
+
result = ''
|
246 |
+
while self.curChar is not None and self.curChar.isalnum():
|
247 |
+
result += self.curChar
|
248 |
+
self.nextChar()
|
249 |
+
|
250 |
+
token = KEYWORDS.get(result, Token(ID, result))
|
251 |
+
return token
|
252 |
+
|
253 |
+
def Stringlex(self):
|
254 |
+
# Handles strings
|
255 |
+
result = ''
|
256 |
+
while self.curChar != '"':
|
257 |
+
result += self.curChar
|
258 |
+
self.nextChar()
|
259 |
+
|
260 |
+
self.nextChar()
|
261 |
+
token = Token('STRING', result)
|
262 |
+
return token
|
263 |
+
|
264 |
+
def get_token(self):
|
265 |
+
# returns the token and token type
|
266 |
+
while self.curChar is not None:
|
267 |
+
|
268 |
+
if self.curChar.isspace():
|
269 |
+
self.skipSpaces()
|
270 |
+
continue
|
271 |
+
|
272 |
+
if self.curChar == '{':
|
273 |
+
self.nextChar()
|
274 |
+
self.skipComments()
|
275 |
+
continue
|
276 |
+
|
277 |
+
if self.curChar == '$':
|
278 |
+
self.nextChar()
|
279 |
+
self.scanSolution()
|
280 |
+
continue
|
281 |
+
|
282 |
+
if self.curChar == '~':
|
283 |
+
if self.peek().isdigit():
|
284 |
+
self.nextChar()
|
285 |
+
return self.intlex()
|
286 |
+
|
287 |
+
if self.curChar.isalpha():
|
288 |
+
return self._id()
|
289 |
+
|
290 |
+
if self.curChar.isdigit():
|
291 |
+
return self.number()
|
292 |
+
|
293 |
+
if self.curChar == ':':
|
294 |
+
if self.peek() == '=':
|
295 |
+
self.nextChar()
|
296 |
+
self.nextChar()
|
297 |
+
return Token(ASSIGN, '=') # :=
|
298 |
+
else:
|
299 |
+
self.nextChar()
|
300 |
+
return Token(COLON, ':')
|
301 |
+
|
302 |
+
if self.curChar == "|":
|
303 |
+
if self.peek() == "|":
|
304 |
+
self.nextChar()
|
305 |
+
self.nextChar()
|
306 |
+
return Token(OR, "||")
|
307 |
+
|
308 |
+
|
309 |
+
if self.curChar == "&":
|
310 |
+
if self.peek() == "&":
|
311 |
+
self.nextChar()
|
312 |
+
self.nextChar()
|
313 |
+
return Token(AND, "&&")
|
314 |
+
|
315 |
+
if self.curChar == '>':
|
316 |
+
if self.peek() == '=':
|
317 |
+
self.nextChar()
|
318 |
+
self.nextChar()
|
319 |
+
return Token(GTEQ, '>=')
|
320 |
+
else:
|
321 |
+
self.nextChar()
|
322 |
+
return Token(GT, '>')
|
323 |
+
|
324 |
+
if self.curChar == '<':
|
325 |
+
if self.peek() == '=':
|
326 |
+
self.nextChar()
|
327 |
+
self.nextChar()
|
328 |
+
return Token(LTEQ, '<=')
|
329 |
+
elif self.peek() == '>':
|
330 |
+
self.nextChar()
|
331 |
+
self.nextChar()
|
332 |
+
return Token(NOTEQ, '!=') # <>
|
333 |
+
else:
|
334 |
+
self.nextChar()
|
335 |
+
return Token(LT, '<')
|
336 |
+
|
337 |
+
if self.curChar == '@':
|
338 |
+
if self.peek() == '=':
|
339 |
+
self.nextChar()
|
340 |
+
self.nextChar()
|
341 |
+
return Token(POWEREQ, '**=')
|
342 |
+
else:
|
343 |
+
self.nextChar()
|
344 |
+
return Token(POWER, '**')
|
345 |
+
|
346 |
+
if self.curChar == "%":
|
347 |
+
self.nextChar()
|
348 |
+
return Token(MODULO, '%')
|
349 |
+
|
350 |
+
if self.curChar == '=':
|
351 |
+
self.nextChar()
|
352 |
+
return Token(EQEQ, '==') # =
|
353 |
+
|
354 |
+
if self.curChar == '+':
|
355 |
+
if self.peek() == '=':
|
356 |
+
self.nextChar()
|
357 |
+
self.nextChar()
|
358 |
+
return Token(PLUSEQ, '+=')
|
359 |
+
else:
|
360 |
+
self.nextChar()
|
361 |
+
return Token(PLUS, '+')
|
362 |
+
|
363 |
+
if self.curChar == '-':
|
364 |
+
if self.peek() == '=':
|
365 |
+
self.nextChar()
|
366 |
+
self.nextChar()
|
367 |
+
return Token(MINUSEQ, '-=')
|
368 |
+
else:
|
369 |
+
self.nextChar()
|
370 |
+
return Token(MINUS, '-')
|
371 |
+
|
372 |
+
if self.curChar == '*':
|
373 |
+
if self.peek() == '=':
|
374 |
+
self.nextChar()
|
375 |
+
self.nextChar()
|
376 |
+
return Token(MULEQ, '*=')
|
377 |
+
else:
|
378 |
+
self.nextChar()
|
379 |
+
return Token(MUL, '*')
|
380 |
+
|
381 |
+
if self.curChar == '/':
|
382 |
+
if self.peek() == "=":
|
383 |
+
self.nextChar()
|
384 |
+
self.nextChar()
|
385 |
+
return Token(FLOAT_DIVEQ, '/=')
|
386 |
+
if self.peek() == "/":
|
387 |
+
self.nextChar()
|
388 |
+
self.nextChar()
|
389 |
+
return Token(INT_DIV, '//')
|
390 |
+
else:
|
391 |
+
self.nextChar()
|
392 |
+
return Token(FLOAT_DIV, '/')
|
393 |
+
|
394 |
+
if self.curChar == '(':
|
395 |
+
self.nextChar()
|
396 |
+
return Token(LPAREN, '(')
|
397 |
+
|
398 |
+
if self.curChar == ')':
|
399 |
+
self.nextChar()
|
400 |
+
return Token(RPAREN, ')')
|
401 |
+
|
402 |
+
if self.curChar == ';':
|
403 |
+
self.nextChar()
|
404 |
+
return Token(SEMI, ';')
|
405 |
+
|
406 |
+
if self.curChar == '.':
|
407 |
+
self.nextChar()
|
408 |
+
return Token(DOT, '.')
|
409 |
+
|
410 |
+
if self.curChar == ',':
|
411 |
+
self.nextChar()
|
412 |
+
return Token(COMMA, ',')
|
413 |
+
|
414 |
+
if self.curChar == '"':
|
415 |
+
self.nextChar()
|
416 |
+
return self.Stringlex()
|
417 |
+
|
418 |
+
if self.curChar == '[':
|
419 |
+
self.nextChar()
|
420 |
+
return Token(LSPAREN, '[')
|
421 |
+
|
422 |
+
if self.curChar == ']':
|
423 |
+
self.nextChar()
|
424 |
+
return Token(RSPAREN, ']')
|
425 |
+
self.error()
|
426 |
+
|
427 |
+
return Token(EOF, None)
|
lexer_input.txt
ADDED
@@ -0,0 +1,25 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
PROGRAM lexercheck;
|
2 |
+
VAR
|
3 |
+
a : INTEGER;
|
4 |
+
b : INTEGER;
|
5 |
+
c : INTEGER;
|
6 |
+
x : REAL;
|
7 |
+
y : REAL;
|
8 |
+
|
9 |
+
BEGIN
|
10 |
+
IF (x = y)
|
11 |
+
THEN
|
12 |
+
a:= 5
|
13 |
+
z:= "happy"
|
14 |
+
|
15 |
+
{ this is a comment}
|
16 |
+
BEGIN
|
17 |
+
BEGIN
|
18 |
+
a := 4------3;
|
19 |
+
b := 5 * a
|
20 |
+
c := b DIV 4
|
21 |
+
END;
|
22 |
+
x := 1.1;
|
23 |
+
y := x / 4
|
24 |
+
END.
|
25 |
+
{ program is over}
|
lexer_test.py
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from lexer import *
|
2 |
+
|
3 |
+
def main():
|
4 |
+
|
5 |
+
text = open("lexer_input.txt","r").read()
|
6 |
+
# text = "2 + 3 "
|
7 |
+
|
8 |
+
lexer = Lexer(text)
|
9 |
+
Token = lexer.get_token()
|
10 |
+
while Token.type != EOF:
|
11 |
+
# print(Token.value, Token.type)
|
12 |
+
print(Token.__str__())
|
13 |
+
Token = lexer.get_token()
|
14 |
+
print(Token.value, Token.type) # to check EOF
|
15 |
+
|
16 |
+
main()
|
requirements.txt
ADDED
@@ -0,0 +1,2 @@
|
|
|
|
|
|
|
1 |
+
streamlit
|
2 |
+
watchdog
|
resolved_tree
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Resolved Tree:
|
2 |
+
Seq(statements=[Statement(command='print',
|
3 |
+
statement=BinOp(operator='+',
|
4 |
+
left=NumLiteral(value=Fraction(3, 1)),
|
5 |
+
right=NumLiteral(value=Fraction(4, 1))))])
|
resolver.py
ADDED
@@ -0,0 +1,243 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from dataclasses_sim import *
|
2 |
+
|
3 |
+
lateBinding = {}
|
4 |
+
def resolve(program: AST, environment: Environment = None) -> AST:
|
5 |
+
if environment is None:
|
6 |
+
environment = Environment()
|
7 |
+
environment.program = program
|
8 |
+
def resolve_(program: AST) -> AST:
|
9 |
+
return resolve(program, environment)
|
10 |
+
|
11 |
+
match program:
|
12 |
+
case IntLiteral(_) as I:
|
13 |
+
return I
|
14 |
+
case NumLiteral(_) as N:
|
15 |
+
return N
|
16 |
+
case BoolLiteral(_) as B:
|
17 |
+
return B
|
18 |
+
case StringLiteral(_) as SL:
|
19 |
+
return SL
|
20 |
+
case BinOp("=" as aop, MutVar(name) as m, right) :
|
21 |
+
r = resolve_(right)
|
22 |
+
if not environment.check(name):
|
23 |
+
environment.add(name, m)
|
24 |
+
else:
|
25 |
+
environment.update(name, m)
|
26 |
+
# environment.enter_scope()
|
27 |
+
m = resolve_(m)
|
28 |
+
mutvar = environment.get(name)
|
29 |
+
# r = resolve_(right)
|
30 |
+
mutvar.put(r)
|
31 |
+
|
32 |
+
# environment.exit_scope()
|
33 |
+
return BinOp(aop, m, r)
|
34 |
+
case BinOp("+="as aop, MutVar(name)as m, right) | BinOp("-="as aop, MutVar(name)as m, right) | BinOp("/="as aop, MutVar(name)as m, right) | BinOp("*="as aop, MutVar(name)as m, right) | BinOp("**="as aop, MutVar(name)as m, right):
|
35 |
+
r = resolve_(right)
|
36 |
+
if not environment.check(name):
|
37 |
+
environment.add(name, m)
|
38 |
+
# environment.enter_scope()
|
39 |
+
m = resolve_(m)
|
40 |
+
mutvar = environment.get(name)
|
41 |
+
# r = resolve_(right)
|
42 |
+
mutvar.put(r)
|
43 |
+
|
44 |
+
# environment.exit_scope()
|
45 |
+
return BinOp(aop, m, r)
|
46 |
+
case BinOp(o, left, right):
|
47 |
+
return BinOp(o, resolve_(left), resolve_(right))
|
48 |
+
case UnOp(o, mid):
|
49 |
+
return UnOp(o, resolve_(mid))
|
50 |
+
case Variable(name):
|
51 |
+
return environment.get(name)
|
52 |
+
case MutVar(name) as m :
|
53 |
+
if not environment.check(name):
|
54 |
+
environment.add(name, m)
|
55 |
+
return environment.get(name)
|
56 |
+
case Let(Variable(name) as v, e1, e2):
|
57 |
+
re1 = resolve_(e1)
|
58 |
+
environment.enter_scope()
|
59 |
+
environment.add(name, v)
|
60 |
+
re2 = resolve_(e2)
|
61 |
+
environment.exit_scope()
|
62 |
+
return Let(v, re1, re2)
|
63 |
+
case Statement(command ,statement):
|
64 |
+
return Statement(command, resolve_(statement))
|
65 |
+
|
66 |
+
|
67 |
+
|
68 |
+
|
69 |
+
case IfElse(c, b, e):
|
70 |
+
return IfElse(resolve_(c), resolve_(b), resolve_(e))
|
71 |
+
case LetFun(Variable(name) as v, params, body, expr):
|
72 |
+
environment.enter_scope()
|
73 |
+
environment.add(name, v)
|
74 |
+
environment.enter_scope()
|
75 |
+
for param in params:
|
76 |
+
environment.add(param.name, param)
|
77 |
+
rbody = resolve_(body)
|
78 |
+
environment.exit_scope()
|
79 |
+
rexpr = resolve_(expr)
|
80 |
+
environment.exit_scope()
|
81 |
+
return LetFun(v, params, rbody, rexpr)
|
82 |
+
case Function(MutVar(name) as m, params , body) | Function(Variable(name) as m, params , body):
|
83 |
+
new = False
|
84 |
+
# environment.add(name, m)
|
85 |
+
if not environment.check(name):
|
86 |
+
environment.add(name, m)
|
87 |
+
if name in lateBinding:
|
88 |
+
lateBinding[name].fn.id = m.id
|
89 |
+
# lateBinding.pop(name)
|
90 |
+
new = True
|
91 |
+
else:
|
92 |
+
if name in lateBinding:
|
93 |
+
lateBinding[name].fn.id = m.id
|
94 |
+
lateBinding[name].fn.put(m.value)
|
95 |
+
lateBinding.pop(name)
|
96 |
+
environment.update(name, m)
|
97 |
+
mutvar = environment.get(name)
|
98 |
+
|
99 |
+
environment.enter_scope()
|
100 |
+
# rparams = []
|
101 |
+
for param in params:
|
102 |
+
environment.add(param.name, param)
|
103 |
+
|
104 |
+
# rparams.append(resolve_(param))
|
105 |
+
rbody = resolve_(body)
|
106 |
+
environment.exit_scope()
|
107 |
+
e = FnObject(params, rbody)
|
108 |
+
mutvar.put(e)
|
109 |
+
if new:
|
110 |
+
lateBinding[name].fn.put(e)
|
111 |
+
lateBinding.pop(name)
|
112 |
+
return Function(mutvar, params, rbody)
|
113 |
+
case Seq(things):
|
114 |
+
environment.enter_scope()
|
115 |
+
v = []
|
116 |
+
for thing in things:
|
117 |
+
v.append(resolve_(thing))
|
118 |
+
|
119 |
+
environment.exit_scope()
|
120 |
+
return Seq(v)
|
121 |
+
case FunCall(MutVar(name) as m, args):
|
122 |
+
if not environment.check(name):
|
123 |
+
lateBinding[name] = program
|
124 |
+
m = resolve_(m)
|
125 |
+
fn = environment.get(name).get()
|
126 |
+
m.put(fn)
|
127 |
+
argv = []
|
128 |
+
|
129 |
+
for arg in args:
|
130 |
+
argv.append(resolve_(arg))
|
131 |
+
return FunCall(m, argv)
|
132 |
+
case FunCall(fn, args):
|
133 |
+
rfn = resolve_(fn)
|
134 |
+
rargs = []
|
135 |
+
for arg in args:
|
136 |
+
rargs.append(resolve_(arg))
|
137 |
+
return FunCall(rfn, rargs)
|
138 |
+
|
139 |
+
|
140 |
+
case While(c, b):
|
141 |
+
|
142 |
+
return While(resolve_(c), resolve_(b))
|
143 |
+
case ForLoop(start, condition, increment, body):
|
144 |
+
return ForLoop(resolve_(start), resolve_(condition), resolve_(increment), resolve_(body))
|
145 |
+
|
146 |
+
case Listing(value, datatype):
|
147 |
+
for i in range(len(value)):
|
148 |
+
value[i] = resolve_(value[i])
|
149 |
+
return Listing(value, datatype)
|
150 |
+
|
151 |
+
case Slicing(name, start, end, jump):
|
152 |
+
return Slicing(resolve_(name), resolve_(start), resolve_(end), resolve_(jump))
|
153 |
+
|
154 |
+
case list_append(MutVar(var), item):
|
155 |
+
if not environment.check(var):
|
156 |
+
environment.add(var, MutVar(var))
|
157 |
+
return list_append(environment.get(var), resolve_(item))
|
158 |
+
case length(MutVar(var)):
|
159 |
+
if not environment.check(var):
|
160 |
+
environment.add(var, MutVar(var))
|
161 |
+
return length(resolve_(environment.get(var)))
|
162 |
+
case Increment(MutVar(var)):
|
163 |
+
return Increment(resolve_(environment.get(var)))
|
164 |
+
case Decrement(MutVar(var)):
|
165 |
+
return Decrement(resolve_(environment.get(var)))
|
166 |
+
|
167 |
+
|
168 |
+
|
169 |
+
|
170 |
+
|
171 |
+
# def eval(program: AST, environment: Environment = None) -> Value:
|
172 |
+
# if environment is None:
|
173 |
+
# environment = Environment()
|
174 |
+
|
175 |
+
# def eval_(program):
|
176 |
+
# return eval(program, environment)
|
177 |
+
|
178 |
+
# match program:
|
179 |
+
# case NumLiteral(value):
|
180 |
+
# return value
|
181 |
+
# case Variable(_) as v:
|
182 |
+
# return environment.get(v)
|
183 |
+
# case Let(Variable(_) as v, e1, e2) | LetMut(Variable(_) as v, e1, e2):
|
184 |
+
# v1 = eval_(e1)
|
185 |
+
# environment.enter_scope()
|
186 |
+
# environment.add(v, v1)
|
187 |
+
# v2 = eval_(e2)
|
188 |
+
# environment.exit_scope()
|
189 |
+
# return v2
|
190 |
+
# case BinOp("+", left, right):
|
191 |
+
# return eval_(left) + eval_(right)
|
192 |
+
# case BinOp("-", left, right):
|
193 |
+
# return eval_(left) - eval_(right)
|
194 |
+
# case BinOp("*", left, right):
|
195 |
+
# return eval_(left) * eval_(right)
|
196 |
+
# case BinOp("/", left, right):
|
197 |
+
# return eval_(left) / eval_(right)
|
198 |
+
# case Put(Variable(_) as v, e):
|
199 |
+
# environment.update(v, eval_(e))
|
200 |
+
# return environment.get(v)
|
201 |
+
# case Get(Variable(_) as v):
|
202 |
+
# return environment.get(v)
|
203 |
+
# case Seq(things):
|
204 |
+
# v = None
|
205 |
+
# for thing in things:
|
206 |
+
# v = eval_(thing)
|
207 |
+
# return v
|
208 |
+
# case LetFun(Variable(_) as v, params, body, expr):
|
209 |
+
# environment.enter_scope()
|
210 |
+
# environment.add(v, FnObject(params, body))
|
211 |
+
# v = eval_(expr)
|
212 |
+
# environment.exit_scope()
|
213 |
+
# return v
|
214 |
+
# case FunCall(Variable(_) as v, args):
|
215 |
+
# fn = environment.get(v)
|
216 |
+
# argv = []
|
217 |
+
# for arg in args:
|
218 |
+
# argv.append(eval_(arg))
|
219 |
+
# environment.enter_scope()
|
220 |
+
# for param, arg in zip(fn.params, argv):
|
221 |
+
# environment.add(param, arg)
|
222 |
+
# v = eval_(fn.body)
|
223 |
+
# environment.exit_scope()
|
224 |
+
# return v
|
225 |
+
# raise InvalidProgram()
|
226 |
+
|
227 |
+
def test_resolve():
|
228 |
+
import pprint
|
229 |
+
pp = pprint.PrettyPrinter(indent=4)
|
230 |
+
e = Let(Variable.make("a"), NumLiteral(0), Variable.make("a"))
|
231 |
+
# pp.pprint(e)
|
232 |
+
re = resolve(e)
|
233 |
+
# pp.pprint(re)
|
234 |
+
|
235 |
+
e = LetFun(Variable.make("foo"), [Variable.make("a")], FunCall(Variable.make("foo"), [Variable.make("a")]),
|
236 |
+
Let(Variable.make("g"), Variable.make("foo"),
|
237 |
+
LetFun(Variable.make("foo"), [Variable.make("a")], NumLiteral(0),
|
238 |
+
FunCall(Variable.make("g"), [NumLiteral(0)]))))
|
239 |
+
pp.pprint(e)
|
240 |
+
pp.pprint(r := resolve(e))
|
241 |
+
print(eval(r))
|
242 |
+
|
243 |
+
# test_resolve()
|
sim.py
ADDED
@@ -0,0 +1,893 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
from dataclasses_sim import *
|
2 |
+
import Parser as prs
|
3 |
+
from type_checking import *
|
4 |
+
from resolver import *
|
5 |
+
import sys
|
6 |
+
import pprint
|
7 |
+
import copy
|
8 |
+
pp = pprint.PrettyPrinter()
|
9 |
+
|
10 |
+
def type_error():
|
11 |
+
sys.exit('Dynamic type check error')
|
12 |
+
|
13 |
+
# Combining lexer parser
|
14 |
+
@dataclass
|
15 |
+
class Interpreter:
|
16 |
+
parser: prs.Parser
|
17 |
+
|
18 |
+
def eval(program: AST, environment: Environment() = None) -> Value:
|
19 |
+
if environment is None:
|
20 |
+
environment = Environment()
|
21 |
+
environment.program = program
|
22 |
+
def eval_env(program):
|
23 |
+
return eval(program, environment)
|
24 |
+
|
25 |
+
def eval_bool_env(program):
|
26 |
+
return eval_bool(program, environment)
|
27 |
+
|
28 |
+
def eval_string_env(program):
|
29 |
+
return eval_string(program, environment)
|
30 |
+
|
31 |
+
match program:
|
32 |
+
case Interpreter(p):
|
33 |
+
tree = p.parse()
|
34 |
+
sys.stdout = open('unresolved_tree', 'w')
|
35 |
+
pp = pprint.PrettyPrinter(stream=sys.stdout)
|
36 |
+
print("Unresolved Tree:")
|
37 |
+
pp.pprint(tree)
|
38 |
+
|
39 |
+
if resolverOn:
|
40 |
+
tree = resolve(tree)
|
41 |
+
sys.stdout = open('resolved_tree', 'w')
|
42 |
+
pp = pprint.PrettyPrinter(stream=sys.stdout)
|
43 |
+
pp.stream = sys.stdout
|
44 |
+
print("Resolved Tree:")
|
45 |
+
pp.pprint(tree)
|
46 |
+
|
47 |
+
# typecheck(tree)
|
48 |
+
sys.stdout = open('eval.txt', 'w')
|
49 |
+
e = eval(tree)
|
50 |
+
sys.stdout = sys.__stdout__
|
51 |
+
|
52 |
+
return e
|
53 |
+
|
54 |
+
|
55 |
+
case Statement(command ,statement):
|
56 |
+
match command:
|
57 |
+
case "print":
|
58 |
+
# print(statement)
|
59 |
+
if isinstance(statement,StringLiteral) :
|
60 |
+
print(eval_string_env(statement))
|
61 |
+
elif isinstance(statement, type(None)):
|
62 |
+
print()
|
63 |
+
elif isinstance(statement, MutVar):
|
64 |
+
e = environment.get(statement.name).get()
|
65 |
+
if isinstance(e, Listing):
|
66 |
+
print(eval_env(e))
|
67 |
+
else:
|
68 |
+
print(e)
|
69 |
+
|
70 |
+
else:
|
71 |
+
e = eval_env(statement)
|
72 |
+
if isinstance(e, Listing):
|
73 |
+
print(eval_env(e))
|
74 |
+
|
75 |
+
else:
|
76 |
+
print(e)
|
77 |
+
# print(eval_env(statement))
|
78 |
+
case "return":
|
79 |
+
e = Statement(command, statement)
|
80 |
+
|
81 |
+
if isinstance(statement,StringLiteral) :
|
82 |
+
|
83 |
+
e.statement = eval_string_env(statement)
|
84 |
+
|
85 |
+
else:
|
86 |
+
e.statement = eval_env(statement)
|
87 |
+
return e
|
88 |
+
case "break":
|
89 |
+
return program
|
90 |
+
|
91 |
+
return
|
92 |
+
|
93 |
+
case IfElse(c, b, e):
|
94 |
+
match eval_env(c):
|
95 |
+
case True:
|
96 |
+
return eval_env(b)
|
97 |
+
case False:
|
98 |
+
if e == None:
|
99 |
+
return
|
100 |
+
return eval_env(e)
|
101 |
+
|
102 |
+
case Put(Variable(name), e):
|
103 |
+
environment.update(name, eval_env(e))
|
104 |
+
return environment.get(name)
|
105 |
+
case Get(Variable(name)):
|
106 |
+
return environment.get(name)
|
107 |
+
|
108 |
+
case Put(MutVar(name), e):
|
109 |
+
MutVar(name).put(eval(e))
|
110 |
+
environment.update(name,MutVar(name))
|
111 |
+
return MutVar(name).get()
|
112 |
+
|
113 |
+
case Get(MutVar(name)):
|
114 |
+
return environment.get(name).get()
|
115 |
+
|
116 |
+
case Seq(things):
|
117 |
+
environment.enter_scope()
|
118 |
+
v = None
|
119 |
+
for thing in things:
|
120 |
+
v = eval_env(thing)
|
121 |
+
if isinstance(v,Statement):
|
122 |
+
if v.command=="break":
|
123 |
+
break
|
124 |
+
if v.command=="return":
|
125 |
+
return v.statement
|
126 |
+
environment.exit_scope()
|
127 |
+
return v
|
128 |
+
|
129 |
+
case LetFun(Variable(name), params, body, expr):
|
130 |
+
environment.enter_scope()
|
131 |
+
environment.add(name, FnObject(params, body))
|
132 |
+
v = eval_env(expr)
|
133 |
+
environment.exit_scope()
|
134 |
+
return v
|
135 |
+
|
136 |
+
case FunCall(Variable(name), args):
|
137 |
+
fn = environment.get(name)
|
138 |
+
argv = []
|
139 |
+
for arg in args:
|
140 |
+
argv.append(eval_env(arg))
|
141 |
+
environment.enter_scope()
|
142 |
+
for param, arg in zip(fn.params, argv):
|
143 |
+
environment.add(param.name, arg)
|
144 |
+
v = eval_env(fn.body)
|
145 |
+
environment.exit_scope()
|
146 |
+
return v
|
147 |
+
|
148 |
+
case FunCall(MutVar(name) as m, args):
|
149 |
+
# not (environment.check(name) and environment.get(name) != None)
|
150 |
+
if m.value == None and (not environment.check(name) or environment.get(name) == None):
|
151 |
+
print(f"Function '{name}' not defined")
|
152 |
+
sys.exit()
|
153 |
+
# environment.add(name, MutVar(name))
|
154 |
+
# environment.get(name).put(FnObject([],None))
|
155 |
+
|
156 |
+
m.value = copy.deepcopy(m.value)
|
157 |
+
fn = m.value if m.value != None else environment.get(name).get() #fn is FnObject
|
158 |
+
# pp = pprint.PrettyPrinter()
|
159 |
+
# pp.pprint(fn)
|
160 |
+
# pp.pprint(environment.envs)
|
161 |
+
# fn = FnObject(fn.params, fn.body)
|
162 |
+
argv = []
|
163 |
+
mtfo = [] #muttable function object
|
164 |
+
for arg in args:
|
165 |
+
if arg != None:
|
166 |
+
mtfo.append(arg)
|
167 |
+
#if isinstance(arg, MutVar) and isinstance(arg.value, FnObject):
|
168 |
+
# mtfo[arg.value] = arg
|
169 |
+
argv.append(eval_env(arg))
|
170 |
+
environment.enter_scope()
|
171 |
+
# print(name)
|
172 |
+
# print(argv)
|
173 |
+
# print(mtfo)
|
174 |
+
# print(fn.params)
|
175 |
+
# print(fn.body)
|
176 |
+
for param, arg in zip(fn.params, argv):
|
177 |
+
if isinstance(param, MutVar):
|
178 |
+
if isinstance(arg, FnObject):
|
179 |
+
e = mtfo[argv.index(arg)]
|
180 |
+
if environment.check(e.name):
|
181 |
+
environment.addWithOther(e.name, param.name, None)
|
182 |
+
# param.put(FnObject(arg.params, copy.deepcopy(arg.body)))
|
183 |
+
# param.put(copy.deepcopy(arg))
|
184 |
+
|
185 |
+
else:
|
186 |
+
environment.add(param.name, param)
|
187 |
+
param.put(arg)
|
188 |
+
else:
|
189 |
+
environment.add(param.name, arg)
|
190 |
+
# print(fn, id(fn.body))
|
191 |
+
v = eval_env(fn.body)
|
192 |
+
|
193 |
+
environment.exit_scope()
|
194 |
+
# print(name, v)
|
195 |
+
return v
|
196 |
+
|
197 |
+
case FunCall(FunCall(_,_) as funcall, args):
|
198 |
+
# print(fncall)
|
199 |
+
fn = eval_env(funcall)
|
200 |
+
|
201 |
+
# not (environment.check(name) and environment.get(name) != None)
|
202 |
+
# if m.value == None and (not environment.check(name) or environment.get(name) == None):
|
203 |
+
# print(f"Function '{name}' not defined")
|
204 |
+
# sys.exit()
|
205 |
+
# # environment.add(name, MutVar(name))
|
206 |
+
# # environment.get(name).put(FnObject([],None))
|
207 |
+
# m.value = copy.deepcopy(m.value)
|
208 |
+
# fn = m.value if m.value != None else environment.get(name).get() #fn is FnObject
|
209 |
+
# fn = FnObject(fn.params, fn.body)
|
210 |
+
argv = []
|
211 |
+
mtfo = [] #muttable function object
|
212 |
+
for arg in args:
|
213 |
+
if arg != None:
|
214 |
+
mtfo.append(arg)
|
215 |
+
#if isinstance(arg, MutVar) and isinstance(arg.value, FnObject):
|
216 |
+
# mtfo[arg.value] = arg
|
217 |
+
argv.append(eval_env(arg))
|
218 |
+
environment.enter_scope()
|
219 |
+
# print(name)
|
220 |
+
# print(argv)
|
221 |
+
# print(mtfo)
|
222 |
+
# print(fn.params)
|
223 |
+
# print(fn.body)
|
224 |
+
for param, arg in zip(fn.params, argv):
|
225 |
+
if isinstance(param, MutVar):
|
226 |
+
if isinstance(arg, FnObject):
|
227 |
+
e = mtfo[argv.index(arg)]
|
228 |
+
if environment.check(e.name):
|
229 |
+
environment.addWithOther(e.name, param.name, None)
|
230 |
+
# param.put(FnObject(arg.params, copy.deepcopy(arg.body)))
|
231 |
+
# param.put(copy.deepcopy(arg))
|
232 |
+
|
233 |
+
else:
|
234 |
+
environment.add(param.name, param)
|
235 |
+
param.put(arg)
|
236 |
+
else:
|
237 |
+
environment.add(param.name, arg)
|
238 |
+
# print(fn, id(fn.body))
|
239 |
+
v = eval_env(fn.body)
|
240 |
+
|
241 |
+
environment.exit_scope()
|
242 |
+
return v
|
243 |
+
|
244 |
+
case MutVar(name) as m:
|
245 |
+
# if program.value != None:
|
246 |
+
# return program.get()
|
247 |
+
|
248 |
+
# return
|
249 |
+
if not environment.check(name):
|
250 |
+
print(environment.envs)
|
251 |
+
print(f"Mutable Variable '{name}' not defined")
|
252 |
+
sys.exit()
|
253 |
+
# environment.add(name, MutVar(name))
|
254 |
+
|
255 |
+
e = m if m.value != None else environment.get(name)
|
256 |
+
# e = environment.get(name)
|
257 |
+
v = e.get()
|
258 |
+
typesWithNoEval = Fraction | FnObject | Listing | int | float | str | bool
|
259 |
+
# if isinstance(v, Fraction) or isinstance(v, FnObject) or isinstance(v, Listing):
|
260 |
+
if isinstance(v, typesWithNoEval):
|
261 |
+
return v
|
262 |
+
else:
|
263 |
+
v = eval_env(v)
|
264 |
+
# e.put(v)
|
265 |
+
return v
|
266 |
+
|
267 |
+
case Increment(MutVar(name)):
|
268 |
+
#print('Hi')
|
269 |
+
temp = environment.get(name)
|
270 |
+
e = eval_env(temp)
|
271 |
+
#print('Hi')
|
272 |
+
e = e + eval_env(NumLiteral(1))
|
273 |
+
temp.put(e)
|
274 |
+
environment.update(name, temp)
|
275 |
+
return
|
276 |
+
|
277 |
+
case Decrement(MutVar(name)):
|
278 |
+
temp = environment.get(name)
|
279 |
+
e = eval_env(temp)
|
280 |
+
e = e - eval_env(NumLiteral(1))
|
281 |
+
temp.put(e)
|
282 |
+
environment.update(name, temp)
|
283 |
+
return
|
284 |
+
|
285 |
+
case length(MutVar(name)):
|
286 |
+
temp = environment.get(name).get()
|
287 |
+
# e = eval_env(temp)
|
288 |
+
# return len(e.value)
|
289 |
+
if isinstance(temp, Listing):
|
290 |
+
return len(temp.value)
|
291 |
+
return len(temp)
|
292 |
+
|
293 |
+
case list_head(MutVar(name)):
|
294 |
+
temp = environment.get(name)
|
295 |
+
e = eval_env(temp)
|
296 |
+
return e[0]
|
297 |
+
|
298 |
+
case list_tail(MutVar(name)):
|
299 |
+
temp = environment.get(name)
|
300 |
+
e = eval_env(temp)
|
301 |
+
return e[1:]
|
302 |
+
|
303 |
+
case list_isempty(MutVar(name)):
|
304 |
+
temp = environment.get(name)
|
305 |
+
e = eval_env(temp)
|
306 |
+
if len(e)==0:
|
307 |
+
return True
|
308 |
+
return False
|
309 |
+
|
310 |
+
case list_append(MutVar(var), item):
|
311 |
+
|
312 |
+
if not environment.check(var):
|
313 |
+
print(f"list '{var}' not defined")
|
314 |
+
sys.exit()
|
315 |
+
temp = environment.get(var).get().value
|
316 |
+
# e1 = eval_env(temp)
|
317 |
+
# e1.append(eval_env(item))
|
318 |
+
e1 = temp
|
319 |
+
e1.append(item)
|
320 |
+
return e1
|
321 |
+
|
322 |
+
|
323 |
+
|
324 |
+
case Listing(value, datatype):
|
325 |
+
if datatype != "NONE":
|
326 |
+
if datatype == "INTEGER":
|
327 |
+
temp = IntLiteral
|
328 |
+
elif datatype == "STRING":
|
329 |
+
temp = StringLiteral
|
330 |
+
elif datatype == "NONE":
|
331 |
+
temp = None
|
332 |
+
for i in value:
|
333 |
+
if isinstance(i, temp):
|
334 |
+
continue
|
335 |
+
else:
|
336 |
+
print("Value of Invalid type in Listing")
|
337 |
+
raise InvalidProgram()
|
338 |
+
|
339 |
+
temp =[]
|
340 |
+
for i in program.value:
|
341 |
+
temp.append(eval_env(i))
|
342 |
+
|
343 |
+
|
344 |
+
return temp
|
345 |
+
|
346 |
+
|
347 |
+
case Slicing(name, start, end, jump):
|
348 |
+
|
349 |
+
e1 = eval_env(name)
|
350 |
+
if isinstance(e1, Listing):
|
351 |
+
e1 = eval_env(e1)
|
352 |
+
e2 = eval_env(start)
|
353 |
+
e2 = int(e2)
|
354 |
+
if end!=None:
|
355 |
+
e3 = eval_env(end)
|
356 |
+
e3 = int(e3)
|
357 |
+
|
358 |
+
if jump!=None:
|
359 |
+
e4 = eval_env(jump)
|
360 |
+
e4 = int(e4)
|
361 |
+
|
362 |
+
if end == None and jump!=None:
|
363 |
+
e = e1[e2::e4]
|
364 |
+
elif jump==None:
|
365 |
+
e = e1[e2]
|
366 |
+
else:
|
367 |
+
e = e1[e2:e3:e4]
|
368 |
+
return e
|
369 |
+
|
370 |
+
case list_Slicing(name, start, end, jump):
|
371 |
+
e1 = eval_env(name)
|
372 |
+
e2 = eval_env(start)
|
373 |
+
e2 = int(e2)
|
374 |
+
if end!=None:
|
375 |
+
e3 = eval_env(end)
|
376 |
+
e3 = int(e3)
|
377 |
+
|
378 |
+
if jump!=None:
|
379 |
+
e4 = eval_env(jump)
|
380 |
+
e4 = int(e4)
|
381 |
+
|
382 |
+
if end == None and jump!=None:
|
383 |
+
e = e1[e2::e4]
|
384 |
+
elif jump==None:
|
385 |
+
e = e1[e2]
|
386 |
+
else:
|
387 |
+
e = e1[e2:e3:e4]
|
388 |
+
return e
|
389 |
+
|
390 |
+
|
391 |
+
case ForLoop(start, condition, increment, body):
|
392 |
+
# print("Zeeshan", condition)
|
393 |
+
|
394 |
+
eval_env(start)
|
395 |
+
if(condition == None):
|
396 |
+
while True:
|
397 |
+
v = eval_env(body)
|
398 |
+
if isinstance(v,Statement):
|
399 |
+
if v.command=="break":
|
400 |
+
break
|
401 |
+
if v.command=="return":
|
402 |
+
return v.statement
|
403 |
+
else:
|
404 |
+
eval_env(increment)
|
405 |
+
else:
|
406 |
+
while(eval_env(condition)):
|
407 |
+
v = eval_env(body)
|
408 |
+
if isinstance(v,Statement):
|
409 |
+
if v.command=="break":
|
410 |
+
break
|
411 |
+
if v.command=="return":
|
412 |
+
return v.statement
|
413 |
+
else:
|
414 |
+
eval_env(increment)
|
415 |
+
return
|
416 |
+
|
417 |
+
|
418 |
+
# def for_loop_helper(en, condition):
|
419 |
+
# # print(jump)
|
420 |
+
# flag = eval_env(condition)
|
421 |
+
# # if(flag < en):
|
422 |
+
# # eval_env(body)
|
423 |
+
# # return for_loop_helper(en, jump)
|
424 |
+
# # while(flag != en):
|
425 |
+
# # eval_env(body)
|
426 |
+
# # flag = eval_env(condition)
|
427 |
+
# while(eval_env(condition)):
|
428 |
+
# eval_env(body)
|
429 |
+
# eval_env(en)
|
430 |
+
# return
|
431 |
+
|
432 |
+
case While(c, b):
|
433 |
+
# if eval_bool_env(c):
|
434 |
+
# eval_env(b)
|
435 |
+
# eval_env(While(c, b))
|
436 |
+
while (eval_env(c)): # avoid recursion depth
|
437 |
+
v = eval_env(b)
|
438 |
+
if isinstance(v,Statement):
|
439 |
+
if v.command=="break":
|
440 |
+
break
|
441 |
+
if v.command=="return":
|
442 |
+
return v.statement
|
443 |
+
return
|
444 |
+
|
445 |
+
case BinOp("=", MutVar(name) as m, val):
|
446 |
+
if (not isinstance(val, Listing)):
|
447 |
+
e = eval_env(val)
|
448 |
+
else:
|
449 |
+
e = val
|
450 |
+
|
451 |
+
program.right = val
|
452 |
+
# e = eval_env(val)
|
453 |
+
# program.get_left().put(eval(val))
|
454 |
+
if not environment.check(name):
|
455 |
+
environment.add(name, m)
|
456 |
+
mutvar = environment.get(name)
|
457 |
+
mutvar.put(e)
|
458 |
+
|
459 |
+
else:
|
460 |
+
mutvar = environment.get(name)
|
461 |
+
# environment.update(name, MutVar(name))
|
462 |
+
mutvar.put(e)
|
463 |
+
m.put(e)
|
464 |
+
return mutvar.get() #Assignment as expression
|
465 |
+
|
466 |
+
case BinOp("+=", MutVar(name) as m, val):
|
467 |
+
e = eval_env(val)
|
468 |
+
# program.get_left().put(eval(val))
|
469 |
+
if not environment.check(name):
|
470 |
+
environment.add(name, m)
|
471 |
+
mutvar = environment.get(name)
|
472 |
+
e += mutvar.get()
|
473 |
+
mutvar.put(e)
|
474 |
+
|
475 |
+
else:
|
476 |
+
mutvar = environment.get(name)
|
477 |
+
e += mutvar.get()
|
478 |
+
# environment.update(name, MutVar(name))
|
479 |
+
mutvar.put(e)
|
480 |
+
return mutvar.get() #Assignment as expression
|
481 |
+
|
482 |
+
|
483 |
+
case BinOp("-=", MutVar(name) as m, val):
|
484 |
+
e = eval_env(val)
|
485 |
+
# program.get_left().put(eval(val))
|
486 |
+
if not environment.check(name):
|
487 |
+
environment.add(name, m)
|
488 |
+
mutvar = environment.get(name)
|
489 |
+
e -= mutvar.get()
|
490 |
+
mutvar.put(e)
|
491 |
+
|
492 |
+
else:
|
493 |
+
mutvar = environment.get(name)
|
494 |
+
e -= mutvar.get()
|
495 |
+
# environment.update(name, MutVar(name))
|
496 |
+
mutvar.put(e)
|
497 |
+
return mutvar.get() #Assignment as expression
|
498 |
+
|
499 |
+
|
500 |
+
|
501 |
+
case BinOp("/=", MutVar(name) as m, val):
|
502 |
+
e = eval_env(val)
|
503 |
+
# program.get_left().put(eval(val))
|
504 |
+
if not environment.check(name):
|
505 |
+
environment.add(name, m)
|
506 |
+
mutvar = environment.get(name)
|
507 |
+
e /= mutvar.get()
|
508 |
+
mutvar.put(e)
|
509 |
+
|
510 |
+
else:
|
511 |
+
mutvar = environment.get(name)
|
512 |
+
e /= mutvar.get()
|
513 |
+
# environment.update(name, MutVar(name))
|
514 |
+
mutvar.put(e)
|
515 |
+
return mutvar.get() #Assignment as expression
|
516 |
+
|
517 |
+
case BinOp("*=", MutVar(name) as m, val):
|
518 |
+
e = eval_env(val)
|
519 |
+
# program.get_left().put(eval(val))
|
520 |
+
if not environment.check(name):
|
521 |
+
environment.add(name, m)
|
522 |
+
mutvar = environment.get(name)
|
523 |
+
e *= mutvar.get()
|
524 |
+
mutvar.put(e)
|
525 |
+
|
526 |
+
else:
|
527 |
+
mutvar = environment.get(name)
|
528 |
+
e *= mutvar.get()
|
529 |
+
# environment.update(name, MutVar(name))
|
530 |
+
mutvar.put(e)
|
531 |
+
return mutvar.get() #Assignment as expression
|
532 |
+
|
533 |
+
case BinOp("**=", MutVar(name) as m, val):
|
534 |
+
e = eval_env(val)
|
535 |
+
# program.get_left().put(eval(val))
|
536 |
+
if not environment.check(name):
|
537 |
+
environment.add(name, m)
|
538 |
+
mutvar = environment.get(name)
|
539 |
+
e **= mutvar.get()
|
540 |
+
mutvar.put(e)
|
541 |
+
|
542 |
+
else:
|
543 |
+
mutvar = environment.get(name)
|
544 |
+
e **= mutvar.get()
|
545 |
+
# environment.update(name, MutVar(name))
|
546 |
+
mutvar.put(e)
|
547 |
+
return mutvar.get() #Assignment as expression
|
548 |
+
|
549 |
+
|
550 |
+
|
551 |
+
case Function(MutVar(name) as m, params , body) | Function(Variable(name) as m, params , body):
|
552 |
+
# environment.enter_scope()
|
553 |
+
# environment.add(name, FnObject(params, body))
|
554 |
+
if not environment.check(name):
|
555 |
+
environment.add(name, m)
|
556 |
+
else:
|
557 |
+
environment.update(name, m)
|
558 |
+
mutvar = environment.get(name)
|
559 |
+
e = FnObject(params, body)
|
560 |
+
mutvar.put(e)
|
561 |
+
|
562 |
+
# if isinstance(program.name, MutVar):
|
563 |
+
# program.name.put(FnObject(params, body))
|
564 |
+
# environment.exit_scope()
|
565 |
+
return e
|
566 |
+
|
567 |
+
case NumLiteral(val):
|
568 |
+
return val
|
569 |
+
case IntLiteral(val):
|
570 |
+
return val
|
571 |
+
case FloatLiteral(val):
|
572 |
+
return val
|
573 |
+
case BoolLiteral(val):
|
574 |
+
return eval_bool_env(program)
|
575 |
+
case StringLiteral(val):
|
576 |
+
return eval_string_env(program)
|
577 |
+
|
578 |
+
|
579 |
+
case Variable(name):
|
580 |
+
# print(environment)
|
581 |
+
# if name in environment:
|
582 |
+
# return environment[name]
|
583 |
+
# raise InvalidProgram()
|
584 |
+
return environment.get(name)
|
585 |
+
|
586 |
+
# case Let(Variable(name), e1, e2):
|
587 |
+
# v1 = eval_env(e1)
|
588 |
+
# return eval(e2, environment | { name: v1})
|
589 |
+
|
590 |
+
case Let(Variable(name), e1, e2) | LetMut(Variable(name), e1, e2) | Let(MutVar(name), e1, e2):
|
591 |
+
# v1 = eval_env(e1)
|
592 |
+
# return eval(e2, environment | { name: v1})
|
593 |
+
v1 = eval_env(e1)
|
594 |
+
environment.enter_scope()
|
595 |
+
environment.add(name, v1)
|
596 |
+
v2 = eval_env(e2)
|
597 |
+
environment.exit_scope()
|
598 |
+
return v2
|
599 |
+
|
600 |
+
|
601 |
+
case BinOp("+", left, right):
|
602 |
+
# if (isinstance(right, NumLiteral) == False):
|
603 |
+
# type_error()
|
604 |
+
return eval_env(left) + eval_env(right)
|
605 |
+
case BinOp("-", left, right):
|
606 |
+
return eval_env(left) - eval_env(right)
|
607 |
+
case BinOp("*", left, right):
|
608 |
+
return eval_env(left) * eval_env(right)
|
609 |
+
case BinOp("/", left, right):
|
610 |
+
return eval_env(left) / eval_env(right)
|
611 |
+
case BinOp("//", left, right):
|
612 |
+
return eval_env(left) // eval_env(right)
|
613 |
+
case BinOp("%", left, right):
|
614 |
+
return eval_env(left) % eval_env(right)
|
615 |
+
case UnOp("-", mid):
|
616 |
+
return Fraction(-1)*eval(mid)
|
617 |
+
case UnOp("+", mid):
|
618 |
+
return eval(mid)
|
619 |
+
case UnOp("++", mid):
|
620 |
+
return eval_env(mid)+Fraction(1)
|
621 |
+
case UnOp("--", mid):
|
622 |
+
return eval_env(mid)-Fraction(1)
|
623 |
+
case BinOp("<<", left, right):
|
624 |
+
try:
|
625 |
+
if(eval_env(right) < 0):
|
626 |
+
raise InvalidProgram(Exception)
|
627 |
+
except InvalidProgram:
|
628 |
+
print("Shift operator must be non negative")
|
629 |
+
return int(eval_env(left)) << int(eval_env(right))
|
630 |
+
case BinOp(">>", left, right):
|
631 |
+
try:
|
632 |
+
if(eval_env(right) < 0):
|
633 |
+
raise InvalidProgram(Exception)
|
634 |
+
except InvalidProgram:
|
635 |
+
print("Shift operator must be non negative")
|
636 |
+
return int(eval_env(left)) >> int(eval_env(right))
|
637 |
+
case BinOp("|", left, right):
|
638 |
+
return eval_env(left) | eval_env(right)
|
639 |
+
case BinOp("&", left, right):
|
640 |
+
return eval_env(left) & eval_env(right)
|
641 |
+
case BinOp("^", left, right):
|
642 |
+
return eval_env(left) ^ eval_env(right)
|
643 |
+
case BinOp("**", left, right):
|
644 |
+
return eval_env(left) ** eval_env(right)
|
645 |
+
case _:
|
646 |
+
return eval_string_env(program)
|
647 |
+
|
648 |
+
raise InvalidProgram()
|
649 |
+
|
650 |
+
|
651 |
+
def eval_string(program: AST, environment: Environment() = None) -> str:
|
652 |
+
if environment is None:
|
653 |
+
environment = Environment()
|
654 |
+
|
655 |
+
def eval_env(program):
|
656 |
+
return eval(program, environment)
|
657 |
+
|
658 |
+
def eval_bool_env(program):
|
659 |
+
return eval_bool(program, environment)
|
660 |
+
|
661 |
+
def eval_string_env(program):
|
662 |
+
return eval_string(program, environment)
|
663 |
+
|
664 |
+
match program:
|
665 |
+
|
666 |
+
case StringLiteral(val):
|
667 |
+
return val
|
668 |
+
case BinOp("=", MutVar(name), val):
|
669 |
+
e = eval_string_env(val)
|
670 |
+
# program.get_left().put(eval(val))
|
671 |
+
if not environment.check(name):
|
672 |
+
environment.add(name, MutVar(name))
|
673 |
+
mutvar = environment.get(name)
|
674 |
+
mutvar.put(e)
|
675 |
+
|
676 |
+
else:
|
677 |
+
mutvar = environment.get(name)
|
678 |
+
# environment.update(name, MutVar(name))
|
679 |
+
mutvar.put(e)
|
680 |
+
return
|
681 |
+
|
682 |
+
case BinOp("+", left, right):
|
683 |
+
return left + right
|
684 |
+
# case BinOp("")
|
685 |
+
case _:
|
686 |
+
return eval_bool_env(program)
|
687 |
+
|
688 |
+
raise InvalidProgram()
|
689 |
+
|
690 |
+
|
691 |
+
def eval_bool(program: AST, environment: Environment() = None) -> Val:
|
692 |
+
if environment is None:
|
693 |
+
environment = Environment()
|
694 |
+
|
695 |
+
def eval_env(program):
|
696 |
+
return eval(program, environment)
|
697 |
+
def eval_bool_env(program):
|
698 |
+
return eval_bool(program, environment)
|
699 |
+
|
700 |
+
def eval_string_env(program):
|
701 |
+
return eval_string(program, environment)
|
702 |
+
match program:
|
703 |
+
|
704 |
+
case BoolLiteral(value):
|
705 |
+
return value
|
706 |
+
case BinOp("==", left, right):
|
707 |
+
return (eval_env(left)==eval_env(right))
|
708 |
+
case BinOp(">", left, right):
|
709 |
+
return (eval_env(left)>eval_env(right))
|
710 |
+
case BinOp("<", left, right):
|
711 |
+
return (eval_env(left)<eval_env(right))
|
712 |
+
case BinOp(">=", left, right):
|
713 |
+
return (eval_env(left)>=eval_env(right))
|
714 |
+
case BinOp("<=", left, right):
|
715 |
+
return (eval_env(left)<=eval_env(right))
|
716 |
+
case BinOp("!=", left, right):
|
717 |
+
return (eval_env(left)!=eval_env(right))
|
718 |
+
case UnOp("!", mid):
|
719 |
+
return (not eval_env(mid))
|
720 |
+
case BinOp("&&", left, right):
|
721 |
+
return eval_env(left) and eval_env(right)
|
722 |
+
case BinOp("||", left, right):
|
723 |
+
return eval_env(left) or eval_env(right)
|
724 |
+
|
725 |
+
sys.stdout = open('error_in_sim', 'w')
|
726 |
+
pp = pprint.PrettyPrinter(stream=sys.stdout)
|
727 |
+
print("Current AST")
|
728 |
+
pp.pprint(program)
|
729 |
+
|
730 |
+
print("Current Environment:")
|
731 |
+
|
732 |
+
pp.pprint( environment.envs)
|
733 |
+
raise InvalidProgram()
|
734 |
+
|
735 |
+
|
736 |
+
def test_eval():
|
737 |
+
e1 = NumLiteral(2)
|
738 |
+
e2 = NumLiteral(7)
|
739 |
+
e3 = NumLiteral(9)
|
740 |
+
e4 = NumLiteral(5)
|
741 |
+
e5 = BinOp("+", e2, e3)
|
742 |
+
e6 = BinOp("/", e5, e4)
|
743 |
+
e7 = BinOp("*", e1, e6)
|
744 |
+
assert eval(e7) == Fraction(32, 5)
|
745 |
+
|
746 |
+
def test_let_eval():
|
747 |
+
a = Variable("a")
|
748 |
+
|
749 |
+
e1 = NumLiteral(5)
|
750 |
+
e2 = BinOp("+", a, a)
|
751 |
+
e = Let(a, e1, e2)
|
752 |
+
assert eval(e) == 10
|
753 |
+
e = Let(a, e1, Let(a, e2, e2))
|
754 |
+
assert eval(e) == 20
|
755 |
+
e = Let(a, e1, BinOp("+", a, Let(a, e2, e2)))
|
756 |
+
assert eval(e) == 25
|
757 |
+
e = Let(a, e1, BinOp("+", Let(a, e2, e2), a))
|
758 |
+
assert eval(e) == 25
|
759 |
+
e3 = NumLiteral(6)
|
760 |
+
e = BinOp("+", Let(a, e1, e2), Let(a, e3, e2))
|
761 |
+
assert eval(e) == 22
|
762 |
+
|
763 |
+
# test_let_eval()
|
764 |
+
|
765 |
+
def test_letmut():
|
766 |
+
a = Variable("a")
|
767 |
+
b = Variable("b")
|
768 |
+
e1 = LetMut(b, NumLiteral(2), Put(a, BinOp("+", Get(a), Get(b))))
|
769 |
+
e2 = LetMut(a, NumLiteral(1), Seq([e1, Get(a)]))
|
770 |
+
assert eval(e2) == 3
|
771 |
+
|
772 |
+
# test_letmut()
|
773 |
+
|
774 |
+
def test_Logic():
|
775 |
+
x1 = NumLiteral(5)
|
776 |
+
x2 = NumLiteral(3)
|
777 |
+
x3 = BinOp(">=",x1,x2)
|
778 |
+
x4 = BinOp("<",x1,x2)
|
779 |
+
x5 = BinOp("+", x1, x2)
|
780 |
+
e = BinOp("<<", x1, x2)
|
781 |
+
assert eval(e) == 40
|
782 |
+
assert eval_bool(x3) == True
|
783 |
+
assert eval_bool(x4) == False
|
784 |
+
x1 = BoolLiteral(True)
|
785 |
+
x2 = BoolLiteral(False)
|
786 |
+
e = BinOp("&&", x1, x2)
|
787 |
+
# print(e)
|
788 |
+
assert eval_bool(e) == False
|
789 |
+
e = UnOp("!", BoolLiteral(True))
|
790 |
+
# print(eval_bool(e))
|
791 |
+
assert eval_bool(e) == False
|
792 |
+
|
793 |
+
# assert eval_bool(e) == False
|
794 |
+
# e = UnOp("!", False)
|
795 |
+
# assert eval_bool(e) == True
|
796 |
+
e = Statement("print", x5)
|
797 |
+
eval(e)
|
798 |
+
|
799 |
+
e = Statement("print",StringLiteral("karthikeya"))
|
800 |
+
eval(e)
|
801 |
+
|
802 |
+
# print("print(\"karthikeya\")".split())
|
803 |
+
# print("")
|
804 |
+
|
805 |
+
# test_Logic()
|
806 |
+
|
807 |
+
def test_IfElse():
|
808 |
+
a = NumLiteral(2)
|
809 |
+
b = NumLiteral(5)
|
810 |
+
c = Variable('c')
|
811 |
+
x1 = BinOp("==", a, b)
|
812 |
+
x2 = Let(c,BinOp("+", a, b),c)
|
813 |
+
x3 = Let(c,BinOp("*", a, b),c)
|
814 |
+
e1 = IfElse(x1, x2, x3)
|
815 |
+
print(eval(e1))
|
816 |
+
# print(eval(c))
|
817 |
+
|
818 |
+
# test_IfElse()
|
819 |
+
|
820 |
+
def test_While():
|
821 |
+
p = MutVar('p')
|
822 |
+
p_g = BinOp("=", p, NumLiteral(1))
|
823 |
+
i = MutVar('i')
|
824 |
+
i_g = BinOp("=", i, NumLiteral(1))
|
825 |
+
|
826 |
+
# print(p.get(), i.get())
|
827 |
+
cond = BinOp("<=", i, NumLiteral(10))
|
828 |
+
x1 = BinOp("*", p, i)
|
829 |
+
x2 = BinOp("+", i, NumLiteral(1))
|
830 |
+
x3 = BinOp("=", p, x1)
|
831 |
+
x4 = BinOp("=", i, x2)
|
832 |
+
e = Seq([p_g, i_g,While(cond, Seq([x3, x4]))])
|
833 |
+
eval(e)
|
834 |
+
print(p.get(), i.get())
|
835 |
+
|
836 |
+
# test_While()
|
837 |
+
|
838 |
+
def test_MutVar_Get_Put():
|
839 |
+
p = MutVar('p')
|
840 |
+
p_g = BinOp("=", p, NumLiteral(1))
|
841 |
+
i = MutVar('i')
|
842 |
+
i_g = BinOp("=", i, NumLiteral(1))
|
843 |
+
e = Seq([p_g, i_g, Statement('print',Get('i')), Statement('print',Get('p')) ])
|
844 |
+
# test_MutVar_Get_Put()
|
845 |
+
|
846 |
+
def test_Function():
|
847 |
+
e1 = BinOp("+", NumLiteral(2), NumLiteral(1))
|
848 |
+
f1 = Function('add', e1, [])
|
849 |
+
e2 = BinOp("-", NumLiteral(2), NumLiteral(1))
|
850 |
+
f2 = Function('sub', e2, [])
|
851 |
+
eval(f1)
|
852 |
+
eval(f2)
|
853 |
+
e = Seq([f1,f2,])
|
854 |
+
|
855 |
+
|
856 |
+
# test_Function()
|
857 |
+
|
858 |
+
def test_letfun():
|
859 |
+
a = Variable("a")
|
860 |
+
b = Variable("b")
|
861 |
+
f = Variable("f")
|
862 |
+
g = BinOp (
|
863 |
+
"*",
|
864 |
+
FunCall(f, [NumLiteral(15), NumLiteral(2)]),
|
865 |
+
FunCall(f, [NumLiteral(12), NumLiteral(3)])
|
866 |
+
)
|
867 |
+
e = LetFun(
|
868 |
+
f, [a, b], BinOp("+", a, b),
|
869 |
+
g
|
870 |
+
)
|
871 |
+
assert eval(e) == (15+2)*(12+3)
|
872 |
+
print(eval(e))
|
873 |
+
|
874 |
+
# test_letfun()
|
875 |
+
|
876 |
+
def test_letfun2():
|
877 |
+
fact = Variable("fact")
|
878 |
+
g = Variable("g")
|
879 |
+
n = Variable("n")
|
880 |
+
e2 = LetFun(fact, [n], NumLiteral(0), FunCall(g, [NumLiteral(3)] ))
|
881 |
+
e1 = LetFun(g, [n], FunCall(fact, [n]), e2)
|
882 |
+
e = LetFun(fact, [n],
|
883 |
+
IfElse(BinOp("==",n,NumLiteral(0)),
|
884 |
+
NumLiteral(1),
|
885 |
+
FunCall(fact, [BinOp("-",n, NumLiteral(1))])),
|
886 |
+
e1)
|
887 |
+
print(eval(e))
|
888 |
+
|
889 |
+
|
890 |
+
|
891 |
+
|
892 |
+
|
893 |
+
# test_letfun2()
|
solution.txt
ADDED
@@ -0,0 +1,35 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
1
|
2 |
+
2
|
3 |
+
FIZZ
|
4 |
+
4
|
5 |
+
BUZZ
|
6 |
+
FIZZ
|
7 |
+
7
|
8 |
+
8
|
9 |
+
FIZZ
|
10 |
+
BUZZ
|
11 |
+
11
|
12 |
+
FIZZ
|
13 |
+
13
|
14 |
+
14
|
15 |
+
FIZZ BUZZ
|
16 |
+
16
|
17 |
+
17
|
18 |
+
FIZZ
|
19 |
+
19
|
20 |
+
BUZZ
|
21 |
+
FIZZ
|
22 |
+
22
|
23 |
+
23
|
24 |
+
FIZZ
|
25 |
+
BUZZ
|
26 |
+
26
|
27 |
+
FIZZ
|
28 |
+
28
|
29 |
+
29
|
30 |
+
FIZZ BUZZ
|
31 |
+
31
|
32 |
+
32
|
33 |
+
FIZZ
|
34 |
+
34
|
35 |
+
BUZZ
|
sum_of_two_million_primes.txt
ADDED
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
|
2 |
+
BEGIN
|
3 |
+
sum := 0;
|
4 |
+
FOR i := 2 ; i < 2000000 ; i := i + 1
|
5 |
+
DO
|
6 |
+
BEGIN
|
7 |
+
flag := 0;
|
8 |
+
FOR j := 2 ; j <= i@(1/2) ; j := j + 1
|
9 |
+
DO
|
10 |
+
BEGIN
|
11 |
+
IF i % j = 0
|
12 |
+
THEN
|
13 |
+
BEGIN
|
14 |
+
flag := 1;
|
15 |
+
BREAK;
|
16 |
+
END
|
17 |
+
ELSE
|
18 |
+
END
|
19 |
+
END
|
20 |
+
END;
|
21 |
+
IF flag = 0
|
22 |
+
THEN
|
23 |
+
BEGIN
|
24 |
+
{ PRINT i END;}
|
25 |
+
sum := sum + i;
|
26 |
+
END
|
27 |
+
ELSE
|
28 |
+
END
|
29 |
+
END
|
30 |
+
END;
|
31 |
+
PRINT sum END;
|
32 |
+
END
|
testing.py
ADDED
@@ -0,0 +1,90 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import lexer as lex
|
2 |
+
# import Parser as prs
|
3 |
+
from sim import *
|
4 |
+
import time
|
5 |
+
|
6 |
+
# Combining lexer parser
|
7 |
+
# text = "IF 2 > 1 THEN 3+5 ELSE 41 END"
|
8 |
+
# text = "a := 3"
|
9 |
+
# text = "BEGIN PRINT 4+4 END; PRINT 7 END; END"
|
10 |
+
# text = """
|
11 |
+
# BEGIN
|
12 |
+
# i:=1;
|
13 |
+
# j:=1;
|
14 |
+
# PRINT i END;
|
15 |
+
# WHILE i<6
|
16 |
+
# DO
|
17 |
+
# BEGIN
|
18 |
+
# j:=j*i;
|
19 |
+
# i:=i+1;
|
20 |
+
# PRINT j END;
|
21 |
+
# PRINT i END;
|
22 |
+
|
23 |
+
# END
|
24 |
+
# END;
|
25 |
+
# j:=j*i;
|
26 |
+
# PRINT j END;
|
27 |
+
# END"""
|
28 |
+
|
29 |
+
# text = """
|
30 |
+
# k:="stri";
|
31 |
+
# """
|
32 |
+
|
33 |
+
# text = "-2*(1---2)"
|
34 |
+
|
35 |
+
# text = """PRINT 3 < 6 && 4 < 3 END"""
|
36 |
+
|
37 |
+
# for i:= 1 to 10 by 1 do writeln(i);
|
38 |
+
# text = """BEGIN
|
39 |
+
# p:=1;
|
40 |
+
# q:=1;
|
41 |
+
# FOR i:= 1 TO 1560 BY i := i + 1
|
42 |
+
# DO
|
43 |
+
# BEGIN
|
44 |
+
# q:=q*p;
|
45 |
+
# p:=p+1;
|
46 |
+
# {PRINT p END;}
|
47 |
+
# PRINT q END;
|
48 |
+
# PRINT i END;
|
49 |
+
# END
|
50 |
+
# END;
|
51 |
+
# END"""
|
52 |
+
# text = """BEGIN
|
53 |
+
# IF 3 % 4 = 0 || 3 % 5 = 0 THEN BEGIN PRINT 5 END; END ELSE BEGIN PRINT 6 END; END END;
|
54 |
+
# IF 3 % 4 = 0 || 5 % 5 = 0 THEN BEGIN PRINT 5 END; END ELSE BEGIN PRINT 6 END; END END;
|
55 |
+
# IF 4 % 4 = 0 && 3 % 5 = 0 THEN BEGIN PRINT 5 END; END ELSE BEGIN PRINT 6 END; END END;
|
56 |
+
# END
|
57 |
+
# """
|
58 |
+
# text = """
|
59 |
+
# BEGIN
|
60 |
+
# p := 2;
|
61 |
+
# {PRINT 2@3@2 END;}
|
62 |
+
# PRINT 4@3@2 END;
|
63 |
+
# a:=3@2;
|
64 |
+
# {p := p @ 3;}
|
65 |
+
# PRINT 4@a END;
|
66 |
+
# PRINT a END;
|
67 |
+
# END
|
68 |
+
# """
|
69 |
+
start = time.time()
|
70 |
+
|
71 |
+
text = open("input.txt","r").read()
|
72 |
+
# text = "PRINT 3@(1/2) END"
|
73 |
+
# text = "3 > 4"
|
74 |
+
# text = "-2*(1---2)"
|
75 |
+
# text = "PRINT 2-+ +3 END"
|
76 |
+
# if len(text) != 0:
|
77 |
+
text = "BEGIN "+text+" END"
|
78 |
+
|
79 |
+
l = lex.Lexer(text)
|
80 |
+
p = prs.Parser(l)
|
81 |
+
i = Interpreter(p)
|
82 |
+
# print(eval(i))
|
83 |
+
|
84 |
+
eval(i)
|
85 |
+
# print(open("eval.txt").read()==open("solution.txt").read())
|
86 |
+
print("Time taken", time.time()-start)
|
87 |
+
|
88 |
+
# test_While()
|
89 |
+
# test_Logic()
|
90 |
+
# test_resolve()
|
type_checking.py
ADDED
@@ -0,0 +1,97 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
# from fractions import Fraction
|
2 |
+
# from dataclasses import dataclass
|
3 |
+
# from typing import Optional, NewType
|
4 |
+
from dataclasses_sim import *
|
5 |
+
# A minimal example to illustrate typechecking.
|
6 |
+
|
7 |
+
# @dataclass
|
8 |
+
# class NumType:
|
9 |
+
# pass
|
10 |
+
|
11 |
+
# @dataclass
|
12 |
+
# class BoolType:
|
13 |
+
# pass
|
14 |
+
|
15 |
+
# SimType = NumType | BoolType
|
16 |
+
|
17 |
+
# @dataclass
|
18 |
+
# class NumLiteral:
|
19 |
+
# value: Fraction
|
20 |
+
# # type: SimType = NumType()
|
21 |
+
|
22 |
+
# @dataclass
|
23 |
+
# class BoolLiteral:
|
24 |
+
# value: bool
|
25 |
+
# # type: SimType = BoolType()
|
26 |
+
|
27 |
+
# @dataclass
|
28 |
+
# class BinOp:
|
29 |
+
# operator: str
|
30 |
+
# left: 'AST'
|
31 |
+
# right: 'AST'
|
32 |
+
# # type: Optional[SimType] = None
|
33 |
+
|
34 |
+
# @dataclass
|
35 |
+
# class IfElse:
|
36 |
+
# condition: 'AST'
|
37 |
+
# iftrue: 'AST'
|
38 |
+
# iffalse: 'AST'
|
39 |
+
# # type: Optional[SimType] = None
|
40 |
+
|
41 |
+
# AST = NumLiteral | BoolLiteral | BinOp | IfElse
|
42 |
+
|
43 |
+
@dataclass
|
44 |
+
class TypeError(Exception):
|
45 |
+
pass
|
46 |
+
|
47 |
+
# Since we don't have variables, environment is not needed.
|
48 |
+
def typecheck(program: AST, env = None):
|
49 |
+
match program:
|
50 |
+
case NumLiteral() as t: # already typed.
|
51 |
+
return t
|
52 |
+
case BoolLiteral() as t: # already typed.
|
53 |
+
return t
|
54 |
+
case BinOp(op, left, right) if op in ["+", "*"]:
|
55 |
+
tleft = typecheck(left)
|
56 |
+
tright = typecheck(right)
|
57 |
+
|
58 |
+
print(isinstance(tleft, NumLiteral), isinstance(tright, NumLiteral))
|
59 |
+
if isinstance(tleft, NumLiteral) != True or isinstance(tright, NumLiteral) != True:
|
60 |
+
raise TypeError()
|
61 |
+
return NumLiteral();
|
62 |
+
|
63 |
+
|
64 |
+
# case BinOp("<", left, right):
|
65 |
+
# tleft = typecheck(left)
|
66 |
+
# tright = typecheck(right)
|
67 |
+
# if tleft.type != NumType() or tright.type != NumType():
|
68 |
+
# raise TypeError()
|
69 |
+
# return BinOp("<", left, right, BoolType())
|
70 |
+
# case BinOp("=", left, right):
|
71 |
+
# tleft = typecheck(left)
|
72 |
+
# tright = typecheck(right)
|
73 |
+
# if tleft.type != tright.type:
|
74 |
+
# raise TypeError()
|
75 |
+
# return BinOp("=", left, right, BoolType())
|
76 |
+
# case IfElse(c, t, f): # We have to typecheck both branches.
|
77 |
+
# tc = typecheck(c)
|
78 |
+
# if tc.type != BoolType():
|
79 |
+
# raise TypeError()
|
80 |
+
# tt = typecheck(t)
|
81 |
+
# tf = typecheck(f)
|
82 |
+
# if tt.type != tf.type: # Both branches must have the same type.
|
83 |
+
# raise TypeError()
|
84 |
+
# return IfElse(tc, tt, tf, tt.type) # The common type becomes the type of the if-else.
|
85 |
+
case _:
|
86 |
+
raise TypeError()
|
87 |
+
|
88 |
+
def test_typecheck():
|
89 |
+
# import pytest
|
90 |
+
typecheck(BinOp("+", NumLiteral(2), BoolLiteral(False)))
|
91 |
+
# assert te.type == NumType()
|
92 |
+
# te = typecheck(BinOp("<", NumLiteral(2), NumLiteral(3)))
|
93 |
+
# assert te.type == BoolType()
|
94 |
+
# with pytest.raises(TypeError):
|
95 |
+
# typecheck(BinOp("+", BinOp("*", NumLiteral(2), NumLiteral(3)), BinOp("<", NumLiteral(2), NumLiteral(3))))
|
96 |
+
|
97 |
+
# test_typecheck()
|
unresolved_tree
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
Unresolved Tree:
|
2 |
+
Seq(statements=[Statement(command='print',
|
3 |
+
statement=BinOp(operator='+',
|
4 |
+
left=NumLiteral(value=Fraction(3, 1)),
|
5 |
+
right=NumLiteral(value=Fraction(4, 1))))])
|