Beispiel #1
0
    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
Beispiel #2
0
    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
Beispiel #3
0
 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
Beispiel #4
0
    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)
Beispiel #5
0
    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
Beispiel #6
0
 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)
Beispiel #7
0
    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)
Beispiel #8
0
    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   
Beispiel #9
0
    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
Beispiel #10
0
 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)
Beispiel #11
0
 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
Beispiel #12
0
 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)
Beispiel #13
0
 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
Beispiel #14
0
    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
Beispiel #15
0
    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 
Beispiel #16
0
    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