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)
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
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
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
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()
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
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)
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")
def free(ptr): b = mem.MEMORY.get(ptr, mem.MEMORY.pointer_length) loc = typ.bytes_to_int(b) mem.MEMORY.free(loc)
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)