예제 #1
0
def mem_copy(from_ptr, to_ptr, len_ptr):
    fb = mem.MEMORY.get(from_ptr, PTR_LEN)
    tb = mem.MEMORY.get(to_ptr, PTR_LEN)
    lb = mem.MEMORY.get(len_ptr, PTR_LEN)
    fi, ti, li = typ.bytes_to_int(fb), typ.bytes_to_int(tb), typ.bytes_to_int(
        lb)
    # print(fi, ti, li)
    mem.MEMORY.mem_copy(fi, ti, li)
예제 #2
0
def malloc(length_ptr: int) -> int:
    int_len = mem.MEMORY.get_type_size("int")
    b = mem.MEMORY.get(length_ptr, int_len)
    v = typ.bytes_to_int(b)
    ptr = mem.MEMORY.malloc(v)
    ptr_b = typ.int_to_bytes(ptr)
    rtn = mem.MEMORY.allocate(ptr_b)
    return rtn
예제 #3
0
def get_indexing_location_and_unit_len(node: ast.IndexingNode,
                                       env: en.Environment) -> (int, int):
    l_ptr = evaluate(node.call_obj, env)
    l_tal = get_tal_of_node_self(node, env)
    if en.is_array(l_tal):
        depth = index_node_depth(node)
        unit_length = l_tal.total_len()
        for i in range(depth):
            unit_length //= l_tal.array_lengths[i]
    elif l_tal.type_name[0] == "*":
        ptr_b = mem.MEMORY.get(l_ptr, PTR_LEN)
        l_ptr = typ.bytes_to_int(ptr_b)
        unit_length = mem.MEMORY.get_type_size(l_tal.type_name[1:])
    else:
        raise lib.TypeException("Type '{}' not supporting indexing".format(
            en.type_to_readable(l_tal)))

    arg_ptr = evaluate(node.arg, env)  # arg type must be int
    arg_b = mem.MEMORY.get(arg_ptr, mem.MEMORY.get_type_size("int"))
    arg_v = typ.bytes_to_int(arg_b)
    return l_ptr + arg_v * unit_length, unit_length
예제 #4
0
 def interpret(self):
     mem.MEMORY.load_literal(self.literal_bytes)
     self.add_natives()
     evaluate(self.ast, self.global_env)
     if "main" in self.global_env.functions:
         main_group: dict = self.global_env.get_function("main", LINE_FILE)
         # main_func: Function = main_group[""]
         # main_rt = main_func.r_tal
         # if main_rt.type_name != "int" or len(main_rt.array_lengths):
         #     raise lib.SplException("Function 'main' must return 'int'")
         r_ptr = call_function(main_group, [], self.global_env)
         rb = mem.MEMORY.get(r_ptr, mem.MEMORY.get_type_size("int"))
         return typ.bytes_to_int(rb)
     return 0
예제 #5
0
def get_tal_of_defining_node(node: ast.Node, env: en.Environment) -> en.Type:
    if node.node_type == ast.NAME_NODE:
        node: ast.NameNode
        return en.Type(node.name)
    elif node.node_type == ast.INDEXING_NODE:  # array
        node: ast.IndexingNode
        tn_al_inner: en.Type = get_tal_of_defining_node(node.call_obj, env)
        if len(node.arg.lines) == 0:
            return en.Type(tn_al_inner.type_name, 0)
        arr_len_ptr = evaluate(node.arg, env)
        arr_len_b = mem.MEMORY.get(arr_len_ptr, INT_LEN)
        arr_len_v = typ.bytes_to_int(arr_len_b)
        # return type_name, arr_len_inner * typ.bytes_to_int(arr_len_b)
        return en.Type(tn_al_inner.type_name, *tn_al_inner.array_lengths,
                       arr_len_v)
    elif node.node_type == ast.UNARY_OPERATOR:
        node: ast.UnaryOperator
        tal = get_tal_of_defining_node(node.value, env)
        if node.operation == "unpack":
            return en.Type("*" + tal.type_name, *tal.array_lengths)
        else:
            raise lib.UnexpectedSyntaxException()
예제 #6
0
def eval_unpack(vp: int, v_tal: en.Type, env: en.Environment):
    vb = mem.MEMORY.get(vp, INT_LEN)
    v = typ.bytes_to_int(vb)
    # orig_type_name = v_tal[0][1:]  # for example, *int to int, or **int to *int
    # # rb = mem.MEMORY.get(v, mem.MEMORY.get_type_size(orig_type_name) * v_tal[1])
    return v
예제 #7
0
def get_array_len_of_node(node: ast.IndexingNode, env: en.Environment) -> int:
    arr_len_ptr = evaluate(node.arg, env)
    arr_len_b = mem.MEMORY.get(arr_len_ptr, mem.MEMORY.get_type_size("int"))
    return typ.bytes_to_int(arr_len_b)
