Esempio n. 1
0
 def type(self, params):
     if len(params) == 1:
         return VariableType(VariableTypeEnum.UNKNOWN, params[0].value)
     elif len(params) == 3:
         assert params[0].value == "[" and params[2].value == "]"
         return VariableType(
             VariableTypeEnum.ARRAY,
             array_type=VariableType(VariableTypeEnum.UNKNOWN,
                                     type_name=params[1].value),
         )
Esempio n. 2
0
def get_type_from_string(global_scope: GlobalScope,
                         type_name: str) -> VariableType:
    # int is just an alias for i64
    if type_name == "int":
        type_name = "i64"
    if type_name == "i64":
        return primitive(PrimitiveType.I64)
    elif type_name == "i32":
        return primitive(PrimitiveType.I32)
    elif type_name == "i16":
        return primitive(PrimitiveType.I16)
    elif type_name == "i8":
        return primitive(PrimitiveType.I8)
    elif type_name == "u64":
        return primitive(PrimitiveType.U64)
    elif type_name == "u32":
        return primitive(PrimitiveType.U32)
    elif type_name == "u16":
        return primitive(PrimitiveType.U16)
    elif type_name == "u8":
        return primitive(PrimitiveType.U8)
    elif type_name == "float":
        return primitive(PrimitiveType.FLOAT)
    elif type_name == "string":
        return primitive(PrimitiveType.STRING)
    elif type_name == "bool":
        return primitive(PrimitiveType.BOOL)
    elif type_name in global_scope.structs:
        return VariableType(VariableTypeEnum.STRUCT, type_name=type_name)
    else:
        raise Exception(f"Unknown type: {type_name}")
Esempio n. 3
0
 def boolean_literal(self, value):
     return Constant(
         VariableType(VariableTypeEnum.UNKNOWN),
         ParseContext(value),
         ConstantType.BOOL,
         value.value == "true",
     )
Esempio n. 4
0
 def string_literal(self, value):
     return Constant(
         VariableType(VariableTypeEnum.UNKNOWN),
         ParseContext(value),
         ConstantType.STRING,
         value.value[1:-1],
     )
Esempio n. 5
0
 def integer_constant(self, value):
     return Constant(
         VariableType(VariableTypeEnum.UNKNOWN),
         ParseContext(value),
         ConstantType.INTEGER,
         int(value.value),
     )
Esempio n. 6
0
 def mul_div_expr(self, op1, operator, op2):
     return MathOperation(
         VariableType(VariableTypeEnum.UNKNOWN),
         op1.context,
         op1,
         op2,
         operator.value,
     )
Esempio n. 7
0
 def compare_expr(self, op1, operator, op2):
     return CompareOperation(
         VariableType(VariableTypeEnum.UNKNOWN),
         op1.context,
         op1,
         op2,
         operator.value,
     )
Esempio n. 8
0
def typeify(base_type: VariableType, global_scope: GlobalScope):
    if base_type.variable_type == VariableTypeEnum.ARRAY:
        assert base_type.array_type
        assert base_type.array_type.type_name
        assert base_type.array_type.variable_type == VariableTypeEnum.UNKNOWN
        base_type.array_type = get_type_from_string(
            global_scope, base_type.array_type.type_name)
    elif base_type.variable_type == VariableTypeEnum.UNKNOWN:
        assert base_type.type_name
        base_type = get_type_from_string(global_scope, base_type.type_name)
    else:
        raise InternalCompilerError("Unhandled type in struct validation pass")
    return base_type
Esempio n. 9
0
    def var_access(self, variable, *args):
        assert len(args) in range(0, 3)
        if len(args) == 2:
            array_access, variable_access = args[0].expression, args[1]
        elif len(args) == 0:
            array_access, variable_access = None, None
        elif isinstance(args[0], VariableAccess):
            array_access, variable_access = None, args[0]
        else:
            array_access, variable_access = args[0].expression, None

        return VariableAccess(
            VariableType(VariableTypeEnum.UNKNOWN),
            ParseContext(variable),
            variable.value,
            array_access,
            variable_access,
        )
Esempio n. 10
0
def primitive(primitive_type: PrimitiveType) -> VariableType:
    return VariableType(VariableTypeEnum.PRIMITIVE,
                        primitive_type=primitive_type)
Esempio n. 11
0
    def expression(self, expression: BaseExpression):
        if isinstance(expression, FunctionCall):
            expression.type = self.function_call(expression)
        elif isinstance(expression, VariableAccess):
            variable_type = self.scope_stack.get_variable_type(
                expression.variable_name)
            if not variable_type:
                raise ContextException(
                    f"Unknown variable: {expression.variable_name}",
                    expression.context)

            # handle array access
            if expression.array_access is not None:
                expression_type = self.array_access(variable_type,
                                                    expression.array_access)
            else:
                expression_type = variable_type

            # handle struct access
            if expression.variable_access is not None:
                expression_type = self.struct_access(
                    expression_type, expression.variable_access)

            expression.type = expression_type

        elif isinstance(expression, Constant):
            if expression.constant_type == ConstantType.STRING:
                expression.type = VariableType(
                    VariableTypeEnum.PRIMITIVE,
                    primitive_type=PrimitiveType.STRING)
            elif expression.constant_type == ConstantType.FLOAT:
                expression.type = VariableType(
                    VariableTypeEnum.PRIMITIVE,
                    primitive_type=PrimitiveType.FLOAT)
            elif expression.constant_type == ConstantType.BOOL:
                expression.type = VariableType(
                    VariableTypeEnum.PRIMITIVE,
                    primitive_type=PrimitiveType.BOOL)
            elif expression.constant_type == ConstantType.INTEGER:
                expression.type = primitive_type_from_constant(
                    expression.value)
            else:
                raise InternalCompilerError("Unknown constant type")

        elif isinstance(expression, MathOperation):
            operand1_type = self.expression(expression.operand1)
            operand2_type = self.expression(expression.operand2)
            if is_type_compatible(operand1_type, operand2_type):
                expression.type = operand1_type
            elif is_type_compatible(operand2_type, operand1_type):
                expression.type = operand2_type
            else:
                raise Exception("Incompatible type in operator expressions")
        elif isinstance(expression, CompareOperation):
            operand1_type = self.expression(expression.operand1)
            operand2_type = self.expression(expression.operand2)
            if not is_type_compatible(operand1_type,
                                      operand2_type) or not is_type_compatible(
                                          operand2_type, operand1_type):
                raise TypeMismatchException("Operands cannot be compared",
                                            expression.context)
            expression.type = VariableType(VariableTypeEnum.PRIMITIVE,
                                           primitive_type=PrimitiveType.BOOL)
        else:
            raise InternalCompilerError("Unknown expression")
        return expression.type