Skip to content

Commit ef43a2f

Browse files
authored
Merge pull request #9 from mdbrnowski/interpretation
Interpretation without loops and variables
2 parents 96cdc8b + 4d7f495 commit ef43a2f

16 files changed

+344
-77
lines changed

MyLexer.g4

+3-3
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@ ASSIGN_MINUS : '-=';
2626
ASSIGN_MULTIPLY : '*=';
2727
ASSIGN_DIVIDE : '/=';
2828

29-
LE : '<';
30-
GE : '>';
29+
LT : '<';
30+
GT : '>';
3131
EQ : '==';
32-
NE : '!=';
32+
NEQ : '!=';
3333
LEQ : '<=';
3434
GEQ : '>=';
3535

MyParser.g4

+1-1
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ whileLoop
5353
;
5454

5555
comparison
56-
: expression (LE | GE | EQ | NE | LEQ | GEQ) expression
56+
: expression (EQ | NEQ | LT | GT | LEQ | GEQ) expression
5757
;
5858

5959
assignment

generated/MyLexer.interp

+6-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

generated/MyLexer.py

+6-6
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

generated/MyLexer.tokens

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

generated/MyParser.interp

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

generated/MyParser.py

+12-12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

generated/MyParser.tokens

+3-3
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

interpreter.py

+90-39
Original file line numberDiff line numberDiff line change
@@ -1,93 +1,144 @@
1-
# from antlr4 import ParserRuleContext
1+
import sys
2+
from copy import deepcopy
3+
24
from generated.MyParser import MyParser
35
from generated.MyParserVisitor import MyParserVisitor
6+
from utils.values import Int, Float, String, Vector
47

58

69
class Interpreter(MyParserVisitor):
7-
def visitProgram(self, ctx: MyParser.ProgramContext):
8-
print("Program")
9-
return self.visitChildren(ctx)
10-
1110
def visitScopeStatement(self, ctx: MyParser.ScopeStatementContext):
12-
return self.visitChildren(ctx)
13-
14-
def visitSimpleStatement(self, ctx: MyParser.SimpleStatementContext):
15-
return self.visitChildren(ctx)
11+
return self.visitChildren(ctx) # todo
1612

1713
def visitIfThenElse(self, ctx: MyParser.IfThenElseContext):
18-
return self.visitChildren(ctx)
14+
condition = self.visit(ctx.if_())
15+
if condition:
16+
return self.visit(ctx.then())
17+
elif ctx.else_() is not None:
18+
return self.visit(ctx.else_())
1919

2020
def visitIf(self, ctx: MyParser.IfContext):
21-
return self.visitChildren(ctx)
22-
23-
def visitThen(self, ctx: MyParser.ThenContext):
24-
return self.visitChildren(ctx)
21+
return self.visit(ctx.comparison())
2522

2623
def visitElse(self, ctx: MyParser.ElseContext):
27-
return self.visitChildren(ctx)
24+
return self.visit(ctx.statement())
2825

2926
def visitForLoop(self, ctx: MyParser.ForLoopContext):
30-
return self.visitChildren(ctx)
27+
return self.visitChildren(ctx) # todo
3128

3229
def visitRange(self, ctx: MyParser.RangeContext):
33-
return self.visitChildren(ctx)
30+
return self.visitChildren(ctx) # todo
3431

3532
def visitWhileLoop(self, ctx: MyParser.WhileLoopContext):
36-
return self.visitChildren(ctx)
33+
return self.visitChildren(ctx) # todo
3734

3835
def visitComparison(self, ctx: MyParser.ComparisonContext):
39-
return self.visitChildren(ctx)
36+
a = self.visit(ctx.expression(0))
37+
b = self.visit(ctx.expression(1))
38+
match ctx.getChild(1).symbol.type:
39+
case MyParser.EQ:
40+
return a == b
41+
case MyParser.NEQ:
42+
return a != b
43+
case MyParser.LT:
44+
return a < b
45+
case MyParser.LEQ:
46+
return a <= b
47+
case MyParser.GT:
48+
return a > b
49+
case MyParser.GEQ:
50+
return a >= b
4051

4152
def visitSimpleAssignment(self, ctx: MyParser.SimpleAssignmentContext):
42-
return self.visitChildren(ctx)
53+
return self.visitChildren(ctx) # todo
4354

4455
def visitCompoundAssignment(self, ctx: MyParser.CompoundAssignmentContext):
45-
return self.visitChildren(ctx)
56+
return self.visitChildren(ctx) # todo
4657

