Пример #1
0
    def __init__(self,
                 ident: Identifier,
                 type_=None,
                 value=None,
                 const: bool = False):
        self.ident = ident
        self.type_ = type_
        self.value = value
        self.const = const
        self.symbol: Optional[SymbolInfo] = symtab.get_symbol(
            self.ident.ident_name)

        children = []

        if isinstance(type_, Node):
            children.append(type_)
        else:
            children.append(List([]))

        if isinstance(value, Node):
            children.append(value)
        else:
            children.append(List([]))

        super().__init__(name="DECL",
                         children=children,
                         data=(ident, type_, value, const))
Пример #2
0
            def get_type(child: Node) -> str:

                if isinstance(child, PrimaryExpr):
                    if len(child.children) > 0 and isinstance(
                            child.children[0], Index):
                        x = symtab.get_symbol(child.data[1]).type_.eltype

                    else:
                        x = symtab.get_symbol(child.data[1]).type_.name

                elif hasattr(child, "type_"):
                    x = getattr(child, "type_")

                else:
                    raise Exception("Could not determine type of child", child)

                return x
Пример #3
0
    def __init__(self, operand, children=None):
        # small optimization for the case when PrimaryExpr
        # has children of [PrimaryExpr, something]
        # with PrimaryExpr having only data and no children
        if operand is None and children is not None:
            if len(children) == 2 and isinstance(children[0], PrimaryExpr):
                if children[0].children is None or children[0].children == []:
                    operand = children[0].data
                    children = children[1:]

        super().__init__("PrimaryExpr",
                         children=[] if children is None else children,
                         data=operand)
        self.ident: Optional[SymbolInfo] = symtab.get_symbol(
            operand[1] if isinstance(operand, tuple) else "")
Пример #4
0
    def __init__(self, fn_name: Any, arguments: Arguments):
        if (isinstance(fn_name, PrimaryExpr)
                and isinstance(fn_name.data, tuple)
                and fn_name.data[0] == "identifier"):
            fn_name = str(fn_name.data[1])

        self.fn_name = fn_name
        self.arguments = arguments

        self.fn_sym = symtab.get_symbol(str(fn_name))
        self.type_ = None
        if self.fn_sym is not None:
            if self.fn_sym.value is not None:
                self.type_ = self.fn_sym.value.signature.ret_type

        super().__init__("FunctionCall", children=[arguments], data=fn_name)
Пример #5
0
def p_OperandName(p):
    """OperandName : IDENTIFIER %prec '='
    | QualifiedIdent
    """
    if not isinstance(p[1], syntree.QualifiedIdent):
        ident: Tuple = p[1]
        sym = symtab.get_symbol(ident[1])
        lineno = p.lineno(1)
        if not symtab.is_declared(ident[1]):
            print_error()
            print(f"Undeclared symbol '{ident[1]}' at line {lineno}")
            print_line(lineno)
            line: str = utils.lines[lineno - 1]
            # TODO: get correct position of token rather than searching
            pos = ident[2] - 1
            width = len(ident[1])
            print_marker(pos, width)
        else:
            sym.uses.append(lineno)

    p[0] = p[1]
Пример #6
0
def make_variable_decls(
    identifier_list: List,
    type_=None,
    expression_list: Optional[List] = None,
    const: bool = False,
):
    var_list = List([])

    if expression_list is None:
        # TODO: implement default values
        ident: Identifier
        for ident in identifier_list:
            symtab.declare_new_variable(
                ident.ident_name,
                ident.lineno,
                ident.col_num,
                type_=type_,
                const=const,
            )
            var_list.append(VarDecl(ident, type_, const=const))
    elif len(identifier_list) == len(expression_list):
        ident: Identifier
        expr: Node

        orig_type = type_

        for ident, expr in zip(identifier_list, expression_list):
            # type inference
            inf_type = "unknown"
            if isinstance(expr, BinOp) or isinstance(expr, UnaryOp):
                inf_type = expr.type_
                if type_ != None:
                    inf_type = type_

            elif isinstance(expr, Literal):
                inf_type = expr.type_

            elif isinstance(expr, PrimaryExpr):
                if len(expr.children) > 0 and isinstance(
                        expr.children[0], Index):
                    inf_type = symtab.get_symbol(expr.data[1]).type_.eltype

                else:
                    inf_type = symtab.get_symbol(expr.data[1]).type_.name

            else:
                print("Could not determine type: ", ident, expr)

            if inf_type is None:
                inf_type = "unknown"

            inf_typename = get_typename(inf_type)

            # now check if the LHS and RHS types match
            if type_ is None:
                type_ = inf_type
            else:
                # get just the type name
                typename = get_typename(type_)

                if typename != inf_typename:
                    # special case for literal
                    if not isinstance(expr, Literal):
                        print_error("Type Mismatch", kind="TYPE ERROR")
                        print(
                            f"Cannot use expression of type {inf_typename} as "
                            f"assignment to type {typename}")
                        print_line_marker_nowhitespace(ident.lineno)

            symtab.declare_new_variable(
                ident.ident_name,
                ident.lineno,
                ident.col_num,
                type_=type_,
                value=expr,
                const=const,
            )

            var_list.append(VarDecl(ident, type_, expr, const))
            type_ = orig_type
    else:
        raise NotImplementedError(
            "Declaration with unpacking not implemented yet")

    return var_list