Advertisement
minh_tran_782

PROGRAMMING CODE: TYPE

Mar 21st, 2023
1,178
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 18.35 KB | None | 0 0
  1. class Type(ABC): pass
  2. class IntType(Type): pass
  3. class FloatType(Type):pass
  4. class BoolType(Type): pass
  5.  
  6. class StaticCheck(Visitor):
  7.     def visitBinOp(self,ctx:BinOp,o):
  8.         ltype = self.visit(ctx.e1,o)
  9.         rtype = self.visit(ctx.e2,o)
  10.         ret = ltype
  11.         if type(ltype) != type(rtype):
  12.             if BoolType in [type(ltype),type(rtype)]:
  13.                 raise TypeMismatchInExpression(ctx)
  14.             else:
  15.                 ret = FloatType()
  16.         if ctx.op in ['+','-','*','/']:
  17.             if type(ret) is BoolType: raise TypeMismatchInExpression(ctx)
  18.             elif ctx.op == '/': return FloatType()
  19.             else: return ret
  20.         elif ctx.op in ["&&","||"]:
  21.             if type(ret) is not BoolType: raise TypeMismatchInExpression(ctx)
  22.             else: return ret
  23.         elif type(ltype) is not type(rtype): raise TypeMismatchInExpression(ctx)
  24.         else: return BoolType()
  25.  
  26.     def visitUnOp(self,ctx:UnOp,o):
  27.         typ = self.visit(ctx.e,o)
  28.         if (ctx.op == "-" and type(typ) is BoolType) or (ctx.op == "!" and type(typ) is not BoolType):
  29.             raise TypeMismatchInExpression(ctx)
  30.         else:
  31.             return typ
  32.  
  33.     def visitIntLit(self,ctx:IntLit,o): return IntType()
  34.  
  35.     def visitFloatLit(self,ctx,o): return FloatType()
  36.  
  37.     def visitBoolLit(self,ctx,o): return BoolType()
  38. #############################
  39. class StaticCheck(Visitor):
  40.     def visitProgram(self,ctx,o):
  41.         self.visit(ctx.exp,ctx.decl)
  42.     def visitBinOp(self,ctx:BinOp,o):
  43.         ltype = self.visit(ctx.e1,o)
  44.         rtype = self.visit(ctx.e2,o)
  45.         ret = ltype
  46.         if type(ltype) != type(rtype):
  47.             if BoolType in [type(ltype),type(rtype)]:
  48.                 raise TypeMismatchInExpression(ctx)
  49.             else:
  50.                 ret = FloatType()
  51.         if ctx.op in ['+','-','*','/']:
  52.             if type(ret) is BoolType: raise TypeMismatchInExpression(ctx)
  53.             elif ctx.op == '/': return FloatType()
  54.             else: return ret
  55.         elif ctx.op in ["&&","||"]:
  56.             if type(ret) is not BoolType: raise TypeMismatchInExpression(ctx)
  57.             else: return ret
  58.         elif type(ltype) is not type(rtype): raise TypeMismatchInExpression(ctx)
  59.         else: return BoolType()
  60.  
  61.     def visitUnOp(self,ctx:UnOp,o):
  62.         typ = self.visit(ctx.e,o)
  63.         if (ctx.op == "-" and type(typ) is BoolType) or (ctx.op == "!" and type(typ) is not BoolType):
  64.             raise TypeMismatchInExpression(ctx)
  65.         else:
  66.             return typ
  67.  
  68.     def visitIntLit(self,ctx:IntLit,o): return IntType()
  69.  
  70.     def visitFloatLit(self,ctx,o): return FloatType()
  71.  
  72.     def visitBoolLit(self,ctx,o): return BoolType()
  73.    
  74.     def visitId(self,ctx,o):
  75.         typ = None
  76.         for x in o:
  77.             if x.name == ctx.name:
  78.                 typ = x.typ
  79.                 break
  80.         if not typ:
  81.             raise UndeclaredIdentifier(ctx.name)
  82.         return typ
  83. ###############################
  84. class StaticCheck(Visitor):
  85.     def visitProgram(self,ctx:Program,o):
  86.         o = {}
  87.         [self.visit(i, o) for i in ctx.decl]
  88.         [self.visit(i, o) for i in ctx.stmts]
  89.  
  90.     def visitVarDecl(self,ctx:VarDecl,o):
  91.         o[ctx.name] = 0
  92.  
  93.     def visitAssign(self,ctx:Assign,o):
  94.         right = self.visit(ctx.rhs, o)
  95.         left = self.visit(ctx.lhs, o)
  96.        
  97.         if left == 0 and right != 0:
  98.             o[ctx.lhs.name] = right
  99.         if left != 0 and right == 0:
  100.             o[ctx.rhs.name] = left
  101.         if left == 0 and right == 0:
  102.             raise TypeCannotBeInferred(ctx)
  103.         if self.visit(ctx.lhs, o) != self.visit(ctx.rhs, o):
  104.             raise TypeMismatchInStatement(ctx)
  105.  
  106.     def visitBinOp(self,ctx:BinOp,o):
  107.         left = self.visit(ctx.e1, o)
  108.         right = self.visit(ctx.e2, o)
  109.         op = ctx.op
  110.        
  111.         if op in ['+', '-', '*', '/']:
  112.             # Type not inferred
  113.             if left == 0:
  114.                 o[ctx.e1.name] = 1
  115.             if right == 0:
  116.                 o[ctx.e2.name] = 1
  117.             # Either of e1 or e2 not in int
  118.             if self.visit(ctx.e1, o) != 1 or self.visit(ctx.e2, o) != 1:
  119.                 raise TypeMismatchInExpression(ctx)
  120.             else:
  121.                 # return Int
  122.                 return 1
  123.                
  124.         elif op in ['+.', '-.', '*.', '/.']:
  125.             if left == 0:
  126.                 o[ctx.e1.name] = 2
  127.             if right == 0:
  128.                 o[ctx.e2.name] = 2
  129.             if self.visit(ctx.e1, o) != 2 or self.visit(ctx.e2, o) != 2:
  130.                 raise TypeMismatchInExpression(ctx)
  131.             else:
  132.                 # return Float
  133.                 return 2
  134.                
  135.         elif op in ['>', '=']:
  136.             if left == 0:
  137.                 o[ctx.e1.name] = 1
  138.             if right == 0:
  139.                 o[ctx.e2.name] = 1
  140.             # Either of e1 or e2 not in int
  141.             if self.visit(ctx.e1, o) != 1 or self.visit(ctx.e2, o) != 1:
  142.                 raise TypeMismatchInExpression(ctx)
  143.             else:
  144.                 # return Bool
  145.                 return 3
  146.                
  147.         elif op in ['>.', '=.']:
  148.             if left == 0:
  149.                 o[ctx.e1.name] = 2
  150.             if right == 0:
  151.                 o[ctx.e2.name] = 2
  152.             if self.visit(ctx.e1, o) != 2 or self.visit(ctx.e2, o) != 2:
  153.                 raise TypeMismatchInExpression(ctx)
  154.             else:
  155.                 # return Bool
  156.                 return 3
  157.                
  158.         elif op in ['!', '&&', '||', '>b', '=b']:
  159.             if left == 0:
  160.                 o[ctx.e1.name] = 3
  161.             if right == 0:
  162.                 o[ctx.e2.name] = 3
  163.             if self.visit(ctx.e1, o) != 3 or self.visit(ctx.e2, o) != 3:
  164.                 raise TypeMismatchInExpression(ctx)
  165.             else:
  166.                 # return Bool
  167.                 return 3
  168.        
  169.     def visitUnOp(self,ctx:UnOp,o):
  170.         expr = self.visit(ctx.e, o)
  171.         op = ctx.op
  172.        
  173.         if op == '-':
  174.             if expr != 1:
  175.                 if expr == 0:
  176.                     o[ctx.e.name] = 1
  177.                     return 1
  178.                 raise TypeMismatchInExpression(ctx)
  179.             return 1
  180.            
  181.         elif op == '-.':
  182.             if expr != 2:
  183.                 if expr == 0:
  184.                     o[ctx.e.name] = 2
  185.                     return 2
  186.                 raise TypeMismatchInExpression(ctx)
  187.             return 2
  188.            
  189.         elif op == '!':
  190.             if expr != 3:
  191.                 if expr == 0:
  192.                     o[ctx.e.name] = 3
  193.                     return 3
  194.                 raise TypeMismatchInExpression(ctx)
  195.             return 3
  196.        
  197.         elif op == 'i2f':
  198.             if expr != 1:
  199.                 if expr == 0:
  200.                     o[ctx.e.name] = 1
  201.                     return 2
  202.                 raise TypeMismatchInExpression(ctx)
  203.             return 2
  204.            
  205.         elif op == 'floor':
  206.             if expr != 2:
  207.                 if expr == 0:
  208.                     o[ctx.e.name] = 2
  209.                     return 1
  210.                 raise TypeMismatchInExpression(ctx)
  211.             return 1
  212.  
  213.     def visitIntLit(self,ctx:IntLit,o):
  214.         return 1
  215.  
  216.     def visitFloatLit(self,ctx,o):
  217.         return 2
  218.  
  219.     def visitBoolLit(self,ctx,o):
  220.         return 3
  221.  
  222.     def visitId(self,ctx,o):
  223.         if ctx.name not in o:
  224.             raise UndeclaredIdentifier(ctx.name)
  225.         else:
  226.             return o[ctx.name]
  227. #####################################
  228. class StaticCheck(Visitor):
  229.     def visitProgram(self,ctx:Program,o):
  230.         o = [{}]
  231.         for i in ctx.decl:
  232.             self.visit(i, o)
  233.         for i in ctx.stmts:
  234.             self.visit(i, o)
  235.        
  236.    
  237.     def searchAndSet(self, typ, name, o):
  238.         for i in o:
  239.             if name in i:
  240.                 i[name] = typ
  241.                 return
  242.  
  243.     def visitVarDecl(self,ctx:VarDecl,o):
  244.         if ctx.name in o[0]:
  245.             raise Redeclared(ctx)
  246.         o[0][ctx.name] = 0
  247.    
  248.     def visitBlock(self,ctx:Block,o):
  249.         new_o = [{}] + o
  250.         for i in ctx.decl:
  251.             self.visit(i, new_o)
  252.         for i in ctx.stmts:
  253.             self.visit(i, new_o)
  254.         o = new_o[1:]
  255.  
  256.     def visitAssign(self,ctx:Assign,o):
  257.         right = self.visit(ctx.rhs, o)
  258.         left = self.visit(ctx.lhs, o)
  259.         if left == 0 and right != 0:
  260.             self.searchAndSet(right, ctx.lhs.name, o)
  261.         if left != 0 and right == 0:
  262.             self.searchAndSet(left, ctx.rhs.name, o)
  263.         if left == 0 and right == 0:
  264.             raise TypeCannotBeInferred(ctx)
  265.         if self.visit(ctx.rhs, o) != self.visit(ctx.lhs, o):
  266.             raise TypeMismatchInStatement(ctx)
  267.            
  268.     def visitBinOp(self,ctx:BinOp,o):
  269.         l = self.visit(ctx.e1, o)
  270.         r = self.visit(ctx.e2, o)
  271.         if ctx.op in ["+", "-", "*", "/"]:
  272.             if l == 0:
  273.                 self.searchAndSet(1, ctx.e1.name, o)
  274.             if r == 0:
  275.                 self.searchAndSet(1, ctx.e2.name, o)
  276.             if self.visit(ctx.e1, o) != 1 or self.visit(ctx.e2, o) != 1:
  277.                 raise TypeMismatchInExpression(ctx)
  278.             else:
  279.                 return 1
  280.                
  281.         elif ctx.op in ["+.", "-.", "*.", "/."]:
  282.             if l == 0:
  283.                 self.searchAndSet(2, ctx.e1.name, o)
  284.             if r == 0:
  285.                 self.searchAndSet(2, ctx.e2.name, o)
  286.             if self.visit(ctx.e1, o) != 2 or self.visit(ctx.e2, o) != 2:
  287.                 raise TypeMismatchInExpression(ctx)
  288.             else:
  289.                 return 2
  290.                
  291.         elif ctx.op in [">", "="]:
  292.             if l == 0:
  293.                 self.searchAndSet(1, ctx.e1.name, o)
  294.             if r == 0:
  295.                 self.searchAndSet(1, ctx.e2.name, o)
  296.             if self.visit(ctx.e1, o) != 1 or self.visit(ctx.e2, o) != 1:
  297.                 raise TypeMismatchInExpression(ctx)
  298.             else:
  299.                 return 3
  300.                
  301.         elif ctx.op in [">.", "=."]:
  302.             if l == 0:
  303.                 self.searchAndSet(2, ctx.e1.name, o)
  304.             if r == 0:
  305.                 self.searchAndSet(2, ctx.e1.name, o)
  306.             if self.visit(ctx.e1, o) != 2 or self.visit(ctx.e2, o) != 2:
  307.                 raise TypeMismatchInExpression(ctx)
  308.             else:
  309.                 return 3
  310.                
  311.         elif ctx.op in ["||", "&&", "=b", ">b"]:
  312.             if l == 0:
  313.                 self.searchAndSet(3, ctx.e1.name, o)
  314.             if r == 0:
  315.                 self.searchAndSet(3, ctx.e1.name, o)
  316.             if self.visit(ctx.e1, o) != 3 or self.visit(ctx.e2, o) != 3:
  317.                 raise TypeMismatchInExpression(ctx)
  318.             else:
  319.                 return 3
  320.                
  321.     def visitUnOp(self,ctx:UnOp,o):
  322.         typ = self.visit(ctx.e, o)
  323.         if ctx.op == "-":
  324.             if typ != 1:
  325.                 if typ == 0:
  326.                     self.searchAndSet(1, ctx.e.name, o)
  327.                     return 1
  328.                 raise TypeMismatchInExpression(ctx)
  329.             return 1
  330.         elif ctx.op == "-.":
  331.             if typ != 2:
  332.                 if typ == 0:
  333.                     self.searchAndSet(3, ctx.e.name, o)
  334.                     return 2
  335.                 raise TypeMismatchInExpression(ctx)
  336.             return 2
  337.         elif ctx.op == "!":
  338.             if typ != 3:
  339.                 if typ == 0:
  340.                     self.searchAndSet(3, ctx.e.name, o)
  341.                     return 3
  342.                 raise TypeMismatchInExpression(ctx)
  343.             return 3
  344.         elif ctx.op == "i2f":
  345.             if typ != 1:
  346.                 if typ == 0:
  347.                     self.searchAndSet(1, ctx.e.name, o)
  348.                     return 2
  349.                 raise TypeMismatchInExpression(ctx)
  350.             return 2
  351.         else: # floor  
  352.             if typ != 2:
  353.                 if typ == 0:
  354.                     self.searchAndSet(2, ctx.e.name, o)
  355.                     return 1
  356.                 raise TypeMismatchInExpression(ctx)
  357.             return 1
  358.            
  359.     def visitIntLit(self,ctx:IntLit,o):
  360.         return 1
  361.  
  362.     def visitFloatLit(self,ctx,o):
  363.         return 2
  364.  
  365.     def visitBoolLit(self,ctx,o):
  366.         return 3
  367.  
  368.     def visitId(self,ctx,o):
  369.         for i in o:
  370.             if ctx.name in i:
  371.                 return i[ctx.name]
  372.         raise UndeclaredIdentifier(ctx.name)
  373. ##########################################
  374. class StaticCheck(Visitor):
  375.     def visitProgram(self,ctx:Program,o):
  376.         o = [{}]
  377.         for i in ctx.decl:
  378.             self.visit(i, o)
  379.         for i in ctx.stmts:
  380.             self.visit(i, o)
  381.        
  382.    
  383.     def searchAndSet(self, typ, name, o):
  384.         for i in o:
  385.             if name in i:
  386.                 i[name] = typ
  387.                 return
  388.  
  389.     def visitVarDecl(self,ctx:VarDecl,o):
  390.         if ctx.name in o[0]:
  391.             raise Redeclared(ctx)
  392.         o[0][ctx.name] = 0
  393.    
  394.     def visitFuncDecl(self,ctx:FuncDecl,o):
  395.         if ctx.name in o[0]:
  396.             raise Redeclared(ctx)
  397.         o_1 = [{}] + o
  398.         for i in ctx.param:
  399.             self.visit(i, o_1)
  400.         for i in ctx.local:
  401.             self.visit(i, o_1)
  402.         for i in ctx.stmts:
  403.             self.visit(i, o_1)
  404.         lst_param = []
  405.         for i in ctx.param:
  406.             lst_param += [o_1[0][i.name]]
  407.         o[0][ctx.name] = lst_param
  408.    
  409.     def visitCallStmt(self,ctx:CallStmt,o):
  410.         if ctx.name not in o[0]:
  411.             raise UndeclaredIdentifier(ctx.name)
  412.         else:
  413.             lst_param = o[0][ctx.name]
  414.             if len(lst_param) != len(ctx.args):
  415.                 raise TypeMismatchInStatement(ctx)
  416.             else:
  417.                 for i in range(0, len(lst_param)):
  418.                     typ = self.visit(ctx.args[i], o)
  419.                     if lst_param[i] == 0 and typ != 0:
  420.                         o[0][ctx.name][i] = typ
  421.                         continue
  422.                     if lst_param[i] != 0 and typ == 0:
  423.                         self.searchAndSet(lst_param[i], ctx.args[i].name, o)
  424.                     if lst_param[i] == 0 and typ == 0:
  425.                         raise TypeCannotBeInferred(ctx)
  426.                     if lst_param[i] != self.visit(ctx.args[i], o):
  427.                         raise TypeMismatchInStatement(ctx)
  428.  
  429.     def visitAssign(self,ctx:Assign,o):
  430.         right = self.visit(ctx.rhs, o)
  431.         left = self.visit(ctx.lhs, o)
  432.         if left == 0 and right != 0:
  433.             self.searchAndSet(right, ctx.lhs.name, o)
  434.         if left != 0 and right == 0:
  435.             self.searchAndSet(left, ctx.rhs.name, o)
  436.         if left == 0 and right == 0:
  437.             raise TypeCannotBeInferred(ctx)
  438.         if self.visit(ctx.rhs, o) != self.visit(ctx.lhs, o):
  439.             raise TypeMismatchInStatement(ctx)
  440.            
  441.     def visitBinOp(self,ctx:BinOp,o):
  442.         l = self.visit(ctx.e1, o)
  443.         r = self.visit(ctx.e2, o)
  444.         if ctx.op in ["+", "-", "*", "/"]:
  445.             if l == 0:
  446.                 self.searchAndSet(1, ctx.e1.name, o)
  447.             if r == 0:
  448.                 self.searchAndSet(1, ctx.e2.name, o)
  449.             if self.visit(ctx.e1, o) != 1 or self.visit(ctx.e2, o) != 1:
  450.                 raise TypeMismatchInExpression(ctx)
  451.             else:
  452.                 return 1
  453.                
  454.         elif ctx.op in ["+.", "-.", "*.", "/."]:
  455.             if l == 0:
  456.                 self.searchAndSet(2, ctx.e1.name, o)
  457.             if r == 0:
  458.                 self.searchAndSet(2, ctx.e2.name, o)
  459.             if self.visit(ctx.e1, o) != 2 or self.visit(ctx.e2, o) != 2:
  460.                 raise TypeMismatchInExpression(ctx)
  461.             else:
  462.                 return 2
  463.                
  464.         elif ctx.op in [">", "="]:
  465.             if l == 0:
  466.                 self.searchAndSet(1, ctx.e1.name, o)
  467.             if r == 0:
  468.                 self.searchAndSet(1, ctx.e2.name, o)
  469.             if self.visit(ctx.e1, o) != 1 or self.visit(ctx.e2, o) != 1:
  470.                 raise TypeMismatchInExpression(ctx)
  471.             else:
  472.                 return 3
  473.                
  474.         elif ctx.op in [">.", "=."]:
  475.             if l == 0:
  476.                 self.searchAndSet(2, ctx.e1.name, o)
  477.             if r == 0:
  478.                 self.searchAndSet(2, ctx.e1.name, o)
  479.             if self.visit(ctx.e1, o) != 2 or self.visit(ctx.e2, o) != 2:
  480.                 raise TypeMismatchInExpression(ctx)
  481.             else:
  482.                 return 3
  483.                
  484.         elif ctx.op in ["||", "&&", "=b", ">b"]:
  485.             if l == 0:
  486.                 self.searchAndSet(3, ctx.e1.name, o)
  487.             if r == 0:
  488.                 self.searchAndSet(3, ctx.e1.name, o)
  489.             if self.visit(ctx.e1, o) != 3 or self.visit(ctx.e2, o) != 3:
  490.                 raise TypeMismatchInExpression(ctx)
  491.             else:
  492.                 return 3
  493.            
  494.  
  495.     def visitUnOp(self,ctx:UnOp,o):
  496.         typ = self.visit(ctx.e, o)
  497.         if ctx.op == "-":
  498.             if typ != 1:
  499.                 if typ == 0:
  500.                     self.searchAndSet(1, ctx.e.name, o)
  501.                     return 1
  502.                 raise TypeMismatchInExpression(ctx)
  503.             return 1
  504.         elif ctx.op == "-.":
  505.             if typ != 2:
  506.                 if typ == 0:
  507.                     self.searchAndSet(3, ctx.e.name, o)
  508.                     return 2
  509.                 raise TypeMismatchInExpression(ctx)
  510.             return 2
  511.         elif ctx.op == "!":
  512.             if typ != 3:
  513.                 if typ == 0:
  514.                     self.searchAndSet(3, ctx.e.name, o)
  515.                     return 3
  516.                 raise TypeMismatchInExpression(ctx)
  517.             return 3
  518.         elif ctx.op == "i2f":
  519.             if typ != 1:
  520.                 if typ == 0:
  521.                     self.searchAndSet(1, ctx.e.name, o)
  522.                     return 2
  523.                 raise TypeMismatchInExpression(ctx)
  524.             return 2
  525.         else: # floor  
  526.             if typ != 2:
  527.                 if typ == 0:
  528.                     self.searchAndSet(2, ctx.e.name, o)
  529.                     return 1
  530.                 raise TypeMismatchInExpression(ctx)
  531.             return 1
  532.            
  533.     def visitIntLit(self,ctx:IntLit,o):
  534.         return 1
  535.  
  536.     def visitFloatLit(self,ctx,o):
  537.         return 2
  538.  
  539.     def visitBoolLit(self,ctx,o):
  540.         return 3
  541.  
  542.     def visitId(self,ctx,o):
  543.         for i in o:
  544.             if ctx.name in i:
  545.                 return i[ctx.name]
  546.         raise UndeclaredIdentifier(ctx.name)
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement