|
1 |
| -# from antlr4 import ParserRuleContext |
| 1 | +import sys |
| 2 | +from copy import deepcopy |
| 3 | + |
2 | 4 | from generated.MyParser import MyParser
|
3 | 5 | from generated.MyParserVisitor import MyParserVisitor
|
| 6 | +from utils.values import Int, Float, String, Vector |
4 | 7 |
|
5 | 8 |
|
6 | 9 | class Interpreter(MyParserVisitor):
|
7 |
| - def visitProgram(self, ctx: MyParser.ProgramContext): |
8 |
| - print("Program") |
9 |
| - return self.visitChildren(ctx) |
10 |
| - |
11 | 10 | 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 |
16 | 12 |
|
17 | 13 | 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_()) |
19 | 19 |
|
20 | 20 | 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()) |
25 | 22 |
|
26 | 23 | def visitElse(self, ctx: MyParser.ElseContext):
|
27 |
| - return self.visitChildren(ctx) |
| 24 | + return self.visit(ctx.statement()) |
28 | 25 |
|
29 | 26 | def visitForLoop(self, ctx: MyParser.ForLoopContext):
|
30 |
| - return self.visitChildren(ctx) |
| 27 | + return self.visitChildren(ctx) # todo |
31 | 28 |
|
32 | 29 | def visitRange(self, ctx: MyParser.RangeContext):
|
33 |
| - return self.visitChildren(ctx) |
| 30 | + return self.visitChildren(ctx) # todo |
34 | 31 |
|
35 | 32 | def visitWhileLoop(self, ctx: MyParser.WhileLoopContext):
|
36 |
| - return self.visitChildren(ctx) |
| 33 | + return self.visitChildren(ctx) # todo |
37 | 34 |
|
38 | 35 | 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 |
40 | 51 |
|
41 | 52 | def visitSimpleAssignment(self, ctx: MyParser.SimpleAssignmentContext):
|
42 |
| - return self.visitChildren(ctx) |
| 53 | + return self.visitChildren(ctx) # todo |
43 | 54 |
|
44 | 55 | def visitCompoundAssignment(self, ctx: MyParser.CompoundAssignmentContext):
|
45 |
| - return self.visitChildren(ctx) |
| 56 | + return self.visitChildren(ctx) # todo |
46 | 57 |
|
47 | 58 | 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)))) |
49 | 61 |
|
50 | 62 | 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() |
52 | 69 |
|
53 | 70 | 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 |
55 | 83 |
|
56 | 84 | def visitParenthesesExpression(self, ctx: MyParser.ParenthesesExpressionContext):
|
57 |
| - return self.visitChildren(ctx) |
| 85 | + return self.visit(ctx.expression()) |
58 | 86 |
|
59 | 87 | 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() |
61 | 92 |
|
62 | 93 | 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()) |
67 | 95 |
|
68 | 96 | 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 |
70 | 118 |
|
71 | 119 | def visitBreak(self, ctx: MyParser.BreakContext):
|
72 |
| - return self.visitChildren(ctx) |
| 120 | + return self.visitChildren(ctx) # todo |
73 | 121 |
|
74 | 122 | def visitContinue(self, ctx: MyParser.ContinueContext):
|
75 |
| - return self.visitChildren(ctx) |
| 123 | + return self.visitChildren(ctx) # todo |
76 | 124 |
|
77 | 125 | 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) |
79 | 130 |
|
80 | 131 | def visitElementReference(self, ctx: MyParser.ElementReferenceContext):
|
81 |
| - return self.visitChildren(ctx) |
| 132 | + return self.visitChildren(ctx) # todo |
82 | 133 |
|
83 | 134 | def visitId(self, ctx: MyParser.IdContext):
|
84 |
| - return self.visitChildren(ctx) |
| 135 | + return self.visitChildren(ctx) # todo |
85 | 136 |
|
86 | 137 | def visitInt(self, ctx: MyParser.IntContext):
|
87 |
| - return self.visitChildren(ctx) |
| 138 | + return Int(ctx.getText()) |
88 | 139 |
|
89 | 140 | def visitFloat(self, ctx: MyParser.FloatContext):
|
90 |
| - return self.visitChildren(ctx) |
| 141 | + return Float(ctx.getText()) |
91 | 142 |
|
92 | 143 | def visitString(self, ctx: MyParser.StringContext):
|
93 |
| - return self.visitChildren(ctx) |
| 144 | + return String(ctx.getText()) |
0 commit comments