diff --git a/kraken.krak b/kraken.krak index 2492bfa..c4f10de 100644 --- a/kraken.krak +++ b/kraken.krak @@ -12,6 +12,7 @@ import ast_transformation:* import adt_lower:* import obj_lower:* import defer_lower:* +import ctce_lower:* import c_line_control:* import c_generator:* import compiler_version @@ -121,6 +122,8 @@ fun main(argc: int, argv: **char):int { obj_lower(&importer.name_ast_map, &importer.ast_pass.ast_to_syntax) printlnerr("Lowering Defer") defer_lower(&importer.name_ast_map, &importer.ast_pass.ast_to_syntax) + printlnerr("Lowering CTCE") + ctce_lower(&importer.name_ast_map, &importer.ast_pass.ast_to_syntax) if (interpret_instead) { printlnerr("Interpreting!") call_main(importer.name_ast_map) diff --git a/krakenGrammer.kgm b/krakenGrammer.kgm index 2a12825..9cceca1 100644 --- a/krakenGrammer.kgm +++ b/krakenGrammer.kgm @@ -116,9 +116,7 @@ continue_statement = "continue" ; defer_statement = "defer" WS statement ; function_call = unarad WS "\(" WS opt_parameter_list WS "\)" ; -compiler_intrinsic = "#" identifier WS "\(" WS intrinsic_parameter_list WS "\)" | "#" identifier WS "<" WS type_list WS ">" ; -intrinsic_parameter_list = intrinsic_parameter_list WS "," WS intrinsic_parameter | intrinsic_parameter ; -intrinsic_parameter = identifier ; +compiler_intrinsic = "#" identifier WS "\(" WS opt_parameter_list WS "\)" | "#" identifier WS "<" WS type_list WS ">" ; boolean_expression = boolean_expression WS "\|\|" WS and_boolean_expression | and_boolean_expression ; and_boolean_expression = and_boolean_expression WS "&&" WS bitwise_or | bitwise_or ; diff --git a/stdlib/adt_lower.krak b/stdlib/adt_lower.krak index 95f2156..5ac2c7e 100644 --- a/stdlib/adt_lower.krak +++ b/stdlib/adt_lower.krak @@ -43,19 +43,19 @@ fun adt_lower(name_ast_map: *map,*ast_node>>, ast_to_ node->adt_def.option_funcs.for_each(fun(func: *ast_node) { var adt_type = replacement->type_def.self_type var block = ast_code_block_ptr() - func->function.body_statement = ast_statement_ptr(block) + func->function.body_statement = block var to_ret = ast_identifier_ptr(string("to_ret"), adt_type, block) - block->code_block.children.add(ast_statement_ptr(ast_declaration_statement_ptr(to_ret, null(), false))) + block->code_block.children.add(ast_declaration_statement_ptr(to_ret, null(), false)) var value = ast_value_ptr(to_string(idx), type_ptr(base_type::integer())) - block->code_block.children.add(ast_statement_ptr(ast_assignment_statement_ptr(make_operator_call(".", vector(to_ret, flag)), value))) + block->code_block.children.add(ast_assignment_statement_ptr(make_operator_call(".", vector(to_ret, flag)), value)) var opt = type_def_option_map[node][idx] var lvalue = make_operator_call(".", vector(make_operator_call(".", vector(to_ret, option_union_ident)), opt)) if (func->function.parameters.size) { // do copy_construct if it should - block->code_block.children.add(ast_statement_ptr(assign_or_copy_construct_statement(lvalue, func->function.parameters[0]))) + block->code_block.children.add(assign_or_copy_construct_statement(lvalue, func->function.parameters[0])) } - block->code_block.children.add(ast_statement_ptr(ast_return_statement_ptr(to_ret))) + block->code_block.children.add(ast_return_statement_ptr(to_ret)) add_before_in(func, node, parent_chain) add_to_scope(func->function.name, func, enclosing_scope) add_to_scope("~enclosing_scope", enclosing_scope, func) @@ -63,11 +63,11 @@ fun adt_lower(name_ast_map: *map,*ast_node>>, ast_to_ }) node->adt_def.regular_funcs.for_each(fun(func: *ast_node) { var block = ast_code_block_ptr() - func->function.body_statement = ast_statement_ptr(block) + func->function.body_statement = block 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))))) - if_stmt->if_statement.then_part = ast_statement_ptr(ast_return_statement_ptr(ast_value_ptr(string("false"), type_ptr(base_type::boolean())))) + 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++;) { @@ -77,20 +77,20 @@ fun adt_lower(name_ast_map: *map,*ast_node>>, ast_to_ 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 their_option = make_operator_call(".", vector(make_operator_call(".", vector(other, option_union_ident)), option)) - if_stmt_inner->if_statement.then_part = ast_statement_ptr(ast_return_statement_ptr(possible_object_equality(our_option, their_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) } - block->code_block.children.add(ast_statement_ptr(ast_return_statement_ptr(ast_value_ptr(string("true"), type_ptr(base_type::boolean()))))) + 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_statement_ptr(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(replacement_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_statement_ptr(ast_assignment_statement_ptr(make_operator_call("->", vector(replacement_this, flag)), value))) - block->code_block.children.add(ast_statement_ptr(ast_return_statement_ptr(replacement_this))) + 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)) } else if (func->function.name == "copy_construct") { var other = func->function.parameters[0] - block->code_block.children.add(ast_statement_ptr(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(replacement_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 @@ -98,13 +98,13 @@ fun adt_lower(name_ast_map: *map,*ast_node>>, ast_to_ 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 their_option = make_operator_call(".", vector(make_operator_call("->", vector(other, option_union_ident)), option)) - if_stmt_inner->if_statement.then_part = ast_statement_ptr(assign_or_copy_construct_statement(our_option, their_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(ast_statement_ptr(make_method_call(replacement_this, "destruct", vector<*ast_node>()))) - block->code_block.children.add(ast_statement_ptr(make_method_call(replacement_this, "copy_construct", vector(make_operator_call("&", vector(other)))))) + 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))))) } 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] @@ -114,7 +114,7 @@ fun adt_lower(name_ast_map: *map,*ast_node>>, ast_to_ 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)) - if_stmt_inner->if_statement.then_part = ast_statement_ptr(make_method_call(our_option, "destruct", vector<*ast_node>())) + if_stmt_inner->if_statement.then_part = make_method_call(our_option, "destruct", vector<*ast_node>()) block->code_block.children.add(if_stmt_inner) } } @@ -138,8 +138,8 @@ fun adt_lower(name_ast_map: *map,*ast_node>>, ast_to_ var block = ast_code_block_ptr() var value = backing.value var holder = ast_identifier_ptr(string("holder"), get_ast_type(value)->clone_with_increased_indirection(), block) - block->code_block.children.add(ast_statement_ptr(ast_declaration_statement_ptr(holder, null(), false))) - block->code_block.children.add(ast_statement_ptr(ast_assignment_statement_ptr(holder, make_operator_call("&", vector(value))))) + block->code_block.children.add(ast_declaration_statement_ptr(holder, null(), false)) + block->code_block.children.add(ast_assignment_statement_ptr(holder, make_operator_call("&", vector(value)))) backing.cases.for_each(fun(case_stmt: *ast_node) { var option = case_stmt->case_statement.option var flag = get_from_scope(get_ast_type(value)->type_def, "flag") @@ -158,7 +158,7 @@ fun adt_lower(name_ast_map: *map,*ast_node>>, ast_to_ var get_option = make_operator_call(".", vector(make_operator_call("->", vector(holder, data)), option)) get_option = make_operator_call("&", vector(get_option)) unpack_ident->identifier.type = unpack_ident->identifier.type->clone_with_ref() - inner_block->code_block.children.add(ast_statement_ptr(ast_declaration_statement_ptr(unpack_ident, get_option, false))) + inner_block->code_block.children.add(ast_declaration_statement_ptr(unpack_ident, get_option, false)) } inner_block->code_block.children.add(case_stmt->case_statement.statement) if_stmt->if_statement.then_part = inner_block diff --git a/stdlib/ast_nodes.krak b/stdlib/ast_nodes.krak index 50f4e05..d837919 100644 --- a/stdlib/ast_nodes.krak +++ b/stdlib/ast_nodes.krak @@ -21,7 +21,6 @@ adt ast_node { function: function, template: template, code_block: code_block, - statement: statement, if_statement: if_statement, match_statement: match_statement, case_statement: case_statement, @@ -458,42 +457,6 @@ obj code_block (Object) { return children == other.children && scope == other.scope } } -fun ast_statement_ptr(child: *ast_node): *ast_node { - var to_ret.construct(child): statement - var ptr = new() - ptr->copy_construct(&ast_node::statement(to_ret)) - return ptr -} -fun is_statement(node: *ast_node): bool { - match(*node) { - ast_node::statement(backing) return true - } - return false -} -obj statement (Object) { - var scope: map> - var child: *ast_node - fun construct(child_in: *ast_node): *statement { - child = null() - scope.construct() - child = child_in - return this - } - fun copy_construct(old: *statement) { - scope.copy_construct(&old->scope) - child = old->child - } - fun destruct() { - scope.destruct() - } - fun operator=(other: ref statement) { - destruct() - copy_construct(&other) - } - fun operator==(other: ref statement): bool { - return child == other.child - } -} fun ast_if_statement_ptr(condition: *ast_node): *ast_node { var to_ret.construct(condition): if_statement var ptr = new() @@ -992,7 +955,7 @@ obj function_call (Object) { return func == func && parameters == other.parameters } } -fun ast_compiler_intrinsic_ptr(intrinsic: string, parameters: vector, type_parameters: vector<*type>, return_type: *type): *ast_node { +fun ast_compiler_intrinsic_ptr(intrinsic: string, parameters: vector<*ast_node>, type_parameters: vector<*type>, return_type: *type): *ast_node { var to_ret.construct(intrinsic, parameters, type_parameters, return_type): compiler_intrinsic var ptr = new() ptr->copy_construct(&ast_node::compiler_intrinsic(to_ret)) @@ -1006,10 +969,10 @@ fun is_compiler_intrinsic(node: *ast_node): bool { } obj compiler_intrinsic (Object) { var intrinsic: string - var parameters: vector + var parameters: vector<*ast_node> var type_parameters: vector<*type> var return_type: *type - fun construct(intrinsic_in: string, parameters_in: vector, type_parameters_in: vector<*type>, return_type_in: *type): *compiler_intrinsic { + fun construct(intrinsic_in: string, parameters_in: vector<*ast_node>, type_parameters_in: vector<*type>, return_type_in: *type): *compiler_intrinsic { intrinsic.copy_construct(&intrinsic_in) parameters.copy_construct(¶meters_in) type_parameters.copy_construct(&type_parameters_in) @@ -1120,7 +1083,6 @@ fun get_ast_children(node: *ast_node): vector<*ast_node> { ast_node::function(backing) return backing.parameters + backing.body_statement ast_node::template(backing) return backing.instantiated ast_node::code_block(backing) return backing.children - ast_node::statement(backing) return vector<*ast_node>(backing.child) ast_node::if_statement(backing) return vector(backing.condition, backing.then_part, backing.else_part) ast_node::match_statement(backing) return vector(backing.value) + backing.cases ast_node::case_statement(backing) return vector(backing.option, backing.unpack_ident, backing.statement) @@ -1159,7 +1121,6 @@ fun get_ast_name(node: *ast_node): string { } ast_node::template(backing) return string("template: ") + backing.name ast_node::code_block(backing) return string("code_block") - ast_node::statement(backing) return string("statement") ast_node::if_statement(backing) return string("if_statement") ast_node::match_statement(backing) return string("match_statement") ast_node::case_statement(backing) return string("case_statement") @@ -1189,7 +1150,6 @@ fun get_ast_scope(node: *ast_node): *map> { ast_node::function() return &node->function.scope ast_node::template() return &node->template.scope ast_node::code_block() return &node->code_block.scope - ast_node::statement() return &node->statement.scope ast_node::if_statement() return &node->if_statement.scope ast_node::match_statement() return &node->match_statement.scope ast_node::case_statement() return &node->case_statement.scope diff --git a/stdlib/ast_transformation.krak b/stdlib/ast_transformation.krak index efba91c..6249c13 100644 --- a/stdlib/ast_transformation.krak +++ b/stdlib/ast_transformation.krak @@ -607,9 +607,7 @@ obj ast_transformation (Object) { return new_passthrough } fun transform_statement(node: *tree, scope: *ast_node, template_replacements: map): *ast_node { - var to_ret = ast_statement_ptr(transform(node->children[0], scope, template_replacements)); - ast_to_syntax.set(to_ret, node) - return to_ret + return transform(node->children[0], scope, template_replacements); } fun transform_declaration_statement(node: *tree, scope: *ast_node, template_replacements: map): *ast_node { // this might have an init position method call @@ -759,6 +757,7 @@ obj ast_transformation (Object) { error(node, string("the number of adts found was not 1, it was ") + the_adts.size + " for " + concat_symbol_tree(get_node("scoped_identifier", node))) var the_adt = the_adts[0] var the_option_name = concat_symbol_tree(get_node("identifier", get_node("scoped_identifier", node))) + // ADD IN ERROR CHECKING HERE var the_option = the_adt->adt_def.options.find_first_satisfying(fun(option: *ast_node): bool return option->identifier.name == the_option_name;) to_ret->case_statement.option = the_option var possible_ident = get_node("identifier", node) @@ -779,32 +778,26 @@ obj ast_transformation (Object) { var func = transform(get_node("unarad", node), scope, search_type::function(parameter_types), template_replacements) // may return an identifier of type object if doing operator() - but the () have been stripped out by importer if (get_ast_type(func)->is_object()) { - /*println("Making an operator() method call!")*/ return make_method_call(func, "operator", parameters) } var f = ast_function_call_ptr(func, parameters) - /*print("function call function ")*/ - /*println(f->function_call.func)*/ - /*print("function call parameters ")*/ - /*f->function_call.parameters.for_each(fun(param: *ast_node) print(param);)*/ return f } fun transform_compiler_intrinsic(node: *tree, scope: *ast_node, template_replacements: map): *ast_node { - // don't bother with a full transform for parameters with their own function, just get the boolean expression and transform it - var parameters = vector() - var type_parameters = vector<*type>() - if (get_nodes("intrinsic_parameter", node).size) - parameters = get_nodes("intrinsic_parameter", node).map(fun(child: *tree): string return concat_symbol_tree(child);) - if (get_nodes("type", node).size) - type_parameters = get_nodes("type", node).map(fun(child: *tree): *type return transform_type(child, scope, template_replacements);) - return ast_compiler_intrinsic_ptr(concat_symbol_tree(get_node("identifier", node)), parameters, type_parameters, type_ptr(base_type::ulong_int())) - /*return ast_compiler_intrinsic_ptr(concat_symbol_tree(get_node("identifier", node)), parameters, type_parameters, type_ptr(base_type::integer()))*/ + var parameters = get_nodes("parameter", node).map(fun(child: *tree): *ast_node return transform(get_node("boolean_expression", child), scope, template_replacements);) + var type_parameters = get_nodes("type", node).map(fun(child: *tree): *type return transform_type(child, scope, template_replacements);) + var intrinsic_name = concat_symbol_tree(get_node("identifier", node)) + var intrinsic_return_type: *type + if (intrinsic_name == "ctce") + intrinsic_return_type = get_ast_type(parameters[0]) + else + intrinsic_return_type = type_ptr(base_type::ulong_int()) + return ast_compiler_intrinsic_ptr(intrinsic_name, parameters, type_parameters, intrinsic_return_type) } fun transform_lambda(node: *tree, scope: *ast_node, template_replacements: map): *ast_node { var function_node = second_pass_function(node, scope, template_replacements, false) function_node->function.body_statement = transform_statement(get_node("statement", node), function_node, template_replacements) function_node->function.closed_variables = find_closed_variables(function_node, function_node->function.body_statement) - /*println(string("Found ") + function_node->function.closed_variables.size() + " closed variables!")*/ while (!is_translation_unit(scope)) scope = get_ast_scope(scope)->get(string("~enclosing_scope"))[0] scope->translation_unit.lambdas.add(function_node) return function_node @@ -816,9 +809,6 @@ obj ast_transformation (Object) { if (!in_scope_chain(backing.enclosing_scope, func)) return set(node); } - ast_node::statement(backing) { - return find_closed_variables(func, backing.child) - } ast_node::code_block(backing) { var to_ret = set<*ast_node>() backing.children.for_each(fun(n: *ast_node) to_ret += find_closed_variables(func, n);) @@ -894,7 +884,8 @@ obj ast_transformation (Object) { return in_scope_chain(get_ast_scope(node)->get(string("~enclosing_scope"))[0], high_scope) return false } - fun transform_expression(node: *tree, scope: *ast_node, template_replacements: map): *ast_node return transform_expression(node, scope, search_type::none(), template_replacements) + fun transform_expression(node: *tree, scope: *ast_node, template_replacements: map): *ast_node + return transform_expression(node, scope, search_type::none(), template_replacements) fun transform_expression(node: *tree, scope: *ast_node, searching_for: search_type, template_replacements: map): *ast_node { var func_name = string() var parameters = vector<*ast_node>() diff --git a/stdlib/c_generator.krak b/stdlib/c_generator.krak index f82e6c7..2985a49 100644 --- a/stdlib/c_generator.krak +++ b/stdlib/c_generator.krak @@ -229,8 +229,8 @@ obj c_generator (Object) { if (!backing.is_extern) function_definitions += prototype_and_header.second if (backing.body_statement) { - function_definitions += string(" {\n") + generate_statement(backing.body_statement, enclosing_object, child).one_string() - function_definitions += "}\n" + function_definitions += string(" {\n") + generate(backing.body_statement, enclosing_object, child, false).one_string() + function_definitions += ";\n}\n" } else if (!backing.is_extern) { error("Empty function statement and not extern - no ADTs anymore!") } @@ -256,8 +256,8 @@ obj c_generator (Object) { match (*child) { // should really check the genrator ast_node::if_comp(backing) { - if (is_simple_passthrough(backing.statement->statement.child)) - top_level_c_passthrough += generate_simple_passthrough(backing.statement->statement.child, true) + if (is_simple_passthrough(backing.statement)) + top_level_c_passthrough += generate_simple_passthrough(backing.statement, 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(), null(), false).one_string() + ";\n" // false - don't do defer @@ -368,7 +368,6 @@ obj c_generator (Object) { return pre + result + post return pre + "{" + result + "}" + post } - fun generate_statement(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node): code_triple return generate(node->statement.child, enclosing_object, enclosing_func, false) + ";\n"; fun generate_declaration_statement(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node, add_to_defer: bool): code_triple { var identifier = node->declaration_statement.identifier var ident_type = identifier->identifier.type @@ -508,7 +507,7 @@ obj c_generator (Object) { } fun generate_code_block(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node): code_triple { var to_ret = code_triple("{\n") - node->code_block.children.for_each(fun(child: *ast_node) to_ret += generate(child, enclosing_object, enclosing_func, false).one_string();) + node->code_block.children.for_each(fun(child: *ast_node) to_ret += generate(child, enclosing_object, enclosing_func, false).one_string() + ";\n";) return to_ret + "}" } // this generates the function as a value, not the actual function @@ -682,8 +681,8 @@ obj c_generator (Object) { error("wrong parameters to sizeof compiler intrinsic") return code_triple("sizeof(") + type_to_c(node->compiler_intrinsic.type_parameters[0]) + ")" } else if (node->compiler_intrinsic.intrinsic == "link") { - node->compiler_intrinsic.parameters.for_each(fun(str: string) { - linker_string += string("-l") + str + " " + node->compiler_intrinsic.parameters.for_each(fun(value: *ast_node) { + linker_string += string("-l") + value->value.string_value.slice(1,-2) + " " }) return code_triple() } @@ -697,7 +696,6 @@ obj c_generator (Object) { match (*node) { ast_node::if_comp(backing) return generate_if_comp(node, enclosing_object, enclosing_func) ast_node::simple_passthrough(backing) return code_triple() + generate_simple_passthrough(node, false) - ast_node::statement(backing) return generate_statement(node, enclosing_object, enclosing_func) ast_node::declaration_statement(backing) return generate_declaration_statement(node, enclosing_object, enclosing_func, true) ast_node::assignment_statement(backing) return generate_assignment_statement(node, enclosing_object, enclosing_func) ast_node::if_statement(backing) return generate_if_statement(node, enclosing_object, enclosing_func) diff --git a/stdlib/c_line_control.krak b/stdlib/c_line_control.krak index 2a19b05..b089d1b 100644 --- a/stdlib/c_line_control.krak +++ b/stdlib/c_line_control.krak @@ -20,18 +20,16 @@ fun get_line(node: *tree, name: string): *ast_node { fun c_line_control(name_ast_map: *map,*ast_node>>, ast_to_syntax: *map<*ast_node, *tree>) { var first = true name_ast_map->for_each(fun(name: string, syntax_ast_pair: pair<*tree,*ast_node>) { - var helper = fun(node: *ast_node, parent_chain: *stack<*ast_node>) { - match(*node) { - ast_node::statement(backing) { - if (is_code_block(parent_chain->top()) && ast_to_syntax->contains_key(node)) { + /*var helper = fun(node: *ast_node, parent_chain: *stack<*ast_node>) {*/ + /*match(*node) {*/ + /*if (is_code_block(parent_chain->top()) && ast_to_syntax->contains_key(node)) {*/ /*println(string("adding ") + get_ast_name(node) + " to " + get_ast_name(parent))*/ - add_before_in(get_line(ast_to_syntax->get(node), name), node, parent_chain->top()) - } - } - } - } - if (first) - run_on_tree(helper, empty_pass_second_half, syntax_ast_pair.second) + /*add_before_in(get_line(ast_to_syntax->get(node), name), node, parent_chain->top())*/ + /*}*/ + /*}*/ + /*}*/ + /*if (first)*/ + /*run_on_tree(helper, empty_pass_second_half, syntax_ast_pair.second)*/ first = false }) } diff --git a/stdlib/ctce_lower.krak b/stdlib/ctce_lower.krak new file mode 100644 index 0000000..821c498 --- /dev/null +++ b/stdlib/ctce_lower.krak @@ -0,0 +1,30 @@ +import symbol:* +import tree:* +import vector:* +import map:* +import util:* +import string:* +import mem:* +import io:* +import ast_nodes:* +import ast_transformation:* +import interpreter:* + +import pass_common:* + +fun ctce_lower(name_ast_map: *map,*ast_node>>, ast_to_syntax: *map<*ast_node, *tree>) { + name_ast_map->for_each(fun(name: string, syntax_ast_pair: pair<*tree,*ast_node>) { + var helper_before = fun(node: *ast_node, parent_chain: *stack<*ast_node>) { + match(*node) { + ast_node::compiler_intrinsic(backing) { + if (backing.intrinsic == "ctce") { + var result = evaluate_constant_expression(backing.parameters[0]) + *node = *unwrap_value(result) + } + } + } + } + run_on_tree(helper_before, empty_pass_second_half, syntax_ast_pair.second) + }) +} + diff --git a/stdlib/defer_lower.krak b/stdlib/defer_lower.krak index 372d229..838d1bc 100644 --- a/stdlib/defer_lower.krak +++ b/stdlib/defer_lower.krak @@ -19,8 +19,8 @@ fun defer_lower(name_ast_map: *map,*ast_node>>, ast_t var helper_before = fun(node: *ast_node, parent_chain: *stack<*ast_node>) { match(*node) { ast_node::defer_statement(backing) { - if (is_code_block(parent_chain->top()) || (is_statement(parent_chain->top()) && is_code_block(parent_chain->from_top(1)))) { - remove_full_statement(node, parent_chain) + if (is_code_block(parent_chain->top())) { + remove(node, parent_chain) defer_double_stack.top().push(backing.statement) } else { replace_with_in(node, backing.statement, parent_chain) @@ -47,7 +47,7 @@ fun defer_lower(name_ast_map: *map,*ast_node>>, ast_t replace_with_in(node, block, parent_chain) for (var i = 0; i < defer_double_stack.size() - loop_stack.top(); i++;) block->code_block.children.add_all(defer_double_stack.from_top(i).reverse_vector()) - block->code_block.children.add(ast_statement_ptr(node)) + block->code_block.children.add(node) } ast_node::return_statement(backing) { var block = ast_code_block_ptr() @@ -57,8 +57,8 @@ fun defer_lower(name_ast_map: *map,*ast_node>>, ast_t if (get_ast_type(enclosing_function)->return_type->is_ref) return_value = make_operator_call("&", vector(return_value)) var temp_return = ast_identifier_ptr("temp_boom_return", get_ast_type(return_value)->clone_without_ref(), block) - block->code_block.children.add(ast_statement_ptr(ast_declaration_statement_ptr(temp_return, null(), false))) - block->code_block.children.add(ast_statement_ptr(assign_or_copy_construct_statement(temp_return, return_value))) + block->code_block.children.add(ast_declaration_statement_ptr(temp_return, null(), false)) + block->code_block.children.add(assign_or_copy_construct_statement(temp_return, return_value)) // dereference so that the real ref can take it back if (get_ast_type(enclosing_function)->return_type->is_ref) temp_return = make_operator_call("*", vector(temp_return)) @@ -66,7 +66,7 @@ fun defer_lower(name_ast_map: *map,*ast_node>>, ast_t } for (var i = 0; i < defer_double_stack.size(); i++;) block->code_block.children.add_all(defer_double_stack.from_top(i).reverse_vector()) - block->code_block.children.add(ast_statement_ptr(node)) + block->code_block.children.add(node) } ast_node::code_block(backing) { node->code_block.children.add_all(defer_double_stack.pop().reverse_vector()) diff --git a/stdlib/interpreter.krak b/stdlib/interpreter.krak index 53cecc5..267a73a 100644 --- a/stdlib/interpreter.krak +++ b/stdlib/interpreter.krak @@ -119,6 +119,33 @@ fun wrap_value(val: *ast_node): value { error("Could not wrap value") return value::void_nothing() } +fun unwrap_value(val: value): *ast_node { + // string, char, bool, floating + var value_string = string() + match (get_real_value(val)) { + value::boolean(data) value_string = to_string(data) + value::character(data) value_string = to_string(data) + value::ucharacter(data) value_string = to_string(data) + value::short_int(data) value_string = to_string(data) + value::ushort_int(data) value_string = to_string(data) + value::integer(data) value_string = to_string(data) + value::uinteger(data) value_string = to_string(data) + value::long_int(data) value_string = to_string(data) + value::ulong_int(data) value_string = to_string(data) + value::floating(data) value_string = to_string(data) + value::double_precision(data) value_string = to_string(data) + value::void_nothing() error("trying to unwrap a void into an ast_value_ptr") + value::pointer(point) { + if (point.second->base == base_type::character() && point.second->indirection == 1) + value_string = string("\"") + string((point.first) cast *char) + "\"" + else + error("trying to unwrap a pointer into an ast_value_ptr") + } + value::object_like(ob) error("trying to unwrap an object_like into an ast_value_ptr") + value::function(fn) error("trying to unwrap a function into an ast_value_ptr") + } + return ast_value_ptr(value_string, get_type_from_primitive_value(get_real_value(val))) +} fun is_boolean(it: value): bool { match(it) { value::boolean(var) return true; } return false; } fun is_character(it: value): bool { match(it) { value::character(var) return true; } return false; } @@ -799,9 +826,6 @@ fun interpret_function(function: *ast_node, var_stack: *stack>, enclosing_object: value, enclosing_func: *ast_node, globals: *map<*ast_node, value>): pair { - return interpret(stmt->statement.child, var_stack, enclosing_object, enclosing_func, globals) -} fun interpret_if_statement(if_stmt: *ast_node, var_stack: *stack>, enclosing_object: value, enclosing_func: *ast_node, globals: *map<*ast_node, value>): pair { var_stack->push(map<*ast_node,value>()) var value_from_inside = make_pair(value::void_nothing(), control_flow::nor()) @@ -974,7 +998,6 @@ fun interpret(node: *ast_node, var_stack: *stack>, enclosi match (*node) { ast_node::function_call(backing) return interpret_function_call(node, var_stack, enclosing_object, enclosing_func, globals) ast_node::function(backing) return interpret_function(node, var_stack, enclosing_object, enclosing_func, globals) - ast_node::statement(backing) return interpret_statement(node, var_stack, enclosing_object, enclosing_func, globals) ast_node::if_statement(backing) return interpret_if_statement(node, var_stack, enclosing_object, enclosing_func, globals) ast_node::while_loop(backing) return interpret_while_loop(node, var_stack, enclosing_object, enclosing_func, globals) ast_node::for_loop(backing) return interpret_for_loop(node, var_stack, enclosing_object, enclosing_func, globals) diff --git a/stdlib/io.krak b/stdlib/io.krak index b9ff77e..4ac83f8 100644 --- a/stdlib/io.krak +++ b/stdlib/io.krak @@ -4,7 +4,6 @@ import mem:* ext fun printf(fmt_str: *char, ...): int ext fun fprintf(file: *void, format: *char, ...): int -ext fun snprintf(to_str: *char, num: ulong, format: *char, ...): int ext fun fflush(file: int): int ext var stderr: *void ext fun fgets(buff: *char, size: int, file: *void): *char @@ -63,16 +62,6 @@ fun print(toPrint: bool) { else print("false") } -fun print(toPrint: float) - print((toPrint) cast double) - -fun print(toPrint: double) { - var how_much = snprintf(null(), (0) cast ulong, "%f", toPrint) - var int_str = new(how_much+2) - snprintf(int_str, (how_much+1) cast ulong, "%f", toPrint) - print(int_str) - delete(int_str) -} fun print(toPrint: T): void print(string::to_string(toPrint)) diff --git a/stdlib/math.krak b/stdlib/math.krak index 3b36c31..1298da3 100644 --- a/stdlib/math.krak +++ b/stdlib/math.krak @@ -1,3 +1,4 @@ +/*#link("m")*/ #link(m) fun fibanacci(num: int): int { diff --git a/stdlib/obj_lower.krak b/stdlib/obj_lower.krak index 559032c..618b8b1 100644 --- a/stdlib/obj_lower.krak +++ b/stdlib/obj_lower.krak @@ -25,10 +25,10 @@ fun obj_lower(name_ast_map: *map,*ast_node>>, ast_to_ // Pass 1 var ensure_block_and_munge = fun(node: *ast_node, parent_chain: *stack<*ast_node>) { match(*node) { - ast_node::function(backing) if (backing.body_statement && !is_code_block(backing.body_statement)) backing.body_statement = ast_statement_ptr(ast_code_block_ptr(backing.body_statement)) + ast_node::function(backing) if (backing.body_statement && !is_code_block(backing.body_statement)) backing.body_statement = ast_code_block_ptr(backing.body_statement) ast_node::if_statement(backing) { - if (!is_code_block(backing.then_part)) backing.then_part = ast_statement_ptr(ast_code_block_ptr(backing.then_part)) - if (backing.else_part && !is_code_block(backing.else_part)) backing.else_part = ast_statement_ptr(ast_code_block_ptr(backing.else_part)) + if (!is_code_block(backing.then_part)) backing.then_part = ast_code_block_ptr(backing.then_part) + if (backing.else_part && !is_code_block(backing.else_part)) backing.else_part = ast_code_block_ptr(backing.else_part) } // no need for case because it's already been lowered ast_node::while_loop(backing) { @@ -37,33 +37,33 @@ fun obj_lower(name_ast_map: *map,*ast_node>>, ast_to_ backing.condition = ast_value_ptr(string("true"), type_ptr(base_type::boolean())) // objects do not coerce to booleans, so it should be ok for this not to be a ref var condition_ident = ast_identifier_ptr("condition_temp", get_ast_type(condition), backing.statement) - backing.statement->code_block.children.add(0, ast_statement_ptr(ast_declaration_statement_ptr(condition_ident, condition, false))) + backing.statement->code_block.children.add(0, ast_declaration_statement_ptr(condition_ident, condition, false)) var condition_if = ast_if_statement_ptr(make_operator_call("!", vector(condition_ident))) - condition_if->if_statement.then_part = ast_statement_ptr(ast_branching_statement_ptr(branching_type::break_stmt())) - backing.statement->code_block.children.add(1, ast_statement_ptr(condition_if)) + condition_if->if_statement.then_part = ast_branching_statement_ptr(branching_type::break_stmt()) + backing.statement->code_block.children.add(1, condition_if) } ast_node::for_loop(backing) { if (!is_code_block(backing.body)) backing.body = ast_code_block_ptr(backing.body) - add_before_in(backing.init, parent_chain->top(), parent_chain->from_top(1)) + add_before_in(backing.init, node, parent_chain->top()) backing.init = null() // the do_update goes in the block above the for - var update_ident = ast_identifier_ptr("do_update", type_ptr(base_type::boolean()), parent_chain->from_top(1)) - add_before_in(ast_statement_ptr(ast_declaration_statement_ptr(update_ident, ast_value_ptr(string("false"), type_ptr(base_type::boolean())), false)), - parent_chain->top(), parent_chain->from_top(1)) + var update_ident = ast_identifier_ptr("do_update", type_ptr(base_type::boolean()), parent_chain->top()) + add_before_in(ast_declaration_statement_ptr(update_ident, ast_value_ptr(string("false"), type_ptr(base_type::boolean())), false), + node, parent_chain->top()) var update_if = ast_if_statement_ptr(update_ident) - update_if->if_statement.then_part = ast_statement_ptr(ast_code_block_ptr(backing.update)) + update_if->if_statement.then_part = ast_code_block_ptr(backing.update) backing.update = null() - backing.body->code_block.children.add(0, ast_statement_ptr(update_if)) - backing.body->code_block.children.add(1, ast_statement_ptr(ast_assignment_statement_ptr(update_ident, ast_value_ptr(string("true"), type_ptr(base_type::boolean()))))) + backing.body->code_block.children.add(0, update_if) + backing.body->code_block.children.add(1, ast_assignment_statement_ptr(update_ident, ast_value_ptr(string("true"), type_ptr(base_type::boolean())))) var condition = backing.condition backing.condition = ast_value_ptr(string("true"), type_ptr(base_type::boolean())) // objects do not coerce to booleans, so it should be ok for this not to be a ref var condition_ident = ast_identifier_ptr("condition_temp", get_ast_type(condition), backing.body) - backing.body->code_block.children.add(2, ast_statement_ptr(ast_declaration_statement_ptr(condition_ident, condition, false))) + backing.body->code_block.children.add(2, ast_declaration_statement_ptr(condition_ident, condition, false)) var condition_if = ast_if_statement_ptr(make_operator_call("!", vector(condition_ident))) - condition_if->if_statement.then_part = ast_statement_ptr(ast_branching_statement_ptr(branching_type::break_stmt())) - backing.body->code_block.children.add(3, ast_statement_ptr(condition_if)) + condition_if->if_statement.then_part = ast_branching_statement_ptr(branching_type::break_stmt()) + backing.body->code_block.children.add(3, condition_if) } } } @@ -87,17 +87,17 @@ fun obj_lower(name_ast_map: *map,*ast_node>>, ast_to_ if (func_name == "||" || func_name == "&&") { var enclosing_block_idx = parent_chain->index_from_top_satisfying(fun(i: *ast_node): bool return is_code_block(i);) var short_circuit_result = ast_identifier_ptr("short_circut_result", type_ptr(base_type::boolean()), parent_chain->from_top(enclosing_block_idx)) - var short_circuit_declaration = ast_statement_ptr(ast_declaration_statement_ptr(short_circuit_result, backing.parameters[0], false)) + var short_circuit_declaration = ast_declaration_statement_ptr(short_circuit_result, backing.parameters[0], false) var condition = short_circuit_result if (func_name == "||") condition = make_operator_call("!", vector(condition)) var short_circuit_if = ast_if_statement_ptr(condition) // how to get proper parent scoping working for this part - short_circuit_if->if_statement.then_part = ast_code_block_ptr(ast_statement_ptr(ast_assignment_statement_ptr(short_circuit_result, backing.parameters[1]))) + short_circuit_if->if_statement.then_part = ast_code_block_ptr(ast_assignment_statement_ptr(short_circuit_result, backing.parameters[1])) add_before_in(short_circuit_declaration, parent_chain->from_top(enclosing_block_idx-1), parent_chain->from_top(enclosing_block_idx)) - add_before_in(ast_statement_ptr(short_circuit_if), parent_chain->from_top(enclosing_block_idx-1), parent_chain->from_top(enclosing_block_idx)) + add_before_in(short_circuit_if, parent_chain->from_top(enclosing_block_idx-1), parent_chain->from_top(enclosing_block_idx)) replace_with_in(node, short_circuit_result, parent_chain) - var shorter_tree =stack_from_vector( parent_chain->data.slice(0, parent_chain->size()-enclosing_block_idx)) + var shorter_tree = stack_from_vector( parent_chain->data.slice(0, parent_chain->size()-enclosing_block_idx)) run_on_tree_helper(short_circut_op, empty_pass_second_half, short_circuit_declaration, &shorter_tree, false) run_on_tree_helper(short_circut_op, empty_pass_second_half, short_circuit_if, &shorter_tree, false) return false @@ -124,6 +124,12 @@ fun obj_lower(name_ast_map: *map,*ast_node>>, ast_to_ return } var enclosing_block_idx = parent_chain->index_from_top_satisfying(fun(i: *ast_node): bool return is_code_block(i);) + var replace_before: *ast_node + if (enclosing_block_idx > 0) + replace_before = parent_chain->from_top(enclosing_block_idx-1) + else + replace_before = node + var replace_in = parent_chain->from_top(enclosing_block_idx) var func_type = get_ast_type(backing.func) for (var i = 0; i < backing.parameters.size; i++;) { var param = backing.parameters[i] @@ -136,20 +142,20 @@ fun obj_lower(name_ast_map: *map,*ast_node>>, ast_to_ var param_type = get_ast_type(param) if (!in_function_param_type->is_ref && param_type->indirection == 0 && (param_type->is_object() && has_method(param_type->type_def, "copy_construct", vector(param_type->clone_with_indirection(1))))) { var temp_ident = ast_identifier_ptr("temporary_param_boom", param_type->clone_without_ref(), null()) - var declaration = ast_statement_ptr(ast_declaration_statement_ptr(temp_ident, null(), false)) - var copy_in = ast_statement_ptr(make_method_call(temp_ident, "copy_construct", vector(make_operator_call("&", vector(param))))) - add_before_in(declaration, parent_chain->from_top(enclosing_block_idx-1), parent_chain->from_top(enclosing_block_idx)) - add_before_in(copy_in, parent_chain->from_top(enclosing_block_idx-1), parent_chain->from_top(enclosing_block_idx)) + var declaration = ast_declaration_statement_ptr(temp_ident, null(), false) + var copy_in = make_method_call(temp_ident, "copy_construct", vector(make_operator_call("&", vector(param)))) + add_before_in(declaration, replace_before, replace_in) + add_before_in(copy_in, replace_before, replace_in) backing.parameters[i] = temp_ident } } var func_return_type = func_type->return_type if (!func_return_type->is_ref && func_return_type->indirection == 0 && (func_return_type->is_object() && has_method(func_return_type->type_def, "destruct", vector<*type>()))) { var temp_return = ast_identifier_ptr("temporary_return_boomchaka", func_return_type, null()) - var declaration = ast_statement_ptr(ast_declaration_statement_ptr(temp_return, node, false)) - add_before_in(declaration, parent_chain->from_top(enclosing_block_idx-1), parent_chain->from_top(enclosing_block_idx)) - add_before_in(ast_statement_ptr(ast_defer_statement_ptr(ast_statement_ptr(make_method_call(temp_return, "destruct", vector<*ast_node>())))), - parent_chain->from_top(enclosing_block_idx-1), parent_chain->from_top(enclosing_block_idx)) + var declaration = ast_declaration_statement_ptr(temp_return, node, false) + add_before_in(declaration, replace_before, replace_in) + add_before_in(ast_defer_statement_ptr(make_method_call(temp_return, "destruct", vector<*ast_node>())), + replace_before, replace_in) replace_with_in(node, temp_return, parent_chain) } } @@ -159,8 +165,8 @@ fun obj_lower(name_ast_map: *map,*ast_node>>, ast_to_ var param_type = get_ast_type(param) if (!param_type->is_ref && param_type->indirection == 0 && (param_type->is_object() && has_method(param_type->type_def, "destruct", vector<*type>()))) { // the first pass ensures a code_block child - backing.body_statement->statement.child->code_block.children.add(order++, - ast_statement_ptr(ast_defer_statement_ptr(ast_statement_ptr(make_method_call(param, "destruct", vector<*ast_node>()))))) + backing.body_statement->code_block.children.add(order++, + ast_defer_statement_ptr(make_method_call(param, "destruct", vector<*ast_node>()))) } }) } @@ -171,18 +177,18 @@ fun obj_lower(name_ast_map: *map,*ast_node>>, ast_to_ if (!ident_type->is_ref && ident_type->indirection == 0 && ident_type->is_object()) { if (backing.expression && has_method(ident_type->type_def, "copy_construct", vector(get_ast_type(backing.expression)->clone_with_increased_indirection()))) { var temp_cpy_ctst = ast_identifier_ptr("temp_declaration_copy_construct", get_ast_type(backing.expression)->clone_without_ref(), null()) - var declaration = ast_statement_ptr(ast_declaration_statement_ptr(temp_cpy_ctst, backing.expression, false)) - add_after_in(ast_statement_ptr(make_method_call(backing.identifier, "copy_construct", vector(make_operator_call("&", vector(temp_cpy_ctst))))), - parent_chain->top(), parent_chain->from_top(1)) + var declaration = ast_declaration_statement_ptr(temp_cpy_ctst, backing.expression, false) + add_after_in(make_method_call(backing.identifier, "copy_construct", vector(make_operator_call("&", vector(temp_cpy_ctst)))), + node, parent_chain->top()) // do second so the order's right add_after_in(declaration, - parent_chain->top(), parent_chain->from_top(1)) + node, parent_chain->top()) backing.expression = null() } if (has_method(ident_type->type_def, "destruct", vector<*type>())) { // have to go up one because our parent is a statement - add_after_in(ast_statement_ptr(ast_defer_statement_ptr(ast_statement_ptr(make_method_call(backing.identifier, "destruct", vector<*ast_node>())))), - parent_chain->top(), parent_chain->from_top(1)) + add_after_in(ast_defer_statement_ptr(make_method_call(backing.identifier, "destruct", vector<*ast_node>())), + node, parent_chain->top()) } } } diff --git a/stdlib/pass_common.krak b/stdlib/pass_common.krak index 34a7982..2fa7393 100644 --- a/stdlib/pass_common.krak +++ b/stdlib/pass_common.krak @@ -262,15 +262,6 @@ fun get_children_pointer(node: *ast_node): *vector<*ast_node> { } return bc } - -fun remove_full_statement(node: *ast_node, parent_chain: *stack<*ast_node>): *ast_node { - if (is_statement(node)) - return remove(node, parent_chain) - if (is_statement(parent_chain->top())) - return remove(parent_chain->top(), parent_chain->from_top(1)) - error(string("cannot remove full statement in ") + get_ast_name(parent_chain->top())) -} - fun remove(orig: *ast_node, in: *stack<*ast_node>): *ast_node return remove(orig, in->top()) fun remove(orig: *ast_node, in: *ast_node): *ast_node { @@ -289,7 +280,6 @@ fun replace_with_in(orig: *ast_node, new: *ast_node, in: *stack<*ast_node>) replace_with_in(orig, new, in->top()) fun replace_with_in(orig: *ast_node, new: *ast_node, in: *ast_node) { match (*in) { - ast_node::statement(backing) { backing.child = new; return; } ast_node::return_statement(backing) { backing.return_value = new; return; } ast_node::assignment_statement(backing) { if (backing.to == orig) { @@ -431,7 +421,6 @@ fun run_on_tree_helper(func_before: fun(*ast_node,*stack<*ast_node>):bool, func_ ast_node::function(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain, false);) ast_node::template(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain, true);) ast_node::code_block(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain, false);) - ast_node::statement(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain, false);) ast_node::if_statement(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain, false);) ast_node::match_statement(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain, false);) ast_node::case_statement(backing) get_ast_children(node).for_each(fun(n: *ast_node) run_on_tree_helper(func_before, func_after, n, parent_chain, false);) diff --git a/stdlib/string.krak b/stdlib/string.krak index 0bb827c..2a160ef 100644 --- a/stdlib/string.krak +++ b/stdlib/string.krak @@ -4,9 +4,22 @@ import mem import serialize import io -/*fun to_string(in: bool): string*/ - /*if (in) return string("true")*/ - /*else return string("false")*/ +ext fun snprintf(to_str: *char, num: ulong, format: *char, ...): int +fun to_string(in: float): string + return to_string((in) cast double) +fun to_string(in: double): string { + var how_much = snprintf(mem::null(), (0) cast ulong, "%f", in) + var int_str = mem::new(how_much+2) + snprintf(int_str, (how_much+1) cast ulong, "%f", in) + var to_ret = string(int_str) + mem::delete(int_str) + return to_ret +} +fun to_string(in: bool): string + if (in) return string("true") + else return string("false") +fun to_string(in: char): string + return string(in) fun to_string(in: uchar): string return to_string_num(in) fun to_string(in: short): string @@ -98,10 +111,6 @@ obj string (Object, Serializable) { data.construct(len); data.set_size(len); mem::memmove((data.getBackingMemory()) cast *void, (str) cast *void, (len) cast ulong) - /*while(*str) {*/ - /*data.addEnd(*str);*/ - /*str += 1;*/ - /*}*/ // no null terminator return this; } diff --git a/stdlib/thread.krak b/stdlib/thread.krak index 66d22d3..1120378 100644 --- a/stdlib/thread.krak +++ b/stdlib/thread.krak @@ -3,6 +3,7 @@ import os:* import mem:* import util:* +/*#link("pthread")*/ #link(pthread) ext fun pthread_attr_init(attr_ptr: *void): int ext fun pthread_create(thread: *ulong, attr_ptr: *void, func: *void, param: *void): int diff --git a/stdlib/vector.krak b/stdlib/vector.krak index 8d54863..a35a5ad 100644 --- a/stdlib/vector.krak +++ b/stdlib/vector.krak @@ -226,6 +226,10 @@ obj vector (Object, Serializable) { } fun add(index: int, dataIn: ref T) { + if (size == 0) { + add(dataIn) + return + } add(last()) for (var i = size-2; i > index; i--;) { data[i] = data[i-1]