Most of stdlib started working 55 tests pass

This commit is contained in:
Nathan Braswell
2016-03-08 16:04:59 -05:00
parent 5b3af2fa25
commit 2e6e87137d
4 changed files with 56 additions and 19 deletions

View File

@@ -390,7 +390,7 @@ obj ast_transformation (Object) {
return transform_value(node, scope)
}
print("FAILED TO TRANSFORM: "); print(name + ": "); println(concat_symbol_tree(node))
while(1) {}
error("FAILED TO TRANSFORM")
return null<ast_node>()
}
fun transform_all(nodes: vector<*tree<symbol>>, scope: *ast_node, template_replacements: map<string, *type>): vector<*ast_node> {
@@ -511,8 +511,8 @@ obj ast_transformation (Object) {
var declaration = ast_declaration_statement_ptr(identifier, expression)
// ok, deal with the possible init position method call
if (identifiers.size == 2) {
var method = transform(identifiers[1], identifier->identifier.type->type_def, template_replacements)
var parameters = get_nodes("parameter", node).map(fun(child: *tree<symbol>): *ast_node return transform(get_node("boolean_expression", child), scope, template_replacements);)
var method = transform(identifiers[1], identifier->identifier.type->type_def, search_type::function(parameters.map(fun(i:*ast_node):*type return get_ast_type(i);)), template_replacements)
declaration->declaration_statement.init_method_call = make_method_call(identifier, method, parameters)
}
return declaration
@@ -542,13 +542,38 @@ obj ast_transformation (Object) {
if (get_node("\"=\"", node)) {
var possible_assign = find_and_make_any_operator_overload_call(string("="), vector(assign_to, to_assign), scope, template_replacements)
if (possible_assign) {
println("Computed and returning operator=!")
println("Computed and returning operator=")
return possible_assign
}
} else if (get_node("\"\\+=\"", node)) to_assign = make_operator_call("+", vector(assign_to, to_assign))
else if (get_node("\"-=\"", node)) to_assign = make_operator_call("-", vector(assign_to, to_assign))
else if (get_node("\"\\*=\"", node)) to_assign = make_operator_call("*", vector(assign_to, to_assign))
else if (get_node("\"/=\"", node)) to_assign = make_operator_call("/", vector(assign_to, to_assign))
} else if (get_node("\"\\+=\"", node)) {
var possible_assign = find_and_make_any_operator_overload_call(string("+="), vector(assign_to, to_assign), scope, template_replacements)
if (possible_assign) {
print("Computed and returning operator+=")
return possible_assign
}
to_assign = make_operator_call("+", vector(assign_to, to_assign))
} else if (get_node("\"-=\"", node)) {
var possible_assign = find_and_make_any_operator_overload_call(string("-="), vector(assign_to, to_assign), scope, template_replacements)
if (possible_assign) {
print("Computed and returning operator-=")
return possible_assign
}
to_assign = make_operator_call("-", vector(assign_to, to_assign))
} else if (get_node("\"\\*=\"", node)) {
var possible_assign = find_and_make_any_operator_overload_call(string("*="), vector(assign_to, to_assign), scope, template_replacements)
if (possible_assign) {
print("Computed and returning operator*=")
return possible_assign
}
to_assign = make_operator_call("*", vector(assign_to, to_assign))
} else if (get_node("\"/=\"", node)){
var possible_assign = find_and_make_any_operator_overload_call(string("/="), vector(assign_to, to_assign), scope, template_replacements)
if (possible_assign) {
print("Computed and returning operator/=")
return possible_assign
}
to_assign = make_operator_call("/", vector(assign_to, to_assign))
}
var assignment = ast_assignment_statement_ptr(assign_to, to_assign)
return assignment
}

View File

@@ -226,7 +226,7 @@ obj c_generator (Object) {
top_level_c_passthrough += generate_simple_passthrough(backing.statement->statement.child, true)
}
ast_node::simple_passthrough(backing) top_level_c_passthrough += generate_simple_passthrough(child, true)
ast_node::declaration_statement(backing) variable_declarations += generate_declaration_statement(child, null<ast_node>(), null<ast_node>(), null<stack<pair<bool,stack<*ast_node>>>>(), true).one_string() + ";\n"
ast_node::declaration_statement(backing) variable_declarations += generate_declaration_statement(child, null<ast_node>(), null<ast_node>(), null<stack<pair<bool,stack<*ast_node>>>>(), false).one_string() + ";\n" // false - don't do defer
ast_node::function(backing) {
// check for and add to parameters if a closure
generate_function_definition(child, null<ast_node>())
@@ -262,7 +262,7 @@ obj c_generator (Object) {
var base_name = get_name(vert)
plain_typedefs += string("typedef struct ") + base_name + "_dummy " + base_name + ";\n"
structs += string("struct ") + base_name + "_dummy {\n"
vert->type_def.variables.for_each(fun(variable_declaration: *ast_node) structs += generate_declaration_statement(variable_declaration, null<ast_node>(), null<ast_node>(), null<stack<pair<bool,stack<*ast_node>>>>(), true).one_string() + ";\n";)
vert->type_def.variables.for_each(fun(variable_declaration: *ast_node) structs += generate_declaration_statement(variable_declaration, null<ast_node>(), null<ast_node>(), null<stack<pair<bool,stack<*ast_node>>>>(), false).one_string() + ";\n";) // also no defer stack
structs += "};\n"
// generate the methods (note some of these may be templates)
vert->type_def.methods.for_each(fun(method: *ast_node) {
@@ -342,7 +342,7 @@ obj c_generator (Object) {
to_ret.pre += ";\n"
to_ret += code_triple() + generate(node->declaration_statement.init_method_call, enclosing_object, enclosing_func, null<stack<pair<bool,stack<*ast_node>>>>())
}
if (add_to_defer && ident_type->is_object() && has_method(ident_type->type_def, "destruct", vector<*type>()))
if (add_to_defer && ident_type->is_object() && ident_type->indirection == 0 && has_method(ident_type->type_def, "destruct", vector<*type>()))
defer_stack->top().second.push(ast_statement_ptr(make_method_call(identifier, "destruct", vector<*ast_node>())))
return to_ret
}
@@ -377,14 +377,17 @@ obj c_generator (Object) {
return to_ret
}
fun generate_identifier(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node): code_triple {
var pre = code_triple()
if (get_ast_type(node)->is_ref)
pre += "*"
var pre = string()
var post = string()
if (get_ast_type(node)->is_ref) {
pre += "(*"
post += ")"
}
if (enclosing_func && enclosing_func->function.closed_variables.contains(node))
return pre + code_triple(string("(*(closure_data->") + get_name(node) + "))")
return code_triple(pre + string("(*(closure_data->") + get_name(node) + "))" + post)
if (enclosing_object && get_ast_scope(enclosing_object)->contains_key(node->identifier.name) && get_ast_scope(enclosing_object)->get(node->identifier.name).contains(node))
return pre + code_triple("(this->") + get_name(node) + ")"
return pre + code_triple(get_name(node))
return code_triple(pre + "(this->" + get_name(node) + ")" + post)
return code_triple(pre + get_name(node) + post)
}
fun generate_return_statement(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node, defer_stack: *stack<pair<bool,stack<*ast_node>>>): code_triple {
var return_value = node->return_statement.return_value
@@ -506,6 +509,7 @@ obj c_generator (Object) {
if (node->function_call.func->function_call.func->function.name == ".")
call_string += "&"
// having a null defer stack should be ok, as the only things we should get through here are identifiers and function calls
// XXX should it? wouldn't function calls be a problem?
call_string += generate(node->function_call.func->function_call.parameters[0], enclosing_object, enclosing_func, null<stack<pair<bool,stack<*ast_node>>>>())
} else if (is_identifier(node->function_call.func) || is_function(node->function_call.func)) {
// we handle the case when it's not this later, i.e. it's a lambda returned from another function or something
@@ -522,10 +526,11 @@ obj c_generator (Object) {
))
return code_triple("(") + generate(parameters[0], enclosing_object, enclosing_func, null<stack<pair<bool,stack<*ast_node>>>>()) + func_name + generate(parameters[1], enclosing_object, enclosing_func, null<stack<pair<bool,stack<*ast_node>>>>()) + string(")")
// don't propegate enclosing function down right of access
// XXX what about enclosing object? should it be the thing on the left?
if (func_name == "." || func_name == "->")
return code_triple("(") + generate(parameters[0], enclosing_object, enclosing_func, null<stack<pair<bool,stack<*ast_node>>>>()) + func_name + generate(parameters[1], null<ast_node>(), null<ast_node>(), null<stack<pair<bool,stack<*ast_node>>>>()) + string(")")
if (func_name == "[]")
return code_triple("(") + generate(parameters[0], enclosing_object, enclosing_func, null<stack<pair<bool,stack<*ast_node>>>>()) + "[" + generate(parameters[1], null<ast_node>(), null<ast_node>(), null<stack<pair<bool,stack<*ast_node>>>>()) + string("])")
return code_triple("(") + generate(parameters[0], enclosing_object, enclosing_func, null<stack<pair<bool,stack<*ast_node>>>>()) + "[" + generate(parameters[1], enclosing_object, enclosing_func, null<stack<pair<bool,stack<*ast_node>>>>()) + string("])")
// the post ones need to be post-ed specifically, and take the p off
if (func_name == "++p" || func_name == "--p")
return code_triple("(") + generate(parameters[0], enclosing_object, enclosing_func, null<stack<pair<bool,stack<*ast_node>>>>()) + ")" + func_name.slice(0,-2)
@@ -560,13 +565,17 @@ obj c_generator (Object) {
}
}
var pre_call = string()
if (func_return_type->is_object() && !func_return_type->is_ref && func_return_type->indirection == 0 && has_method(func_return_type->type_def, "destruct", vector<*type>())) {
// we now have temporary return variables for all objects, even without destruct so we can do chained method calls
// if (func_return_type->is_object() && !func_return_type->is_ref && func_return_type->indirection == 0 && has_method(func_return_type->type_def, "destruct", vector<*type>())) {
if (func_return_type->is_object() && !func_return_type->is_ref && func_return_type->indirection == 0) {
// kind of ugly combo here of
var temp_ident = ast_identifier_ptr(string("temporary_return")+get_id(), func_return_type, null<ast_node>())
var declaration = ast_declaration_statement_ptr(temp_ident, null<ast_node>())
// have to pass false to the declaration generator, so can't do it through generate_statement
call_string.pre += generate_declaration_statement(declaration, enclosing_object, enclosing_func, null<stack<pair<bool,stack<*ast_node>>>>(), false).one_string() + ";\n"
pre_call = generate_identifier(temp_ident, enclosing_object, enclosing_func).one_string()
// move destruct condition inside
if (has_method(func_return_type->type_def, "destruct", vector<*type>()))
call_string.post += generate_statement(ast_statement_ptr(make_method_call(temp_ident, "destruct", vector<*ast_node>())), enclosing_object, enclosing_func, null<stack<pair<bool,stack<*ast_node>>>>()).one_string()
}
var ref_pre = code_triple()

View File

@@ -160,6 +160,8 @@ obj type (Object) {
return string("impossible type, indirection:") + indirection
}
fun rank(): int {
if (indirection > 0)
return 5
match (base) {
base_type::character() return 1
base_type::integer() return 2

1
tests/.gitignore vendored
View File

@@ -1,2 +1,3 @@
tester
test_compiler
*.results