def __typecheck_assignment(self, statement):
     if statement["Type"] != "Assignment":
         raise InvalidStatementType("not an assignment")
     try:
         var_type = get_var(self.__environments, statement)["LatteType"]["TypeName"]
         expr_type = self.__eval_expression_type(statement, "Expr")
         if var_type != expr_type:
             self.__errors.append(
                 "in assignment to %s: invalid type of expression being assigned:\n"
                 "expected: %s, got: %s, line: %d pos: %d - %d"
                 % (
                     statement["Name"],
                     var_type,
                     expr_type,
                     statement["LineNo"],
                     statement["StartPos"],
                     statement["EndPos"],
                 )
             )
             return statement
         # else:
         #    get_var(self.__environments, statement)['Assigned'] = statement['Expr']
         if self.__optimize > 0 and not self.__errors:
             self.__optimizer.simplify_expression(statement, "Expr")
     except (VariableUndeclared, InvalidExpression) as e:
         self.__errors.append(e.msg)
     return statement
 def __typecheck_inc_dec(self, statement):
     if statement["Type"] != "IncDec":
         raise InvalidStatementType("not an increment/decrement statement")
     try:
         if get_var(self.__environments, statement)["LatteType"]["TypeName"] != "int":
             self.__errors.append(
                 "in increment/decrement statement:\n"
                 "invalid type of variable %s, line: %d pos %d - %d"
                 % (statement["Name"], statement["LineNo"], statement["StartPos"], statement["EndPos"])
             )
     except VariableUndeclared as e:
         self.__errors.append(e.msg)
     return statement
 def __eval_expression_type(self, node, key):
     expression = node[key]
     if expression["Type"] == "NumLiteral":
         node[key]["EvalType"] = "int"
         return "int"
     elif expression["Type"] == "BoolLiteral":
         node[key]["EvalType"] = "boolean"
         return "boolean"
     elif expression["Type"] == "StrLiteral":
         node[key]["EvalType"] = "string"
         return "string"
     elif expression["Type"] == "UnaryOp":
         return self.__eval_expression_type_unary(node, key)
     elif expression["Type"] == "BinaryOp":
         return self.__eval_expression_type_binary(node, key)
     elif expression["Type"] == "Var":
         var_type = get_var(self.__environments, expression)["LatteType"]["TypeName"]
         node[key]["EvalType"] = var_type
         return var_type
     elif expression["Type"] == "FunCall":
         return self.__eval_expression_type_funcall(node, key)
     else:
         raise InvalidExpression("unrecognized expression type")
 def get_var_info(self, var):
     JVMVar = get_var(self.__environments, var)
     prefix = 'i' if JVMVar['LatteType']['TypeName'] in ('int', 'boolean') else 'a'
     return  prefix, '_' if JVMVar['JVMVarNo'] < OPTIMIZED_LIMIT else ' ', JVMVar['JVMVarNo']
 def emit_inc_dec(self, stmt):
     self.emit('%cload%c%d\n' % self.get_var_info(stmt))
     self.emit('iinc %d %d\n' % (get_var(self.__environments, stmt)['JVMVarNo'],
         1 if stmt['Op'] == '++' else -1))
     self.emit('pop\n')