4758
def visitPrint(self, ctx: MyParser.PrintContext):
48-
return self.visitChildren(ctx)
59+
for i in range(ctx.getChildCount() // 2):
60+
print(str(self.visit(ctx.expression(i))))
4961

5062
def visitReturn(self, ctx: MyParser.ReturnContext):
51-
return self.visitChildren(ctx)
63+
if ctx.expression() is not None:
64+
return_value = self.visit(ctx.expression())
65+
if not isinstance(return_value, Int):
66+
raise TypeError
67+
sys.exit(return_value.value)
68+
sys.exit()
5269

5370
def visitBinaryExpression(self, ctx: MyParser.BinaryExpressionContext):
54-
return self.visitChildren(ctx)
71+
a = self.visit(ctx.expression(0))
72+
b = self.visit(ctx.expression(1))
73+
match ctx.op.type:
74+
case MyParser.PLUS:
75+
return a + b
76+
case MyParser.MINUS:
77+
return a - b
78+
case MyParser.MULTIPLY:
79+
return a * b
80+
case MyParser.DIVIDE:
81+
return a / b
82+
# todo: MAT_* operations
5583

5684
def visitParenthesesExpression(self, ctx: MyParser.ParenthesesExpressionContext):
57-
return self.visitChildren(ctx)
85+
return self.visit(ctx.expression())
5886

5987
def visitTransposeExpression(self, ctx: MyParser.TransposeExpressionContext):
60-
return self.visitChildren(ctx)
88+
vector = self.visit(ctx.expression())
89+
if not isinstance(vector, Vector):
90+
raise TypeError
91+
return vector.transpose()
6192

6293
def visitMinusExpression(self, ctx: MyParser.MinusExpressionContext):
63-
return self.visitChildren(ctx)
64-
65-
def visitSingleExpression(self, ctx: MyParser.SingleExpressionContext):
66-
return self.visitChildren(ctx)
94+
return -self.visit(ctx.expression())
6795

6896
def visitSpecialMatrixFunction(self, ctx: MyParser.SpecialMatrixFunctionContext):
69-
return self.visitChildren(ctx)
97+
fname = ctx.getChild(0).symbol.type
98+
if fname == MyParser.EYE:
99+
dim = self.visit(ctx.expression(0))
100+
if not isinstance(dim, Int):
101+
raise TypeError
102+
rows = [
103+
Vector([Int(i == j) for j in range(dim.value)])
104+
for i in range(dim.value)
105+
]
106+
return Vector(rows)
107+
else:
108+
dims = [
109+
self.visit(ctx.expression(i))
110+
for i in range(ctx.getChildCount() // 2 - 1)
111+
]
112+
if {type(dim) for dim in dims} != {Int}:
113+
raise TypeError
114+
vector = {MyParser.ZEROS: Int(0), MyParser.ONES: Int(1)}[fname]
115+
for dim in reversed(dims):
116+
vector = Vector([deepcopy(vector) for _ in range(dim.value)])
117+
return vector
70118

71119
def visitBreak(self, ctx: MyParser.BreakContext):
72-
return self.visitChildren(ctx)
120+
return self.visitChildren(ctx) # todo
73121

74122
def visitContinue(self, ctx: MyParser.ContinueContext):
75-
return self.visitChildren(ctx)
123+
return self.visitChildren(ctx) # todo
76124

77125
def visitVector(self, ctx: MyParser.VectorContext):
78-
return self.visitChildren(ctx)
126+
elements = [
127+
self.visit(ctx.expression(i)) for i in range(ctx.getChildCount() // 2)
128+
]
129+
return Vector(elements)
79130

80131
def visitElementReference(self, ctx: MyParser.ElementReferenceContext):
81-
return self.visitChildren(ctx)
132+
return self.visitChildren(ctx) # todo
82133

83134
def visitId(self, ctx: MyParser.IdContext):
84-
return self.visitChildren(ctx)
135+
return self.visitChildren(ctx) # todo
85136

86137
def visitInt(self, ctx: MyParser.IntContext):
87-
return self.visitChildren(ctx)
138+
return Int(ctx.getText())
88139

89140
def visitFloat(self, ctx: MyParser.FloatContext):
90-
return self.visitChildren(ctx)
141+
return Float(ctx.getText())
91142

92143
def visitString(self, ctx: MyParser.StringContext):
93-
return self.visitChildren(ctx)
144+
return String(ctx.getText())

semantic_listener.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ def exitComparison(self, ctx: MyParser.ComparisonContext):
7878
if not (
7979
children_types <= {Type.INT, Type.FLOAT}
8080
or (
81-
ctx.getChild(1).symbol.type in {MyParser.EQ, MyParser.NE}
81+
ctx.getChild(1).symbol.type in {MyParser.EQ, MyParser.NEQ}
8282
and children_types <= {Type.STRING}
8383
)
8484
):

0 commit comments

Comments
 (0)