Esempio n. 1
0
    def _codegen_Builtins_c_obj_alloc(self, node):
        '''
        Allocates bytes for an object of the type submitted.
        Eventually we will be able to submit a type directly.
        For now, use a throwaway closure that generates
        an object of the type you want to use
        E.g., for an i32[8]:
        var x=c_obj_alloc({with var z:i32[8] z})
        (the contents of the closure are optimized out
        at compile time)
        '''

        expr = self._get_obj_noload(node)
        e2 = self.builder.load(expr)
        sizeof = self._obj_size(e2)

        call = self._codegen_Call(
            Call(node.position, 'c_alloc',
                 [Number(node.position, sizeof, self.vartypes.u_size)]))

        b1 = self.builder.bitcast(call, expr.type) # pylint: disable=E1111
        b2 = self.builder.alloca(b1.type)
        self.builder.store(b1, b2)

        b2.do_not_allocate = True
        b2.heap_alloc = True
        b2.tracked = True

        return b2
Esempio n. 2
0
    def _parse_standalone_vartype_expr(self):
        '''
        Currently used for parsing variable types that are passed
        as an argument to a function. This is an exceptional case
        that will in time be eliminated.
        '''
        pos = self.cur_tok.position
        vartype = self._parse_vartype_expr()

        # if we're invoking a type as a call,
        # then we call the __new__ method
        # for that type

        if self._cur_tok_is_punctuator('('):
            args = self._parse_argument_list(True)
            self._get_next_token()
            if vartype.is_obj_ptr():
                v = vartype.pointee
                v = '.object.' + v.v_id
            else:
                v = vartype
                v = '.' + v.v_id
            return Call(pos, v + '.__new__', args, vartype)

        return VariableType(pos, vartype)
Esempio n. 3
0
    def _parse_builtin(self, name):
        if name in ('cast', 'convert'):
            return getattr(self, f'_parse_{name}_expr')()

        start = self.cur_tok.position
        self._get_next_token()
        self._match(TokenKind.PUNCTUATOR, '(', consume=False)
        args = self._parse_argument_list()
        self._get_next_token()
        return Call(start, name, args)
Esempio n. 4
0
 def _parse_convert_expr(self, callee='convert'):
     start = self.cur_tok.position
     self._get_next_token()
     self._match(TokenKind.PUNCTUATOR, '(')
     convert_from = self._parse_expression()
     self._match(TokenKind.PUNCTUATOR, ',')
     # For builtins that take a vartype as an argument,
     # we need to use this for now
     convert_to = self._parse_standalone_vartype_expr()
     #convert_to = self._parse_expression()
     self._match(TokenKind.PUNCTUATOR, ')')
     return Call(start, callee, [convert_from, convert_to])
Esempio n. 5
0
    def _parse_identifier_expr(self):
        start = self.cur_tok.position
        id_name = self.cur_tok.value

        if id_name in Builtins or id_name in Dunders:
            return self._parse_builtin(id_name)

        if id_name in self.consts:
            self._get_next_token()
            return self.consts[id_name]

        current = Variable(start, id_name, self.cur_tok.vartype)
        toplevel = current

        while True:
            self._get_next_token()

            if self._cur_tok_is_punctuator('['):
                current.child = self._parse_array_accessor()
                current = current.child
                continue

            elif self._cur_tok_is_punctuator('('):
                args = self._parse_argument_list()
                current.child = Call(start, id_name, args,
                                     self.cur_tok.vartype)
                current = current.child
                continue

            elif self.cur_tok.value == '.':
                self._get_next_token()
                current.child = Variable(start, self.cur_tok.value)
                current = current.child
                continue

            else:
                break

        return toplevel
Esempio n. 6
0
    def _codegen_Builtins_c_obj_free(self, node):
        '''
        Deallocates memory for an object created with c_obj_alloc.
        '''
        expr = self._get_obj_noload(node)

        if not expr.tracked:
            raise CodegenError(f'{node.args[0].name} is not an allocated object',node.args[0].position)

        # Mark the variable in question as untracked
        expr.tracked = False

        addr = self.builder.load(expr)
        addr2 = self.builder.bitcast(addr, self.vartypes.u_mem.as_pointer()).get_reference()

        call = self._codegen_Call(
            Call(node.position, 'c_free',
                 [Number(node.position, addr2,
            self.vartypes.u_mem.as_pointer())]))        

        # TODO: zero after free, automatically
        
        return call
Esempio n. 7
0
 def _codegen_dunder_methods(self, node):
     call = self._codegen_Call(Call(node.position, node.name, node.args),
                               obj_method=True)
     return call
Esempio n. 8
0
    def _codegen_Builtins_out(self, node):
        in_template = re.split(r'([{}])', node.args[0].val)
        
        var_names = []        
        escape = False
        open_br = False

        for n in in_template:
            if n==r'{' and not escape:
                open_br = True
                continue
            if n==r'}' and not escape:
                open_br = False
                continue
            if open_br:
                var_ref = self._varaddr(n,False)
                var_names.append([var_ref.type.p_fmt,n])
                continue
            escape=False            
            if n and n[-1]=='\\':
                escape=True
                n=n[0:-1]
            n = n.replace('%','%%')
            var_names.append([n,None])
        
        format_string = []
        variable_list = []

        for n in var_names:
            format_string.append(n[0])

            if n[1] is None:
                continue

            if n[0] == '%s':
                var_app = Call(
                    node.position,
                    'c_data',
                    [Variable(node.position, n[1])]
                )
            else:
                var_app = Variable(node.position, n[1])

            variable_list.append(var_app)

        str_to_extract = String(node.position, ''.join(format_string))

        convert = Call(
            node.position,
            'c_data',
            [str_to_extract]
        )

        variable_list.insert(0,convert)

        return self._codegen(
            Call(
                node.position,
                'printf',
                variable_list,
                self.vartypes.i32
            )
        )