def get_const(self): self.constL = self.exprL.get_const() if self.constL is None: return None self.typeL = self.exprL.type if self.typeL not in ["boolean", "int"]: raise compileException( f"left side of {self.op} is not boolean/int :C", self.line) cL = self.constL if (self.exprL.type == "int"): cL = self.constL != 0 if cL == False: return False self.constR = self.exprR.get_const() if self.constR is None: return None self.typeR = self.exprR.type if self.typeR not in ["boolean", "int"]: raise compileException( f"right side of {self.op} is not boolean/int :C", self.line) cR = self.constR if (self.exprR.type == "int"): cR = self.constR != 0 self.const = cR and cL return self.const
def get_const(self): if self.constL is None or self.constR is None: return None self.typeL = self.exprL.type self.typeR = self.exprR.type if self.typeL == "void": raise compileException(f"left side of {self.op} is void :C",self.line) if self.typeR == "void": raise compileException(f"right side of {self.op} is void :C",self.line) if self.typeL != self.typeR and (self.typeL == 'string' or self.typeR == 'string'): raise compileException(f"mismach of types in ({self.op}) operator: left side: {self.typeL} right side: {self.typeR} :C",self.line) if self.typeL != self.typeR and (self.typeL == 'string' or self.typeR == 'string'): raise compileException(f"mismach of types in ({self.op}) operator: left side: {self.typeL} right side: {self.typeR} :C",self.line) if self.op == '<': self.const = self.constL < self.constR if self.op == '<=': self.const = self.constL <= self.constR if self.op == '>': self.const = self.constL > self.constR if self.op == '>=': self.const = self.constL >= self.constR if self.op == '==': self.const = self.constL == self.constR if self.op == '!=': self.const = self.constL != self.constR return self.const
def checkType(self, s): self.type = self.expr.checkType(s) # print(f"OP = {self.op}\n") if self.op == '-' and self.type != 'int': raise compileException( f"operator (-) cant be used with type {self.type} should be int :C", self.line) if self.op == '!' and self.type != 'boolean': raise compileException( f"operator (!) cant be used with type {self.type} should be boolean :C", self.line) return self.type
def checkType(self, s): # s.text() expr_type = self.expr.checkType(s) var = s.find(self.name) if var is None: raise compileException(f"Variable {self.name} not defined :C", self.line) if var.type != expr_type: raise compileException( f"mismach of types in assigment: varible type = {var.type} expresion = {expr_type} :C", self.line)
def checkType(self, s): self.typeL = self.exprL.checkType(s) self.typeR = self.exprR.checkType(s) # print(f"OP = {self.op}\n") if self.typeL not in ["boolean", "int"]: raise compileException( f"left side of {self.op} is not boolean/int :C", self.line) if self.typeR not in ["boolean", "int"]: raise compileException( f"right side of {self.op} is not boolean/int :C", self.line) return self.type
def checkType(self, s): type = s.find(self.name).type if type is None: raise compileException(f"Variable {self.name} not defined :C", self.line) if type != "int" and self.stmt_type == "Inc": raise compileException( f"Variable {self.name} of type {type} cant be increded (++) :C", self.line) if type != "int" and self.stmt_type == "Dec": raise compileException( f"Variable {self.name} of type {type} cant be decreded (--) :C", self.line)
def addTopDef(self, s): types = [] args_names = [] for arg in self.args: if arg.name in args_names: raise compileException(f"Argument {arg.name} repeated :C", self.line) args_names.append(arg.name) if arg.type == 'void': raise compileException( f"Argument {arg.name} cant be void type :C", self.line) types.append(arg.type) s.add_fun(self.name, types, self)
def checkType(self, s): self.typeL = self.exprL.checkType(s) self.typeR = self.exprR.checkType(s) # print(f"OP = {self.op}\n") if self.typeL == "void": raise compileException(f"left side of {self.op} is void :C",self.line) if self.typeR == "void": raise compileException(f"right side of {self.op} is void :C",self.line) if self.typeL != self.typeR and (self.typeL == 'string' or self.typeR == 'string'): raise compileException(f"mismach of types in ({self.op}) operator: left side: {self.typeL} right side: {self.typeR} :C",self.line) self.type = 'boolean' return self.type
def checkReturn(self, s, fun): bTret = self.blockTrue.checkReturn(s, fun) bFret = None if self.blockFalse is not None: bFret = self.blockFalse.checkReturn(s, fun) # print(f"True bloak type = {bTret}\n") # print(f"False bloak type = {bFret}\n") if self.expr.const is not None and self.expr.const == True: self.return_type = bTret return bTret if self.expr.const is not None and self.expr.const == False: self.return_type = bFret return bFret if bFret is None or bTret is None: self.return_type = None return None if bFret == 'inf': self.return_type = bTret return self.return_type if bTret == 'inf': self.return_type = bFret return self.return_type if bTret != bFret: raise compileException( f"Wrong return type in function {fun.name}: {bFret} or {bTret} :C", self.line) self.return_type = bTret return self.return_type
def checkType(self, s): expr_type = self.expr.checkType(s) if expr_type not in ["int", "boolean"]: raise compileException( f"Condition must bo of type int/boolean cant be {expr_type} :C", self.line) self.block.checkType(s)
def checkType(self, s): # print ( f" {self.name} -> {s.find(self.name)} \n" ) var = s.find(self.name) if var is None: raise compileException(f"Variable {self.name} not defined :C", self.line) self.type = var.type return self.type
def addYourself(self, s): types = [] args_names = [] for arg in self.args: s.add(arg.name, arg) if arg.type == 'void': raise compileException( f"Argument {arg.name} cant be void type :C", self.line) types.append(arg.type)
def checkType(self, s): args_type = [] for expr in self.exprs: expr_type = expr.checkType(s) args_type.append(expr_type) fun = s.find_fun(self.name, args_type) if fun is None: raise compileException( f"function {self.name} with arguments of types: {args_type} wasnt declared :C", self.line) self.type = fun.type return self.type
def get_const(self): expr_const = self.expr.get_const() if expr_const is None: return None self.type = self.expr.type if self.op == '-': if self.type != 'int': raise compileException( f"operator (-) cant be used with type {self.type} should be int :C", self.line) else: self.const = -expr_const if self.op == '!': if self.type != 'boolean': raise compileException( f"operator (!) cant be used with type {self.type} should be boolean :C", self.line) else: self.const = not expr_const return self.const
def checkType(self, s): # self.text() self.typeL = self.exprL.checkType(s) self.typeR = self.exprR.checkType(s) # print ( f"L = {self.typeL} R = {self.typeR}\n" ) self.type = 'void' # print(f"OP = {self.op}\n") if self.typeL == "void": raise compileException(f"left side of {self.op} is void :C",self.line) if self.typeR == "void": raise compileException(f"right side of {self.op} is void :C",self.line) if self.typeL != self.typeR: raise compileException(f"mismach of types in ({self.op}) operator: left side: {self.typeL} right side: {self.typeR} :C",self.line) if self.op in ['-', '*','/','%'] and self.typeL != "int": raise compileException(f"operator {self.op} cant be used with type {self.typeL} and {self.typeL} should be int :C",self.line) if self.op == '+' and ( self.typeL != 'int' and self.typeL != 'string' ): raise compileException(f"operator (+) cant be used with type {self.type} should be int/string :C",self.line) self.type = self.typeL return self.type
def get_const(self): if self.constL is None or self.constR is None: return None self.typeL = self.exprL.type self.typeR = self.exprR.type self.type = self.typeL if self.typeL == "void": raise compileException(f"left side of {self.op} is void :C",self.line) if self.typeR == "void": raise compileException(f"right side of {self.op} is void :C",self.line) if self.typeL != self.typeR: raise compileException(f"mismach of types in ({self.op}) operator: left side: {self.typeL} right side: {self.typeR} :C",self.line) if self.op in ['-', '*','/','%'] and self.typeL != "int": raise compileException(f"operator {self.op} cant be used with type {self.typeL} and {self.typeL} should be int :C",self.line) if self.op == '+' and ( self.typeL != 'int' and self.typeL != 'string' ): raise compileException(f"operator (+) cant be used with type {self.type} should be int/string :C",self.line) if self.op == '+': self.const = self.constL + self.constR if self.op == '-': self.const = self.constL - self.constR if self.op == '*': self.const = self.constL * self.constR if self.constR == 0: raise compileException(f"operator {self.op} division by 0 :C",self.line) if self.op == '/': self.const = self.constL // self.constR if self.op == '%': self.const = self.constL % self.constR if self.constL < 0 and self.constR > 0: self.const = self.const - self.constR return self.const