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))
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
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 "")
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)
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]
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