Fix this handling, other bytecode fixes
This commit is contained in:
@@ -12,6 +12,7 @@ import hash_set:*
|
||||
|
||||
import pass_common:*
|
||||
|
||||
|
||||
fun adt_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_syntax: *map<*ast_node, *tree<symbol>>) {
|
||||
var type_def_option_map = map<*ast_node, vector<*ast_node>>()
|
||||
var visited1 = hash_set<*ast_node>()
|
||||
@@ -25,7 +26,7 @@ fun adt_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_
|
||||
var replacement = ast_type_def_ptr(backing.name, false);
|
||||
// we're going to be replacing adt_def in the same ptr, so this works
|
||||
replacement->type_def.self_type = node->adt_def.self_type
|
||||
var replacement_this = make_this_noncached(replacement)
|
||||
|
||||
var option_union = ast_type_def_ptr(backing.name + "_union", true);
|
||||
node->adt_def.options.for_each(fun(opt: *ast_node) {
|
||||
if (!opt->identifier.type->is_empty_adt_option())
|
||||
@@ -69,18 +70,19 @@ fun adt_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_
|
||||
var block = ast_code_block_ptr()
|
||||
add_to_scope("~enclosing_scope", func, block)
|
||||
func->function.body_statement = block
|
||||
var func_this = func->function.this_param
|
||||
if (func->function.name == "operator==") {
|
||||
var other = func->function.parameters[0]
|
||||
var if_stmt = ast_if_statement_ptr(make_operator_call("!=", vector(make_operator_call("->", vector(replacement_this, flag)), make_operator_call(".", vector(other, flag)))))
|
||||
var if_stmt = ast_if_statement_ptr(make_operator_call("!=", vector(make_operator_call("->", vector(func_this, flag)), make_operator_call(".", vector(other, flag)))))
|
||||
if_stmt->if_statement.then_part = ast_return_statement_ptr(ast_value_ptr(string("false"), type_ptr(base_type::boolean())))
|
||||
block->code_block.children.add(if_stmt)
|
||||
|
||||
for (var i = 0; i < type_def_option_map[node].size; i++;) {
|
||||
if (get_ast_type(type_def_option_map[node][i])->is_empty_adt_option())
|
||||
continue
|
||||
var if_stmt_inner = ast_if_statement_ptr(make_operator_call("==", vector(make_operator_call("->", vector(replacement_this, flag)), ast_value_ptr(to_string(i), type_ptr(base_type::integer())))))
|
||||
var if_stmt_inner = ast_if_statement_ptr(make_operator_call("==", vector(make_operator_call("->", vector(func_this, flag)), ast_value_ptr(to_string(i), type_ptr(base_type::integer())))))
|
||||
var option = type_def_option_map[node][i]
|
||||
var our_option = make_operator_call(".", vector(make_operator_call("->", vector(replacement_this, option_union_ident)), option))
|
||||
var our_option = make_operator_call(".", vector(make_operator_call("->", vector(func_this, option_union_ident)), option))
|
||||
var their_option = make_operator_call(".", vector(make_operator_call(".", vector(other, option_union_ident)), option))
|
||||
if_stmt_inner->if_statement.then_part = ast_return_statement_ptr(possible_object_equality(our_option, their_option))
|
||||
block->code_block.children.add(if_stmt_inner)
|
||||
@@ -88,28 +90,28 @@ fun adt_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_
|
||||
block->code_block.children.add(ast_return_statement_ptr(ast_value_ptr(string("true"), type_ptr(base_type::boolean()))))
|
||||
} else if (func->function.name == "operator!=") {
|
||||
var other = func->function.parameters[0]
|
||||
block->code_block.children.add(ast_return_statement_ptr(make_operator_call("!", vector(make_method_call(replacement_this, "operator==", vector(other))))))
|
||||
block->code_block.children.add(ast_return_statement_ptr(make_operator_call("!", vector(make_method_call(func_this, "operator==", vector(other))))))
|
||||
} else if (func->function.name == "construct") {
|
||||
var value = ast_value_ptr(string("-1"), type_ptr(base_type::integer()))
|
||||
block->code_block.children.add(ast_assignment_statement_ptr(make_operator_call("->", vector(replacement_this, flag)), value))
|
||||
block->code_block.children.add(ast_return_statement_ptr(replacement_this))
|
||||
block->code_block.children.add(ast_assignment_statement_ptr(make_operator_call("->", vector(func_this, flag)), value))
|
||||
block->code_block.children.add(ast_return_statement_ptr(func_this))
|
||||
} else if (func->function.name == "copy_construct") {
|
||||
var other = func->function.parameters[0]
|
||||
block->code_block.children.add(ast_assignment_statement_ptr(make_operator_call("->", vector(replacement_this, flag)), make_operator_call("->", vector(other, flag))))
|
||||
block->code_block.children.add(ast_assignment_statement_ptr(make_operator_call("->", vector(func_this, flag)), make_operator_call("->", vector(other, flag))))
|
||||
for (var i = 0; i < type_def_option_map[node].size; i++;) {
|
||||
if (get_ast_type(type_def_option_map[node][i])->is_empty_adt_option())
|
||||
continue
|
||||
var if_stmt_inner = ast_if_statement_ptr(make_operator_call("==", vector(make_operator_call("->", vector(replacement_this, flag)), ast_value_ptr(to_string(i), type_ptr(base_type::integer())))))
|
||||
var if_stmt_inner = ast_if_statement_ptr(make_operator_call("==", vector(make_operator_call("->", vector(func_this, flag)), ast_value_ptr(to_string(i), type_ptr(base_type::integer())))))
|
||||
var option = type_def_option_map[node][i]
|
||||
var our_option = make_operator_call(".", vector(make_operator_call("->", vector(replacement_this, option_union_ident)), option))
|
||||
var our_option = make_operator_call(".", vector(make_operator_call("->", vector(func_this, option_union_ident)), option))
|
||||
var their_option = make_operator_call(".", vector(make_operator_call("->", vector(other, option_union_ident)), option))
|
||||
if_stmt_inner->if_statement.then_part = assign_or_copy_construct_statement(our_option, their_option)
|
||||
block->code_block.children.add(if_stmt_inner)
|
||||
}
|
||||
} else if (func->function.name == "operator=") {
|
||||
var other = func->function.parameters[0]
|
||||
block->code_block.children.add(make_method_call(replacement_this, "destruct", vector<*ast_node>()))
|
||||
block->code_block.children.add(make_method_call(replacement_this, "copy_construct", vector(make_operator_call("&", vector(other)))))
|
||||
block->code_block.children.add(make_method_call(func_this, "destruct", vector<*ast_node>()))
|
||||
block->code_block.children.add(make_method_call(func_this, "copy_construct", vector(make_operator_call("&", vector(other)))))
|
||||
} else if (func->function.name == "destruct") {
|
||||
for (var i = 0; i < type_def_option_map[node].size; i++;) {
|
||||
var option = type_def_option_map[node][i]
|
||||
@@ -117,8 +119,8 @@ fun adt_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_
|
||||
if (option_type->is_empty_adt_option())
|
||||
continue
|
||||
if (option_type->indirection == 0 && option_type->is_object() && has_method(option_type->type_def, "destruct", vector<*type>())) {
|
||||
var if_stmt_inner = ast_if_statement_ptr(make_operator_call("==", vector(make_operator_call("->", vector(replacement_this, flag)), ast_value_ptr(to_string(i), type_ptr(base_type::integer())))))
|
||||
var our_option = make_operator_call(".", vector(make_operator_call("->", vector(replacement_this, option_union_ident)), option))
|
||||
var if_stmt_inner = ast_if_statement_ptr(make_operator_call("==", vector(make_operator_call("->", vector(func_this, flag)), ast_value_ptr(to_string(i), type_ptr(base_type::integer())))))
|
||||
var our_option = make_operator_call(".", vector(make_operator_call("->", vector(func_this, option_union_ident)), option))
|
||||
if_stmt_inner->if_statement.then_part = make_method_call(our_option, "destruct", vector<*ast_node>())
|
||||
block->code_block.children.add(if_stmt_inner)
|
||||
}
|
||||
|
||||
@@ -296,9 +296,9 @@ obj adt_def (Object) {
|
||||
}
|
||||
}
|
||||
fun ast_function_ptr(name: string, type: *type, parameters: vector<*ast_node>, is_extern: bool): *ast_node
|
||||
return ast_function_ptr(name, type, parameters, is_extern, false)
|
||||
fun ast_function_ptr(name: string, type: *type, parameters: vector<*ast_node>, is_extern: bool, is_variadic: bool): *ast_node {
|
||||
var to_ret.construct(name, type, parameters, is_extern, is_variadic): function
|
||||
return ast_function_ptr(name, type, parameters, null<ast_node>(), is_extern, false)
|
||||
fun ast_function_ptr(name: string, type: *type, parameters: vector<*ast_node>, this_param: *ast_node, is_extern: bool, is_variadic: bool): *ast_node {
|
||||
var to_ret.construct(name, type, parameters, this_param, is_extern, is_variadic): function
|
||||
var ptr = new<ast_node>()
|
||||
ptr->copy_construct(&ast_node::function(to_ret))
|
||||
return ptr
|
||||
@@ -313,14 +313,16 @@ obj function (Object) {
|
||||
var name: string
|
||||
var type: *type
|
||||
var parameters: vector<*ast_node>
|
||||
var this_param: *ast_node
|
||||
var closed_variables: set<*ast_node>
|
||||
var body_statement: *ast_node
|
||||
var scope: map<string, vector<*ast_node>>
|
||||
var is_extern: bool
|
||||
var is_variadic: bool
|
||||
fun construct(name_in: string, type_in: *type, parameters_in: vector<*ast_node>, is_extern_in: bool, is_variadic_in: bool): *function {
|
||||
fun construct(name_in: string, type_in: *type, parameters_in: vector<*ast_node>, this_param_in: *ast_node, is_extern_in: bool, is_variadic_in: bool): *function {
|
||||
name.copy_construct(&name_in)
|
||||
parameters.copy_construct(¶meters_in)
|
||||
this_param = this_param_in
|
||||
closed_variables.construct()
|
||||
scope.construct()
|
||||
type = type_in
|
||||
@@ -334,6 +336,7 @@ obj function (Object) {
|
||||
type = old->type
|
||||
body_statement = old->body_statement
|
||||
parameters.copy_construct(&old->parameters)
|
||||
this_param = old->this_param
|
||||
closed_variables.copy_construct(&old->closed_variables)
|
||||
scope.copy_construct(&old->scope)
|
||||
is_extern = old->is_extern
|
||||
@@ -350,7 +353,7 @@ obj function (Object) {
|
||||
copy_construct(&other)
|
||||
}
|
||||
fun operator==(other: ref function): bool {
|
||||
return name == name && type == other.type && parameters == other.parameters && body_statement == other.body_statement && closed_variables == other.closed_variables && is_extern == other.is_extern && is_variadic == other.is_variadic
|
||||
return name == name && type == other.type && parameters == other.parameters && this_param == other.this_param && body_statement == other.body_statement && closed_variables == other.closed_variables && is_extern == other.is_extern && is_variadic == other.is_variadic
|
||||
}
|
||||
}
|
||||
fun ast_template_ptr(name: string, syntax_node: *tree<symbol>, template_types: vector<string>, template_type_replacements: map<string, *type>, is_function: bool): *ast_node {
|
||||
|
||||
@@ -188,12 +188,24 @@ obj ast_transformation (Object) {
|
||||
var copy_construct_param = ast_identifier_ptr(string("in"), node->adt_def.self_type->clone_with_indirection(1,false), node)
|
||||
var assign_param = ast_identifier_ptr(string("in"), node->adt_def.self_type->clone_with_indirection(0,true), node)
|
||||
vector(
|
||||
make_pair("operator==", ast_function_ptr(string("operator=="), type_ptr(vector(equals_param->identifier.type), type_ptr(base_type::boolean()), 0, false, false, true), vector(equals_param), false)),
|
||||
make_pair("operator!=", ast_function_ptr(string("operator!="), type_ptr(vector(nequals_param->identifier.type), type_ptr(base_type::boolean()), 0, false, false, true), vector(nequals_param), false)),
|
||||
make_pair("construct", ast_function_ptr(string("construct"), type_ptr(vector<*type>(), node->adt_def.self_type->clone_with_increased_indirection(), 0, false, false, true), vector<*ast_node>(), false)),
|
||||
make_pair("copy_construct", ast_function_ptr(string("copy_construct"), type_ptr(vector(copy_construct_param->identifier.type), type_ptr(base_type::void_return()), 0, false, false, true), vector(copy_construct_param), false)),
|
||||
make_pair("operator=", ast_function_ptr(string("operator="), type_ptr(vector(assign_param->identifier.type), type_ptr(base_type::void_return()), 0, false, false, true), vector(assign_param), false)),
|
||||
make_pair("destruct", ast_function_ptr(string("destruct"), type_ptr(vector<*type>(), type_ptr(base_type::void_return()), 0, false, false, true), vector<*ast_node>(), false))
|
||||
make_pair("operator==", ast_function_ptr(string("operator=="),
|
||||
type_ptr(vector(equals_param->identifier.type), type_ptr(base_type::boolean()), 0, false, false, true),
|
||||
vector(equals_param), ast_identifier_ptr("this", node->adt_def.self_type->clone_with_indirection(1), node), false, false)),
|
||||
make_pair("operator!=", ast_function_ptr(string("operator!="),
|
||||
type_ptr(vector(nequals_param->identifier.type), type_ptr(base_type::boolean()), 0, false, false, true),
|
||||
vector(nequals_param), ast_identifier_ptr("this", node->adt_def.self_type->clone_with_indirection(1), node), false, false)),
|
||||
make_pair("construct", ast_function_ptr(string("construct"),
|
||||
type_ptr(vector<*type>(), node->adt_def.self_type->clone_with_increased_indirection(), 0, false, false, true),
|
||||
vector<*ast_node>(), ast_identifier_ptr("this", node->adt_def.self_type->clone_with_indirection(1), node), false, false)),
|
||||
make_pair("copy_construct", ast_function_ptr(string("copy_construct"),
|
||||
type_ptr(vector(copy_construct_param->identifier.type), type_ptr(base_type::void_return()), 0, false, false, true),
|
||||
vector(copy_construct_param), ast_identifier_ptr("this", node->adt_def.self_type->clone_with_indirection(1), node), false, false)),
|
||||
make_pair("operator=", ast_function_ptr(string("operator="),
|
||||
type_ptr(vector(assign_param->identifier.type), type_ptr(base_type::void_return()), 0, false, false, true),
|
||||
vector(assign_param), ast_identifier_ptr("this", node->adt_def.self_type->clone_with_indirection(1), node), false, false)),
|
||||
make_pair("destruct", ast_function_ptr(string("destruct"),
|
||||
type_ptr(vector<*type>(), type_ptr(base_type::void_return()), 0, false, false, true),
|
||||
vector<*ast_node>(), ast_identifier_ptr("this", node->adt_def.self_type->clone_with_indirection(1), node), false, false))
|
||||
).for_each(fun(func_pair: pair<*char, *ast_node>) {
|
||||
node->adt_def.regular_funcs.add(func_pair.second)
|
||||
add_to_scope(string(func_pair.first), func_pair.second, node)
|
||||
@@ -238,10 +250,19 @@ obj ast_transformation (Object) {
|
||||
})
|
||||
var is_variadic = get_node("\"...\"", node) != null<tree<symbol>>()
|
||||
var is_raw = function_name != "__compiler_lambda__"
|
||||
var this_param = null<ast_node>()
|
||||
if (is_type_def(scope)) {
|
||||
this_param = ast_identifier_ptr("this", scope->type_def.self_type->clone_with_indirection(1), scope)
|
||||
} else if (is_template(scope)) {
|
||||
var parent_scope = get_ast_scope(scope)->get(string("~enclosing_scope"))[0]
|
||||
if (is_type_def(parent_scope)) {
|
||||
this_param = ast_identifier_ptr("this", parent_scope->type_def.self_type->clone_with_indirection(1), parent_scope)
|
||||
}
|
||||
}
|
||||
// figure out function type and make function_node
|
||||
var function_node = ast_function_ptr(function_name,
|
||||
type_ptr(parameters.map(fun(parameter: *ast_node): *type return parameter->identifier.type;),
|
||||
return_type, 0, false, is_variadic, is_raw), parameters, get_node("\"ext\"", node) != null<tree<symbol>>(), is_variadic)
|
||||
return_type, 0, false, is_variadic, is_raw), parameters, this_param, get_node("\"ext\"", node) != null<tree<symbol>>(), is_variadic)
|
||||
// fix up the enclosing_scope's
|
||||
parameters.for_each(fun(n: *ast_node) n->identifier.enclosing_scope = function_node;)
|
||||
// add to scope
|
||||
@@ -470,17 +491,15 @@ obj ast_transformation (Object) {
|
||||
fun transform_all(nodes: vector<*tree<symbol>>, scope: *ast_node, template_replacements: map<string, *type>): vector<*ast_node> {
|
||||
return nodes.map(fun(node: *tree<symbol>): *ast_node return transform(node, scope, template_replacements);)
|
||||
}
|
||||
fun make_this(object: *ast_node): *ast_node {
|
||||
if (!type_def_to_this.contains_key(object))
|
||||
type_def_to_this[object] = ast_identifier_ptr("this", object->type_def.self_type->clone_with_indirection(1), object)
|
||||
return type_def_to_this[object]
|
||||
}
|
||||
fun transform_identifier(node: *tree<symbol>, scope: *ast_node, searching_for: search_type): *ast_node {
|
||||
// first, we check for and generate this
|
||||
var name = concat_symbol_tree(node)
|
||||
if (name == "this") {
|
||||
while (!is_type_def(scope)) scope = get_ast_scope(scope)->get(string("~enclosing_scope"))[0]
|
||||
return make_this(scope)
|
||||
while (!is_function(scope) || scope->function.this_param == null<ast_node>())
|
||||
scope = get_ast_scope(scope)->get(string("~enclosing_scope"))[0]
|
||||
if (!is_function(scope))
|
||||
error(node, "Couldn't find this")
|
||||
return scope->function.this_param
|
||||
}
|
||||
match (searching_for) {
|
||||
search_type::none() return identifier_lookup(name, scope)
|
||||
|
||||
@@ -93,7 +93,7 @@ fun size_to_operand_size(size: ulong): operand_size {
|
||||
if (size == 2) return operand_size::b16()
|
||||
if (size == 4) return operand_size::b32()
|
||||
if (size == 8) return operand_size::b64()
|
||||
error("invalid operand size")
|
||||
error(string("invalid operand size ") + size)
|
||||
}
|
||||
adt byte_inst {
|
||||
nop,
|
||||
@@ -580,7 +580,7 @@ obj bytecode_generator (Object) {
|
||||
if (node->value.value_type->is_bool())
|
||||
return emit_imm((node->value.string_value == "true") cast long)
|
||||
else if (node->value.value_type->base == base_type::character() && node->value.value_type->indirection == 1)
|
||||
return emit_imm((&node->value.string_value[0]) cast long)
|
||||
return emit_imm((node->value.string_value.toCharArray()) cast long)
|
||||
else
|
||||
return emit_imm(string_to_num<int>(node->value.string_value))
|
||||
}
|
||||
@@ -660,19 +660,20 @@ obj bytecode_generator (Object) {
|
||||
} else if (name == "!") {
|
||||
return emit_ez(params[0])
|
||||
} else if (name == "[]" || (name == "*" && params.size == 1)) {
|
||||
var derefed_size = type_size(lhs_type->clone_with_decreased_indirection())
|
||||
var derefed_type = lhs_type->clone_with_decreased_indirection()
|
||||
var derefed_size = type_size(derefed_type)
|
||||
if (name == "[]") {
|
||||
var offset_reg = params[1]
|
||||
if (derefed_size != 1)
|
||||
offset_reg = emit_smul(offset_reg, emit_imm(derefed_size))
|
||||
var addr_reg = emit_add(params[0], offset_reg)
|
||||
if (lvalue)
|
||||
if (lvalue || (derefed_type->is_object() && derefed_type->indirection == 0))
|
||||
return addr_reg
|
||||
else
|
||||
return emit_ldr(addr_reg, 0, size_to_operand_size(derefed_size))
|
||||
}
|
||||
if (name == "*") {
|
||||
if (lvalue)
|
||||
if (lvalue || (derefed_type->is_object() && derefed_type->indirection == 0))
|
||||
return params[0]
|
||||
else
|
||||
return emit_ldr(params[0], 0, size_to_operand_size(derefed_size))
|
||||
|
||||
@@ -240,14 +240,6 @@ fun function_value_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node
|
||||
lambda_creation_funcs[l]->function.parameters.add(closure_param)
|
||||
body->code_block.children.add(ast_assignment_statement_ptr(access_expression(ident, "data"), closure_param))
|
||||
l->function.closed_variables.for_each(fun(v: *ast_node) {
|
||||
// HACK
|
||||
/*if (v->identifier.name == "this") {*/
|
||||
/*// add in an assignment at the beginning of the lambda*/
|
||||
/*if (!is_code_block(l->function.body_statement))*/
|
||||
/*error("lambda body isn't a block in function_value_lower")*/
|
||||
/*l->function.body_statement->code_block.children.add(0, ast_declaration_statement_ptr(ast_identifier_ptr("this", v->identifier.type, l->function.body_statement),*/
|
||||
/*make_operator_call("*", vector(access_expression(closure_lambda_param, v->identifier.name)))))*/
|
||||
/*}*/
|
||||
// have to make sure to clean here as well
|
||||
var closed_param_type = v->identifier.type
|
||||
if (lambda_type_to_struct_type_and_call_func.contains_key(*closed_param_type))
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
|
||||
// This is a reminder to take out the generated this hack in function_value_lower.krak
|
||||
|
||||
@@ -329,7 +329,7 @@ fun obj_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_
|
||||
})
|
||||
fun_to_obj.for_each(fun(method: *ast_node, object: *ast_node) {
|
||||
var this_type = object->type_def.self_type->clone_with_increased_indirection()
|
||||
var this_ident = ast_identifier_ptr("this", this_type, method)
|
||||
var this_ident = method->function.this_param
|
||||
method->function.parameters.add(0, this_ident)
|
||||
add_to_scope("this", this_ident, method)
|
||||
add_to_scope("~enclosing_scope", method, this_ident)
|
||||
|
||||
@@ -6,9 +6,6 @@ import stack:*
|
||||
import string:*
|
||||
import hash_set:*
|
||||
|
||||
fun make_this_noncached(object: *ast_node): *ast_node {
|
||||
return ast_identifier_ptr("this", object->type_def.self_type->clone_with_indirection(1), object)
|
||||
}
|
||||
fun get_first_terminal(source: *tree<symbol>): *tree<symbol> {
|
||||
if (!source)
|
||||
return null<tree<symbol>>()
|
||||
|
||||
Reference in New Issue
Block a user