Basic CTCE working! In between commit because #link(a) syntax changed to #link(a)
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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 ;
|
||||
|
||||
@@ -43,19 +43,19 @@ fun adt_lower(name_ast_map: *map<string, pair<*tree<symbol>,*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<ast_node>(), false)))
|
||||
block->code_block.children.add(ast_declaration_statement_ptr(to_ret, null<ast_node>(), 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<string, pair<*tree<symbol>,*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<string, pair<*tree<symbol>,*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<string, pair<*tree<symbol>,*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<string, pair<*tree<symbol>,*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<string, pair<*tree<symbol>,*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<ast_node>(), 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<ast_node>(), 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<string, pair<*tree<symbol>,*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
|
||||
|
||||
@@ -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<ast_node>()
|
||||
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<string, vector<*ast_node>>
|
||||
var child: *ast_node
|
||||
fun construct(child_in: *ast_node): *statement {
|
||||
child = null<ast_node>()
|
||||
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<ast_node>()
|
||||
@@ -992,7 +955,7 @@ obj function_call (Object) {
|
||||
return func == func && parameters == other.parameters
|
||||
}
|
||||
}
|
||||
fun ast_compiler_intrinsic_ptr(intrinsic: string, parameters: vector<string>, 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<ast_node>()
|
||||
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<string>
|
||||
var parameters: vector<*ast_node>
|
||||
var type_parameters: vector<*type>
|
||||
var return_type: *type
|
||||
fun construct(intrinsic_in: string, parameters_in: vector<string>, 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<string,vector<*ast_node>> {
|
||||
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
|
||||
|
||||
@@ -607,9 +607,7 @@ obj ast_transformation (Object) {
|
||||
return new_passthrough
|
||||
}
|
||||
fun transform_statement(node: *tree<symbol>, scope: *ast_node, template_replacements: map<string, *type>): *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<symbol>, scope: *ast_node, template_replacements: map<string, *type>): *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<symbol>, scope: *ast_node, template_replacements: map<string, *type>): *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<string>()
|
||||
var type_parameters = vector<*type>()
|
||||
if (get_nodes("intrinsic_parameter", node).size)
|
||||
parameters = get_nodes("intrinsic_parameter", node).map(fun(child: *tree<symbol>): string return concat_symbol_tree(child);)
|
||||
if (get_nodes("type", node).size)
|
||||
type_parameters = get_nodes("type", node).map(fun(child: *tree<symbol>): *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<symbol>): *ast_node return transform(get_node("boolean_expression", child), scope, template_replacements);)
|
||||
var type_parameters = get_nodes("type", node).map(fun(child: *tree<symbol>): *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<symbol>, scope: *ast_node, template_replacements: map<string, *type>): *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<symbol>, scope: *ast_node, template_replacements: map<string, *type>): *ast_node return transform_expression(node, scope, search_type::none(), template_replacements)
|
||||
fun transform_expression(node: *tree<symbol>, scope: *ast_node, template_replacements: map<string, *type>): *ast_node
|
||||
return transform_expression(node, scope, search_type::none(), template_replacements)
|
||||
fun transform_expression(node: *tree<symbol>, scope: *ast_node, searching_for: search_type, template_replacements: map<string, *type>): *ast_node {
|
||||
var func_name = string()
|
||||
var parameters = vector<*ast_node>()
|
||||
|
||||
@@ -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<ast_node>(), null<ast_node>(), 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)
|
||||
|
||||
@@ -20,18 +20,16 @@ fun get_line(node: *tree<symbol>, name: string): *ast_node {
|
||||
fun c_line_control(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_syntax: *map<*ast_node, *tree<symbol>>) {
|
||||
var first = true
|
||||
name_ast_map->for_each(fun(name: string, syntax_ast_pair: pair<*tree<symbol>,*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
|
||||
})
|
||||
}
|
||||
|
||||
30
stdlib/ctce_lower.krak
Normal file
30
stdlib/ctce_lower.krak
Normal file
@@ -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<string, pair<*tree<symbol>,*ast_node>>, ast_to_syntax: *map<*ast_node, *tree<symbol>>) {
|
||||
name_ast_map->for_each(fun(name: string, syntax_ast_pair: pair<*tree<symbol>,*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)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -19,8 +19,8 @@ fun defer_lower(name_ast_map: *map<string, pair<*tree<symbol>,*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<string, pair<*tree<symbol>,*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<string, pair<*tree<symbol>,*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<ast_node>(), 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<ast_node>(), 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<string, pair<*tree<symbol>,*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())
|
||||
|
||||
@@ -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<map<*ast_node, val
|
||||
})
|
||||
return make_pair(value::function(make_pair(function, possible_closure_map)), control_flow::nor())
|
||||
}
|
||||
fun interpret_statement(stmt: *ast_node, var_stack: *stack<map<*ast_node, value>>, enclosing_object: value, enclosing_func: *ast_node, globals: *map<*ast_node, value>): pair<value, control_flow> {
|
||||
return interpret(stmt->statement.child, var_stack, enclosing_object, enclosing_func, globals)
|
||||
}
|
||||
fun interpret_if_statement(if_stmt: *ast_node, var_stack: *stack<map<*ast_node, value>>, enclosing_object: value, enclosing_func: *ast_node, globals: *map<*ast_node, value>): pair<value, control_flow> {
|
||||
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<map<*ast_node, value>>, 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)
|
||||
|
||||
@@ -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<char>(), (0) cast ulong, "%f", toPrint)
|
||||
var int_str = new<char>(how_much+2)
|
||||
snprintf(int_str, (how_much+1) cast ulong, "%f", toPrint)
|
||||
print(int_str)
|
||||
delete(int_str)
|
||||
}
|
||||
fun print<T>(toPrint: T): void
|
||||
print(string::to_string(toPrint))
|
||||
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
/*#link("m")*/
|
||||
#link(m)
|
||||
|
||||
fun fibanacci(num: int): int {
|
||||
|
||||
@@ -25,10 +25,10 @@ fun obj_lower(name_ast_map: *map<string, pair<*tree<symbol>,*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<string, pair<*tree<symbol>,*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<ast_node>()
|
||||
// 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<ast_node>()
|
||||
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<string, pair<*tree<symbol>,*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<string, pair<*tree<symbol>,*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<string, pair<*tree<symbol>,*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<ast_node>())
|
||||
var declaration = ast_statement_ptr(ast_declaration_statement_ptr(temp_ident, null<ast_node>(), 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<ast_node>(), 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<ast_node>())
|
||||
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<string, pair<*tree<symbol>,*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<string, pair<*tree<symbol>,*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<ast_node>())
|
||||
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<ast_node>()
|
||||
}
|
||||
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())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);)
|
||||
|
||||
@@ -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<char>(), (0) cast ulong, "%f", in)
|
||||
var int_str = mem::new<char>(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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -226,6 +226,10 @@ obj vector<T> (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]
|
||||
|
||||
Reference in New Issue
Block a user