예제 #8
0
def eval_assignment_node(node: ast.AssignmentNode, env: en.Environment):
    r = evaluate(node.right, env)
    lf = node.line_num, node.file

    if node.left.node_type == ast.NAME_NODE:
        name: str = node.left.name
        if node.level == ast.FUNC_DEFINE:
            if not isinstance(r, Function):
                raise lib.TypeException("Unexpected function declaration")
            env.define_function(name, r)
        else:
            tal = get_tal_of_evaluated_node(node.left, env)
            total_len = tal.total_len()
            rv = mem.MEMORY.get(r, total_len)
            current_ptr = env.get(name, lf)
            mem.MEMORY.set(current_ptr, rv)
            # env.assign(name, r, lf)
    elif node.left.node_type == ast.TYPE_NODE:
        type_node: ast.TypeNode = node.left
        tal = get_tal_of_defining_node(type_node.right, env)
        name: str = type_node.left.name
        total_len = tal.total_len()
        if total_len == 0:  # array with undefined length
            tal = get_tal_of_evaluated_node(node.right, env)
            total_len = tal.total_len()

        ptr = mem.MEMORY.allocate_empty(total_len)
        if r != 0:  # is not undefined
            mem.MEMORY.mem_copy(r, ptr, total_len)

        if node.level == ast.VAR:
            env.define_var(name, tal, ptr)
        elif node.level == ast.CONST:
            env.define_const(name, tal, ptr)
    elif node.left.node_type == ast.DOT:
        dot: ast.Dot = node.left
        l_ptr = evaluate(dot.left, env)
        l_tal = get_tal_of_evaluated_node(dot.left, env)
        # print(l_tal)
        struct: Struct = env.get_struct(l_tal.type_name)
        attr: ast.NameNode = dot.right
        pos_in_struct = struct.get_attr_pos(attr.name)
        attr_tal = struct.get_attr_tal(attr.name)
        attr_len = attr_tal.total_len()
        rv = mem.MEMORY.get(r, attr_len)
        mem.MEMORY.set(l_ptr + pos_in_struct, rv)
    elif node.left.node_type == ast.INDEXING_NODE:
        eval_setitem(node.left, r, env)
    elif node.left.node_type == ast.UNARY_OPERATOR:
        uo: ast.UnaryOperator = node.left
        tal = get_tal_of_evaluated_node(uo, env)
        total_len = tal.total_len()
        l_ptr = evaluate(uo, env)
        rv = mem.MEMORY.get(r, total_len)
        if uo.operation == "pack" and uo.value.node_type == ast.NAME_NODE:
            ri = typ.bytes_to_int(rv)
            env.assign(uo.value.name, ri, lf)
        else:
            mem.MEMORY.set(l_ptr, rv)
    else:
        raise lib.TypeException("Currently unimplemented")
예제 #9
0
def free(ptr):
    b = mem.MEMORY.get(ptr, mem.MEMORY.pointer_length)
    loc = typ.bytes_to_int(b)
    mem.MEMORY.free(loc)
예제 #10
0
def printf(env: en.Environment, *args_node):
    fmt_node = args_node[0]
    # print(fmt_ptr)
    # fmt_b: bytes = mem.MEMORY.get_string(fmt_ptr)
    fmt_tal = get_tal_of_evaluated_node(fmt_node, env)
    fmt_len = fmt_tal.total_len()
    fmt_ptr = evaluate(fmt_node, env)
    fmt_b = mem.MEMORY.get(fmt_ptr, fmt_len)
    fmt: str = fmt_b.decode("utf-8")
    i = 0
    a_index = 0
    f = False
    lst = []
    args = [evaluate(n, env) for n in args_node[1:]]
    while i < len(fmt):
        ch = fmt[i]
        if ch == "%":
            f = True
        elif f:
            if ch == "d":
                f = False
                num_ptr = args[a_index]
                a_index += 1
                bs = mem.MEMORY.get(num_ptr, INT_LEN)
                lst.append(str(typ.bytes_to_int(bs)))
            elif ch == "f":
                f = False
                # TODO: get more pref
                num_ptr = args[a_index]
                a_index += 1
                bs = mem.MEMORY.get(num_ptr, FLOAT_LEN)
                lst.append(str(typ.bytes_to_float(bs)))
            elif ch == "s":
                f = False
                ch_ptr = args[a_index]
                ch_node = args_node[a_index + 1]  # not aligned
                ch_tal = get_tal_of_evaluated_node(ch_node, env)
                # print(ch_tal)
                if en.is_array(ch_tal):
                    b = mem.MEMORY.get(ch_ptr, ch_tal.total_len())
                    s = typ.bytes_to_string(b)
                    lst.append(s)
                elif ch_tal.type_name == "*char":
                    content_ptr_b = mem.MEMORY.get(ch_ptr, PTR_LEN)
                    content_ptr = typ.bytes_to_int(content_ptr_b)
                    b = mem.MEMORY.get_char_array(content_ptr)
                    s = typ.bytes_to_string(b)
                    lst.append(s)
                else:
                    print_warning("Unknown argument for identifier '%s'.\n")
                a_index += 1
            elif ch == "c":
                f = False
                c_ptr = args[a_index]
                a_index += 1
                bs = mem.MEMORY.get(c_ptr, CHAR_LEN)
                lst.append(typ.bytes_to_string(bs))
            elif ch == "b":
                f = False
                bool_ptr = args[a_index]
                a_index += 1
                bb = mem.MEMORY.get(bool_ptr, BOOLEAN_LEN)
                bv = typ.bytes_to_bool(bb)
                lst.append("true" if bv else "false")
            else:
                print_warning("Unknown identifier '%{}'".format(ch))
                f = False
        else:
            lst.append(ch)
        i += 1
    string = "".join(lst)
    print(string)