karthik1019 commited on
Commit
16f1442
1 Parent(s): 86ce59b

Upload 25 files

Browse files
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))))])