def visitUnaryExpression(self, ctx: CParser.UnaryExpressionContext): try: operator = Expression.UnaryOpTokens( self.visitUnaryOp(ctx.unaryOp())) operand = self.visitUnaryExpression(ctx.unaryExpression()) return Expression.UnaryOp(ctx.start.line, ctx.start.column, operator, operand) except: return self.visitChildren(ctx)
def visitTerm(self, ctx: CParser.TermContext): try: operator = Expression.BinOpTokens(self.visitMulOp(ctx.mulOp())) left = self.visitTerm(ctx.term()) right = self.visitUnaryExpression(ctx.unaryExpression()) return Expression.BinOp(ctx.start.line, ctx.start.column, operator, left, right) except: return self.visitChildren(ctx)
def visitRelExpression(self, ctx: CParser.RelExpressionContext): try: operator = Expression.BinOpTokens(self.visitRelOp(ctx.relOp())) left = self.visitSumExpression(ctx.sumExpression(0)) right = self.visitSumExpression(ctx.sumExpression(1)) return Expression.BinOp(ctx.start.line, ctx.start.column, operator, left, right) except: return self.visitChildren(ctx)
def visitMutable(self, ctx: CParser.MutableContext): try: return Expression.Mutable(ctx.start.line, ctx.start.column, ctx.Id().getText()) except: pass mutable = self.visitMutable(ctx.mutable()) expression = self.visitExpression(ctx.expression()) return Expression.SubScript(ctx.start.line, ctx.start.column, mutable, expression)
def visitAndExpression(self, ctx: CParser.AndExpressionContext): try: operator = Expression.BinOpTokens.AND left = self.visitAndExpression(ctx.andExpression()) right = self.visitUnaryRelExpression(ctx.unaryRelExpression()) return Expression.BinOp(ctx.start.line, ctx.start.column, operator, left, right) except: return self.visitChildren(ctx)
def visitExpression(self, ctx: CParser.ExpressionContext): try: left = self.visitMutable(ctx.mutable()) right = self.visitExpression(ctx.expression()) return Expression.Assign(ctx.start.line, ctx.start.column, left, right) except: pass try: return self.visitExpression(ctx.expression()) except: pass return self.visitChildren(ctx)
def solve(function: Expression, value=0, show_steps=False) -> Expression: """ Solve trivial Expression """ f = function.copy() s = ScalarReal(value) c = True while c: if show_steps: print(f, '=', s) s, f, c = counter(s, f) return s
def constantFolding(self, basicType, expression): if (isinstance(expression, Expression.BinOp)): if (basicType == "char"): if (isinstance(expression.left, Expression.BinOp)): leftPart = self.constantFolding(basicType, expression.left) if (isinstance(expression.right, Literals.String) or isinstance(expression.right, Literals.Char) or isinstance(expression.right, Literals.Int) or isinstance(expression.right, Literals.Double)): if (isinstance(leftPart, Expression.BinOp)): if (isinstance(leftPart.right, Literals.String) or isinstance(leftPart.right, Literals.Char) or isinstance(leftPart.right, Literals.Int) or isinstance(leftPart.right, Literals.Double)): rightPart = Literals.String( leftPart.right.lineNr, leftPart.right.positionNr, leftPart.right. value[0:len(leftPart.right.value) - 1] + expression.right.value[1:len(expression. right.value)]) return Expression.BinOp( expression.lineNr, expression.positionNr, expression.operator, leftPart.left, rightPart) else: expression.left = leftPart return expression else: return Literals.String( expression.lineNr, expression.positionNr, leftPart.value[0:len(leftPart.value) - 1] + expression.right.value[1:len(expression.right. value)]) else: expression.left = leftPart return expression else: if ((isinstance(expression.left, Literals.String) or isinstance(expression.left, Literals.Char) or isinstance(expression.left, Literals.Int) or isinstance(expression.left, Literals.Double)) and (isinstance(expression.right, Literals.String) or isinstance(expression.right, Literals.Char) or isinstance(expression.right, Literals.Int) or isinstance(expression.right, Literals.Double))): return Literals.String( expression.lineNr, expression.positionNr, expression.left. value[0:len(expression.left.value) - 1] + expression.right.value[1:len(expression.right.value )]) else: return expression elif (basicType == "int" or basicType == "signed" or basicType == "unsigned" or basicType == "long"): if (isinstance(expression.left, Expression.BinOp)): leftPart = self.constantFolding(basicType, expression.left) if (isinstance(expression.right, Literals.Int)): if (isinstance(leftPart, Expression.BinOp)): if (leftPart.operator.value == "+" or leftPart.operator.value == "-"): if (isinstance(leftPart.right, Literals.Int)): if (expression.operator.value == "+"): newValue = str( int(leftPart.right.value) + int(expression.right.value)) elif (expression.operator.value == "-"): newValue = str( int(leftPart.right.value) - int(expression.right.value)) elif (expression.operator.value == "*"): newValue = str( int( int(leftPart.right.value) * int(expression.right.value))) else: newValue = str( int( int(leftPart.right.value) / int(expression.right.value))) rightPart = Literals.Int( leftPart.right.lineNr, leftPart.right.positionNr, newValue) return Expression.BinOp( expression.lineNr, expression.positionNr, expression.operator, leftPart.left, rightPart) else: expression.left = leftPart return expression else: expression.left = leftPart return expression else: if (expression.operator.value == "+"): newValue = str( int(leftPart.value) + int(expression.right.value)) elif (expression.operator.value == "-"): newValue = str( int(leftPart.value) - int(expression.right.value)) elif (expression.operator.value == "*"): newValue = str( int( int(leftPart.value) * int(expression.right.value))) else: newValue = str( int( int(leftPart.value) / int(expression.right.value))) return Literals.Int(expression.lineNr, expression.positionNr, newValue) elif (isinstance(expression.right, Expression.BinOp)): rightPart = self.constantFolding( basicType, expression.right) if (isinstance(rightPart, Literals.Int)): if (isinstance(leftPart, Expression.BinOp)): if (isinstance(leftPart.right, Literals.Int)): if (expression.operator.value == "+"): newValue = str( int(leftPart.right.value) + int(rightPart.value)) elif (expression.operator.value == "-"): newValue = str( int(leftPart.right.value) - int(rightPart.value)) elif (expression.operator.value == "*"): newValue = str( int( int(leftPart.right.value) * int(rightPart.value))) else: newValue = str( int( int(leftPart.right.value) / int(rightPart.value))) rightPart = Literals.Int( leftPart.right.lineNr, leftPart.right.positionNr, newValue) return Expression.BinOp( expression.lineNr, expression.positionNr, expression.operator, leftPart.left, rightPart) else: expression.left = leftPart expression.right = rightPart return expression else: if (expression.operator.value == "+"): newValue = str( int(leftPart.value) + int(rightPart.value)) elif (expression.operator.value == "-"): newValue = str( int(leftPart.value) - int(rightPart.value)) elif (expression.operator.value == "*"): newValue = str( int( int(leftPart.value) * int(rightPart.value))) else: newValue = str( int( int(leftPart.value) / int(rightPart.value))) return Literals.Int(expression.lineNr, expression.positionNr, newValue) else: expression.left = leftPart expression.right = rightPart return expression else: expression.left = leftPart return expression else: if (isinstance(expression.left, Literals.Int)): if (isinstance(expression.right, Literals.Int)): if (expression.operator.value == "+"): newValue = str( int(expression.left.value) + int(expression.right.value)) elif (expression.operator.value == "-"): newValue = str( int(expression.left.value) - int(expression.right.value)) elif (expression.operator.value == "*"): newValue = str( int( int(expression.left.value) * int(expression.right.value))) else: newValue = str( int( int(expression.left.value) / int(expression.right.value))) return Literals.Int(expression.lineNr, expression.positionNr, newValue) elif (isinstance(expression.right, Expression.BinOp)): rightPart = self.constantFolding( basicType, expression.right) if (isinstance(rightPart, Literals.Int)): if (expression.operator.value == "+"): newValue = str( int(expression.left.value) + int(rightPart.value)) elif (expression.operator.value == "-"): newValue = str( int(expression.left.value) - int(rightPart.value)) elif (expression.operator.value == "*"): newValue = str( int( int(expression.left.value) * int(rightPart.value))) else: newValue = str( int( int(expression.left.value) / int(rightPart.value))) return Literals.Int(expression.lineNr, expression.positionNr, newValue) else: expression.right = rightPart return expression else: return expression else: if (isinstance(expression.right, Expression.BinOp)): expression.right = self.constantFolding( basicType, expression.right) return expression else: if (isinstance(expression.left, Expression.BinOp)): leftPart = self.constantFolding(basicType, expression.left) if (isinstance(expression.right, Literals.Double)): if (isinstance(leftPart, Expression.BinOp)): if (isinstance(leftPart.right, Literals.Double)): if (expression.operator.value == "+"): newValue = str( float(leftPart.right.value) + float(expression.right.value)) elif (expression.operator.value == "-"): newValue = str( float(leftPart.right.value) - float(expression.right.value)) elif (expression.operator.value == "*"): newValue = str( float(leftPart.right.value) * float(expression.right.value)) else: newValue = str( float(leftPart.right.value) / float(expression.right.value)) rightPart = Literals.Double( leftPart.right.lineNr, leftPart.right.positionNr, newValue) return Expression.BinOp( expression.lineNr, expression.positionNr, expression.operator, leftPart.left, rightPart) else: expression.left = leftPart return expression else: if (expression.operator.value == "+"): newValue = str( float(leftPart.value) + float(expression.right.value)) elif (expression.operator.value == "-"): newValue = str( float(leftPart.value) - float(expression.right.value)) elif (expression.operator.value == "*"): newValue = str( float(leftPart.value) * float(expression.right.value)) else: newValue = str( float(leftPart.value) / float(expression.right.value)) return Literals.Double(expression.lineNr, expression.positionNr, newValue) elif (isinstance(expression.right, Expression.BinOp)): rightPart = self.constantFolding( basicType, expression.right) if (isinstance(rightPart, Literals.Double)): if (isinstance(leftPart, Expression.BinOp)): if (isinstance(leftPart.right, Literals.Double)): if (expression.operator.value == "+"): newValue = str( float(leftPart.right.value) + float(rightPart.value)) elif (expression.operator.value == "-"): newValue = str( float(leftPart.right.value) - float(rightPart.value)) elif (expression.operator.value == "*"): newValue = str( float(leftPart.right.value) * float(rightPart.value)) else: newValue = str( float(leftPart.right.value) / float(rightPart.value)) rightPart = Literals.Double( leftPart.right.lineNr, leftPart.right.positionNr, newValue) return Expression.BinOp( expression.lineNr, expression.positionNr, expression.operator, leftPart.left, rightPart) else: expression.left = leftPart expression.right = rightPart return expression else: if (expression.operator.value == "+"): newValue = str( float(leftPart.value) + float(rightPart.value)) elif (expression.operator.value == "-"): newValue = str( float(leftPart.value) - float(rightPart.value)) elif (expression.operator.value == "*"): newValue = str( float(leftPart.value) * float(rightPart.value)) else: newValue = str( float(leftPart.value) / float(rightPart.value)) return Literals.Double(expression.lineNr, expression.positionNr, newValue) else: expression.left = leftPart expression.right = rightPart return expression else: expression.left = leftPart return expression else: if (isinstance(expression.left, Literals.Double)): if (isinstance(expression.right, Literals.Double)): if (expression.operator.value == "+"): newValue = str( float(expression.left.value) + float(expression.right.value)) elif (expression.operator.value == "-"): newValue = str( float(expression.left.value) - float(expression.right.value)) elif (expression.operator.value == "*"): newValue = str( float(expression.left.value) * float(expression.right.value)) else: newValue = str( float(expression.left.value) / float(expression.right.value)) return Literals.Double(expression.lineNr, expression.positionNr, newValue) elif (isinstance(expression.right, Expression.BinOp)): rightPart = self.constantFolding( basicType, expression.right) if (isinstance(rightPart, Literals.Double)): if (expression.operator.value == "+"): newValue = str( float(expression.left.value) + float(rightPart.value)) elif (expression.operator.value == "-"): newValue = str( float(expression.left.value) - float(rightPart.value)) elif (expression.operator.value == "*"): newValue = str( float(expression.left.value) * float(rightPart.value)) else: newValue = str( float(expression.left.value) / float(rightPart.value)) return Literals.Double(expression.lineNr, expression.positionNr, newValue) else: expression.right = rightPart return expression else: return expression else: if (isinstance(expression.right, Expression.BinOp)): expression.right = self.constantFolding( basicType, expression.right) return expression else: return expression
def visitCall(self, ctx: CParser.CallContext): funcName = ctx.Id().getText() args = self.visitArgs(ctx.args()) return Expression.Call(ctx.start.line, ctx.start.column, funcName, args)
def expression_fn(s, l, t): return Expression(t[0])