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 adt_lower:*
|
||||||
import obj_lower:*
|
import obj_lower:*
|
||||||
import defer_lower:*
|
import defer_lower:*
|
||||||
|
import ctce_lower:*
|
||||||
import c_line_control:*
|
import c_line_control:*
|
||||||
import c_generator:*
|
import c_generator:*
|
||||||
import compiler_version
|
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)
|
obj_lower(&importer.name_ast_map, &importer.ast_pass.ast_to_syntax)
|
||||||
printlnerr("Lowering Defer")
|
printlnerr("Lowering Defer")
|
||||||
defer_lower(&importer.name_ast_map, &importer.ast_pass.ast_to_syntax)
|
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) {
|
if (interpret_instead) {
|
||||||
printlnerr("Interpreting!")
|
printlnerr("Interpreting!")
|
||||||
call_main(importer.name_ast_map)
|
call_main(importer.name_ast_map)
|
||||||
|
|||||||
@@ -116,9 +116,7 @@ continue_statement = "continue" ;
|
|||||||
defer_statement = "defer" WS statement ;
|
defer_statement = "defer" WS statement ;
|
||||||
function_call = unarad WS "\(" WS opt_parameter_list WS "\)" ;
|
function_call = unarad WS "\(" WS opt_parameter_list WS "\)" ;
|
||||||
|
|
||||||
compiler_intrinsic = "#" identifier WS "\(" WS intrinsic_parameter_list WS "\)" | "#" identifier WS "<" WS type_list WS ">" ;
|
compiler_intrinsic = "#" identifier WS "\(" WS opt_parameter_list WS "\)" | "#" identifier WS "<" WS type_list WS ">" ;
|
||||||
intrinsic_parameter_list = intrinsic_parameter_list WS "," WS intrinsic_parameter | intrinsic_parameter ;
|
|
||||||
intrinsic_parameter = identifier ;
|
|
||||||
|
|
||||||
boolean_expression = boolean_expression WS "\|\|" WS and_boolean_expression | and_boolean_expression ;
|
boolean_expression = boolean_expression WS "\|\|" WS and_boolean_expression | and_boolean_expression ;
|
||||||
and_boolean_expression = and_boolean_expression WS "&&" WS bitwise_or | bitwise_or ;
|
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) {
|
node->adt_def.option_funcs.for_each(fun(func: *ast_node) {
|
||||||
var adt_type = replacement->type_def.self_type
|
var adt_type = replacement->type_def.self_type
|
||||||
var block = ast_code_block_ptr()
|
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)
|
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()))
|
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 opt = type_def_option_map[node][idx]
|
||||||
var lvalue = make_operator_call(".", vector(make_operator_call(".", vector(to_ret, option_union_ident)), opt))
|
var lvalue = make_operator_call(".", vector(make_operator_call(".", vector(to_ret, option_union_ident)), opt))
|
||||||
if (func->function.parameters.size) {
|
if (func->function.parameters.size) {
|
||||||
// do copy_construct if it should
|
// 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_before_in(func, node, parent_chain)
|
||||||
add_to_scope(func->function.name, func, enclosing_scope)
|
add_to_scope(func->function.name, func, enclosing_scope)
|
||||||
add_to_scope("~enclosing_scope", enclosing_scope, func)
|
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) {
|
node->adt_def.regular_funcs.for_each(fun(func: *ast_node) {
|
||||||
var block = ast_code_block_ptr()
|
var block = ast_code_block_ptr()
|
||||||
func->function.body_statement = ast_statement_ptr(block)
|
func->function.body_statement = block
|
||||||
if (func->function.name == "operator==") {
|
if (func->function.name == "operator==") {
|
||||||
var other = func->function.parameters[0]
|
var other = func->function.parameters[0]
|
||||||
var if_stmt = ast_if_statement_ptr(make_operator_call("!=", vector(make_operator_call("->", vector(replacement_this, flag)), make_operator_call(".", vector(other, flag)))))
|
var if_stmt = ast_if_statement_ptr(make_operator_call("!=", vector(make_operator_call("->", vector(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)
|
block->code_block.children.add(if_stmt)
|
||||||
|
|
||||||
for (var i = 0; i < type_def_option_map[node].size; i++;) {
|
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 option = type_def_option_map[node][i]
|
||||||
var our_option = make_operator_call(".", vector(make_operator_call("->", vector(replacement_this, option_union_ident)), option))
|
var our_option = make_operator_call(".", vector(make_operator_call("->", vector(replacement_this, option_union_ident)), option))
|
||||||
var their_option = make_operator_call(".", vector(make_operator_call(".", vector(other, 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(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!=") {
|
} else if (func->function.name == "operator!=") {
|
||||||
var other = func->function.parameters[0]
|
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") {
|
} else if (func->function.name == "construct") {
|
||||||
var value = ast_value_ptr(string("-1"), type_ptr(base_type::integer()))
|
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_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_return_statement_ptr(replacement_this))
|
||||||
} else if (func->function.name == "copy_construct") {
|
} else if (func->function.name == "copy_construct") {
|
||||||
var other = func->function.parameters[0]
|
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++;) {
|
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())
|
if (get_ast_type(type_def_option_map[node][i])->is_empty_adt_option())
|
||||||
continue
|
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 option = type_def_option_map[node][i]
|
||||||
var our_option = make_operator_call(".", vector(make_operator_call("->", vector(replacement_this, option_union_ident)), option))
|
var our_option = make_operator_call(".", vector(make_operator_call("->", vector(replacement_this, option_union_ident)), option))
|
||||||
var their_option = make_operator_call(".", vector(make_operator_call("->", vector(other, 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)
|
block->code_block.children.add(if_stmt_inner)
|
||||||
}
|
}
|
||||||
} else if (func->function.name == "operator=") {
|
} else if (func->function.name == "operator=") {
|
||||||
var other = func->function.parameters[0]
|
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(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, "copy_construct", vector(make_operator_call("&", vector(other)))))
|
||||||
} else if (func->function.name == "destruct") {
|
} else if (func->function.name == "destruct") {
|
||||||
for (var i = 0; i < type_def_option_map[node].size; i++;) {
|
for (var i = 0; i < type_def_option_map[node].size; i++;) {
|
||||||
var option = type_def_option_map[node][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>())) {
|
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 if_stmt_inner = ast_if_statement_ptr(make_operator_call("==", vector(make_operator_call("->", vector(replacement_this, flag)), ast_value_ptr(to_string(i), type_ptr(base_type::integer())))))
|
||||||
var our_option = make_operator_call(".", vector(make_operator_call("->", vector(replacement_this, option_union_ident)), option))
|
var 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)
|
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 block = ast_code_block_ptr()
|
||||||
var value = backing.value
|
var value = backing.value
|
||||||
var holder = ast_identifier_ptr(string("holder"), get_ast_type(value)->clone_with_increased_indirection(), block)
|
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_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_assignment_statement_ptr(holder, make_operator_call("&", vector(value))))
|
||||||
backing.cases.for_each(fun(case_stmt: *ast_node) {
|
backing.cases.for_each(fun(case_stmt: *ast_node) {
|
||||||
var option = case_stmt->case_statement.option
|
var option = case_stmt->case_statement.option
|
||||||
var flag = get_from_scope(get_ast_type(value)->type_def, "flag")
|
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))
|
var get_option = make_operator_call(".", vector(make_operator_call("->", vector(holder, data)), option))
|
||||||
get_option = make_operator_call("&", vector(get_option))
|
get_option = make_operator_call("&", vector(get_option))
|
||||||
unpack_ident->identifier.type = unpack_ident->identifier.type->clone_with_ref()
|
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)
|
inner_block->code_block.children.add(case_stmt->case_statement.statement)
|
||||||
if_stmt->if_statement.then_part = inner_block
|
if_stmt->if_statement.then_part = inner_block
|
||||||
|
|||||||
@@ -21,7 +21,6 @@ adt ast_node {
|
|||||||
function: function,
|
function: function,
|
||||||
template: template,
|
template: template,
|
||||||
code_block: code_block,
|
code_block: code_block,
|
||||||
statement: statement,
|
|
||||||
if_statement: if_statement,
|
if_statement: if_statement,
|
||||||
match_statement: match_statement,
|
match_statement: match_statement,
|
||||||
case_statement: case_statement,
|
case_statement: case_statement,
|
||||||
@@ -458,42 +457,6 @@ obj code_block (Object) {
|
|||||||
return children == other.children && scope == other.scope
|
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 {
|
fun ast_if_statement_ptr(condition: *ast_node): *ast_node {
|
||||||
var to_ret.construct(condition): if_statement
|
var to_ret.construct(condition): if_statement
|
||||||
var ptr = new<ast_node>()
|
var ptr = new<ast_node>()
|
||||||
@@ -992,7 +955,7 @@ obj function_call (Object) {
|
|||||||
return func == func && parameters == other.parameters
|
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 to_ret.construct(intrinsic, parameters, type_parameters, return_type): compiler_intrinsic
|
||||||
var ptr = new<ast_node>()
|
var ptr = new<ast_node>()
|
||||||
ptr->copy_construct(&ast_node::compiler_intrinsic(to_ret))
|
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) {
|
obj compiler_intrinsic (Object) {
|
||||||
var intrinsic: string
|
var intrinsic: string
|
||||||
var parameters: vector<string>
|
var parameters: vector<*ast_node>
|
||||||
var type_parameters: vector<*type>
|
var type_parameters: vector<*type>
|
||||||
var return_type: *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)
|
intrinsic.copy_construct(&intrinsic_in)
|
||||||
parameters.copy_construct(¶meters_in)
|
parameters.copy_construct(¶meters_in)
|
||||||
type_parameters.copy_construct(&type_parameters_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::function(backing) return backing.parameters + backing.body_statement
|
||||||
ast_node::template(backing) return backing.instantiated
|
ast_node::template(backing) return backing.instantiated
|
||||||
ast_node::code_block(backing) return backing.children
|
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::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::match_statement(backing) return vector(backing.value) + backing.cases
|
||||||
ast_node::case_statement(backing) return vector(backing.option, backing.unpack_ident, backing.statement)
|
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::template(backing) return string("template: ") + backing.name
|
||||||
ast_node::code_block(backing) return string("code_block")
|
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::if_statement(backing) return string("if_statement")
|
||||||
ast_node::match_statement(backing) return string("match_statement")
|
ast_node::match_statement(backing) return string("match_statement")
|
||||||
ast_node::case_statement(backing) return string("case_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::function() return &node->function.scope
|
||||||
ast_node::template() return &node->template.scope
|
ast_node::template() return &node->template.scope
|
||||||
ast_node::code_block() return &node->code_block.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::if_statement() return &node->if_statement.scope
|
||||||
ast_node::match_statement() return &node->match_statement.scope
|
ast_node::match_statement() return &node->match_statement.scope
|
||||||
ast_node::case_statement() return &node->case_statement.scope
|
ast_node::case_statement() return &node->case_statement.scope
|
||||||
|
|||||||
@@ -607,9 +607,7 @@ obj ast_transformation (Object) {
|
|||||||
return new_passthrough
|
return new_passthrough
|
||||||
}
|
}
|
||||||
fun transform_statement(node: *tree<symbol>, scope: *ast_node, template_replacements: map<string, *type>): *ast_node {
|
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));
|
return transform(node->children[0], scope, template_replacements);
|
||||||
ast_to_syntax.set(to_ret, node)
|
|
||||||
return to_ret
|
|
||||||
}
|
}
|
||||||
fun transform_declaration_statement(node: *tree<symbol>, scope: *ast_node, template_replacements: map<string, *type>): *ast_node {
|
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
|
// 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)))
|
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_adt = the_adts[0]
|
||||||
var the_option_name = concat_symbol_tree(get_node("identifier", get_node("scoped_identifier", node)))
|
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;)
|
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
|
to_ret->case_statement.option = the_option
|
||||||
var possible_ident = get_node("identifier", node)
|
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)
|
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
|
// 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()) {
|
if (get_ast_type(func)->is_object()) {
|
||||||
/*println("Making an operator() method call!")*/
|
|
||||||
return make_method_call(func, "operator", parameters)
|
return make_method_call(func, "operator", parameters)
|
||||||
}
|
}
|
||||||
var f = ast_function_call_ptr(func, 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
|
return f
|
||||||
}
|
}
|
||||||
fun transform_compiler_intrinsic(node: *tree<symbol>, scope: *ast_node, template_replacements: map<string, *type>): *ast_node {
|
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 = get_nodes("parameter", node).map(fun(child: *tree<symbol>): *ast_node return transform(get_node("boolean_expression", child), scope, template_replacements);)
|
||||||
var parameters = vector<string>()
|
var type_parameters = get_nodes("type", node).map(fun(child: *tree<symbol>): *type return transform_type(child, scope, template_replacements);)
|
||||||
var type_parameters = vector<*type>()
|
var intrinsic_name = concat_symbol_tree(get_node("identifier", node))
|
||||||
if (get_nodes("intrinsic_parameter", node).size)
|
var intrinsic_return_type: *type
|
||||||
parameters = get_nodes("intrinsic_parameter", node).map(fun(child: *tree<symbol>): string return concat_symbol_tree(child);)
|
if (intrinsic_name == "ctce")
|
||||||
if (get_nodes("type", node).size)
|
intrinsic_return_type = get_ast_type(parameters[0])
|
||||||
type_parameters = get_nodes("type", node).map(fun(child: *tree<symbol>): *type return transform_type(child, scope, template_replacements);)
|
else
|
||||||
return ast_compiler_intrinsic_ptr(concat_symbol_tree(get_node("identifier", node)), parameters, type_parameters, type_ptr(base_type::ulong_int()))
|
intrinsic_return_type = 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()))*/
|
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 {
|
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)
|
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.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)
|
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]
|
while (!is_translation_unit(scope)) scope = get_ast_scope(scope)->get(string("~enclosing_scope"))[0]
|
||||||
scope->translation_unit.lambdas.add(function_node)
|
scope->translation_unit.lambdas.add(function_node)
|
||||||
return function_node
|
return function_node
|
||||||
@@ -816,9 +809,6 @@ obj ast_transformation (Object) {
|
|||||||
if (!in_scope_chain(backing.enclosing_scope, func))
|
if (!in_scope_chain(backing.enclosing_scope, func))
|
||||||
return set(node);
|
return set(node);
|
||||||
}
|
}
|
||||||
ast_node::statement(backing) {
|
|
||||||
return find_closed_variables(func, backing.child)
|
|
||||||
}
|
|
||||||
ast_node::code_block(backing) {
|
ast_node::code_block(backing) {
|
||||||
var to_ret = set<*ast_node>()
|
var to_ret = set<*ast_node>()
|
||||||
backing.children.for_each(fun(n: *ast_node) to_ret += find_closed_variables(func, n);)
|
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 in_scope_chain(get_ast_scope(node)->get(string("~enclosing_scope"))[0], high_scope)
|
||||||
return false
|
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 {
|
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 func_name = string()
|
||||||
var parameters = vector<*ast_node>()
|
var parameters = vector<*ast_node>()
|
||||||
|
|||||||
@@ -229,8 +229,8 @@ obj c_generator (Object) {
|
|||||||
if (!backing.is_extern)
|
if (!backing.is_extern)
|
||||||
function_definitions += prototype_and_header.second
|
function_definitions += prototype_and_header.second
|
||||||
if (backing.body_statement) {
|
if (backing.body_statement) {
|
||||||
function_definitions += string(" {\n") + generate_statement(backing.body_statement, enclosing_object, child).one_string()
|
function_definitions += string(" {\n") + generate(backing.body_statement, enclosing_object, child, false).one_string()
|
||||||
function_definitions += "}\n"
|
function_definitions += ";\n}\n"
|
||||||
} else if (!backing.is_extern) {
|
} else if (!backing.is_extern) {
|
||||||
error("Empty function statement and not extern - no ADTs anymore!")
|
error("Empty function statement and not extern - no ADTs anymore!")
|
||||||
}
|
}
|
||||||
@@ -256,8 +256,8 @@ obj c_generator (Object) {
|
|||||||
match (*child) {
|
match (*child) {
|
||||||
// should really check the genrator
|
// should really check the genrator
|
||||||
ast_node::if_comp(backing) {
|
ast_node::if_comp(backing) {
|
||||||
if (is_simple_passthrough(backing.statement->statement.child))
|
if (is_simple_passthrough(backing.statement))
|
||||||
top_level_c_passthrough += generate_simple_passthrough(backing.statement->statement.child, true)
|
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::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
|
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
|
||||||
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 {
|
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 identifier = node->declaration_statement.identifier
|
||||||
var ident_type = identifier->identifier.type
|
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 {
|
fun generate_code_block(node: *ast_node, enclosing_object: *ast_node, enclosing_func: *ast_node): code_triple {
|
||||||
var to_ret = code_triple("{\n")
|
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 + "}"
|
return to_ret + "}"
|
||||||
}
|
}
|
||||||
// this generates the function as a value, not the actual function
|
// 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")
|
error("wrong parameters to sizeof compiler intrinsic")
|
||||||
return code_triple("sizeof(") + type_to_c(node->compiler_intrinsic.type_parameters[0]) + ")"
|
return code_triple("sizeof(") + type_to_c(node->compiler_intrinsic.type_parameters[0]) + ")"
|
||||||
} else if (node->compiler_intrinsic.intrinsic == "link") {
|
} else if (node->compiler_intrinsic.intrinsic == "link") {
|
||||||
node->compiler_intrinsic.parameters.for_each(fun(str: string) {
|
node->compiler_intrinsic.parameters.for_each(fun(value: *ast_node) {
|
||||||
linker_string += string("-l") + str + " "
|
linker_string += string("-l") + value->value.string_value.slice(1,-2) + " "
|
||||||
})
|
})
|
||||||
return code_triple()
|
return code_triple()
|
||||||
}
|
}
|
||||||
@@ -697,7 +696,6 @@ obj c_generator (Object) {
|
|||||||
match (*node) {
|
match (*node) {
|
||||||
ast_node::if_comp(backing) return generate_if_comp(node, enclosing_object, enclosing_func)
|
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::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::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::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)
|
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>>) {
|
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
|
var first = true
|
||||||
name_ast_map->for_each(fun(name: string, syntax_ast_pair: pair<*tree<symbol>,*ast_node>) {
|
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>) {
|
/*var helper = fun(node: *ast_node, parent_chain: *stack<*ast_node>) {*/
|
||||||
match(*node) {
|
/*match(*node) {*/
|
||||||
ast_node::statement(backing) {
|
/*if (is_code_block(parent_chain->top()) && ast_to_syntax->contains_key(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))*/
|
/*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())
|
/*add_before_in(get_line(ast_to_syntax->get(node), name), node, parent_chain->top())*/
|
||||||
}
|
/*}*/
|
||||||
}
|
/*}*/
|
||||||
}
|
/*}*/
|
||||||
}
|
/*if (first)*/
|
||||||
if (first)
|
/*run_on_tree(helper, empty_pass_second_half, syntax_ast_pair.second)*/
|
||||||
run_on_tree(helper, empty_pass_second_half, syntax_ast_pair.second)
|
|
||||||
first = false
|
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>) {
|
var helper_before = fun(node: *ast_node, parent_chain: *stack<*ast_node>) {
|
||||||
match(*node) {
|
match(*node) {
|
||||||
ast_node::defer_statement(backing) {
|
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)))) {
|
if (is_code_block(parent_chain->top())) {
|
||||||
remove_full_statement(node, parent_chain)
|
remove(node, parent_chain)
|
||||||
defer_double_stack.top().push(backing.statement)
|
defer_double_stack.top().push(backing.statement)
|
||||||
} else {
|
} else {
|
||||||
replace_with_in(node, backing.statement, parent_chain)
|
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)
|
replace_with_in(node, block, parent_chain)
|
||||||
for (var i = 0; i < defer_double_stack.size() - loop_stack.top(); i++;)
|
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_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) {
|
ast_node::return_statement(backing) {
|
||||||
var block = ast_code_block_ptr()
|
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)
|
if (get_ast_type(enclosing_function)->return_type->is_ref)
|
||||||
return_value = make_operator_call("&", vector(return_value))
|
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)
|
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_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(assign_or_copy_construct_statement(temp_return, return_value))
|
||||||
// dereference so that the real ref can take it back
|
// dereference so that the real ref can take it back
|
||||||
if (get_ast_type(enclosing_function)->return_type->is_ref)
|
if (get_ast_type(enclosing_function)->return_type->is_ref)
|
||||||
temp_return = make_operator_call("*", vector(temp_return))
|
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++;)
|
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_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) {
|
ast_node::code_block(backing) {
|
||||||
node->code_block.children.add_all(defer_double_stack.pop().reverse_vector())
|
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")
|
error("Could not wrap value")
|
||||||
return value::void_nothing()
|
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_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; }
|
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())
|
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> {
|
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_stack->push(map<*ast_node,value>())
|
||||||
var value_from_inside = make_pair(value::void_nothing(), control_flow::nor())
|
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) {
|
match (*node) {
|
||||||
ast_node::function_call(backing) return interpret_function_call(node, var_stack, enclosing_object, enclosing_func, globals)
|
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::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::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::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)
|
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 printf(fmt_str: *char, ...): int
|
||||||
ext fun fprintf(file: *void, format: *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 fun fflush(file: int): int
|
||||||
ext var stderr: *void
|
ext var stderr: *void
|
||||||
ext fun fgets(buff: *char, size: int, file: *void): *char
|
ext fun fgets(buff: *char, size: int, file: *void): *char
|
||||||
@@ -63,16 +62,6 @@ fun print(toPrint: bool) {
|
|||||||
else
|
else
|
||||||
print("false")
|
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
|
fun print<T>(toPrint: T): void
|
||||||
print(string::to_string(toPrint))
|
print(string::to_string(toPrint))
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
/*#link("m")*/
|
||||||
#link(m)
|
#link(m)
|
||||||
|
|
||||||
fun fibanacci(num: int): int {
|
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
|
// Pass 1
|
||||||
var ensure_block_and_munge = fun(node: *ast_node, parent_chain: *stack<*ast_node>) {
|
var ensure_block_and_munge = fun(node: *ast_node, parent_chain: *stack<*ast_node>) {
|
||||||
match(*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) {
|
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 (!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_statement_ptr(ast_code_block_ptr(backing.else_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
|
// no need for case because it's already been lowered
|
||||||
ast_node::while_loop(backing) {
|
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()))
|
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
|
// 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)
|
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)))
|
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()))
|
condition_if->if_statement.then_part = ast_branching_statement_ptr(branching_type::break_stmt())
|
||||||
backing.statement->code_block.children.add(1, ast_statement_ptr(condition_if))
|
backing.statement->code_block.children.add(1, condition_if)
|
||||||
}
|
}
|
||||||
ast_node::for_loop(backing) {
|
ast_node::for_loop(backing) {
|
||||||
if (!is_code_block(backing.body)) backing.body = ast_code_block_ptr(backing.body)
|
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>()
|
backing.init = null<ast_node>()
|
||||||
// the do_update goes in the block above the for
|
// 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))
|
var update_ident = ast_identifier_ptr("do_update", type_ptr(base_type::boolean()), parent_chain->top())
|
||||||
add_before_in(ast_statement_ptr(ast_declaration_statement_ptr(update_ident, ast_value_ptr(string("false"), type_ptr(base_type::boolean())), false)),
|
add_before_in(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))
|
node, parent_chain->top())
|
||||||
var update_if = ast_if_statement_ptr(update_ident)
|
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.update = null<ast_node>()
|
||||||
backing.body->code_block.children.add(0, ast_statement_ptr(update_if))
|
backing.body->code_block.children.add(0, 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(1, ast_assignment_statement_ptr(update_ident, ast_value_ptr(string("true"), type_ptr(base_type::boolean()))))
|
||||||
|
|
||||||
var condition = backing.condition
|
var condition = backing.condition
|
||||||
backing.condition = ast_value_ptr(string("true"), type_ptr(base_type::boolean()))
|
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
|
// 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)
|
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)))
|
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()))
|
condition_if->if_statement.then_part = ast_branching_statement_ptr(branching_type::break_stmt())
|
||||||
backing.body->code_block.children.add(3, ast_statement_ptr(condition_if))
|
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 == "&&") {
|
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 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_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
|
var condition = short_circuit_result
|
||||||
if (func_name == "||")
|
if (func_name == "||")
|
||||||
condition = make_operator_call("!", vector(condition))
|
condition = make_operator_call("!", vector(condition))
|
||||||
var short_circuit_if = ast_if_statement_ptr(condition)
|
var short_circuit_if = ast_if_statement_ptr(condition)
|
||||||
// how to get proper parent scoping working for this part
|
// 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(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)
|
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_declaration, &shorter_tree, false)
|
||||||
run_on_tree_helper(short_circut_op, empty_pass_second_half, short_circuit_if, &shorter_tree, false)
|
run_on_tree_helper(short_circut_op, empty_pass_second_half, short_circuit_if, &shorter_tree, false)
|
||||||
return false
|
return false
|
||||||
@@ -124,6 +124,12 @@ fun obj_lower(name_ast_map: *map<string, pair<*tree<symbol>,*ast_node>>, ast_to_
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
var enclosing_block_idx = parent_chain->index_from_top_satisfying(fun(i: *ast_node): bool return is_code_block(i);)
|
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)
|
var func_type = get_ast_type(backing.func)
|
||||||
for (var i = 0; i < backing.parameters.size; i++;) {
|
for (var i = 0; i < backing.parameters.size; i++;) {
|
||||||
var param = backing.parameters[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)
|
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))))) {
|
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 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 declaration = 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)))))
|
var copy_in = 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(declaration, replace_before, replace_in)
|
||||||
add_before_in(copy_in, parent_chain->from_top(enclosing_block_idx-1), parent_chain->from_top(enclosing_block_idx))
|
add_before_in(copy_in, replace_before, replace_in)
|
||||||
backing.parameters[i] = temp_ident
|
backing.parameters[i] = temp_ident
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
var func_return_type = func_type->return_type
|
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>()))) {
|
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 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))
|
var declaration = 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(declaration, replace_before, replace_in)
|
||||||
add_before_in(ast_statement_ptr(ast_defer_statement_ptr(ast_statement_ptr(make_method_call(temp_return, "destruct", vector<*ast_node>())))),
|
add_before_in(ast_defer_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))
|
replace_before, replace_in)
|
||||||
replace_with_in(node, temp_return, parent_chain)
|
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)
|
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>()))) {
|
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
|
// the first pass ensures a code_block child
|
||||||
backing.body_statement->statement.child->code_block.children.add(order++,
|
backing.body_statement->code_block.children.add(order++,
|
||||||
ast_statement_ptr(ast_defer_statement_ptr(ast_statement_ptr(make_method_call(param, "destruct", vector<*ast_node>())))))
|
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 (!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()))) {
|
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 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))
|
var declaration = 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))))),
|
add_after_in(make_method_call(backing.identifier, "copy_construct", vector(make_operator_call("&", vector(temp_cpy_ctst)))),
|
||||||
parent_chain->top(), parent_chain->from_top(1))
|
node, parent_chain->top())
|
||||||
// do second so the order's right
|
// do second so the order's right
|
||||||
add_after_in(declaration,
|
add_after_in(declaration,
|
||||||
parent_chain->top(), parent_chain->from_top(1))
|
node, parent_chain->top())
|
||||||
backing.expression = null<ast_node>()
|
backing.expression = null<ast_node>()
|
||||||
}
|
}
|
||||||
if (has_method(ident_type->type_def, "destruct", vector<*type>())) {
|
if (has_method(ident_type->type_def, "destruct", vector<*type>())) {
|
||||||
// have to go up one because our parent is a statement
|
// 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>())))),
|
add_after_in(ast_defer_statement_ptr(make_method_call(backing.identifier, "destruct", vector<*ast_node>())),
|
||||||
parent_chain->top(), parent_chain->from_top(1))
|
node, parent_chain->top())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -262,15 +262,6 @@ fun get_children_pointer(node: *ast_node): *vector<*ast_node> {
|
|||||||
}
|
}
|
||||||
return bc
|
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
|
fun remove(orig: *ast_node, in: *stack<*ast_node>): *ast_node
|
||||||
return remove(orig, in->top())
|
return remove(orig, in->top())
|
||||||
fun remove(orig: *ast_node, in: *ast_node): *ast_node {
|
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())
|
replace_with_in(orig, new, in->top())
|
||||||
fun replace_with_in(orig: *ast_node, new: *ast_node, in: *ast_node) {
|
fun replace_with_in(orig: *ast_node, new: *ast_node, in: *ast_node) {
|
||||||
match (*in) {
|
match (*in) {
|
||||||
ast_node::statement(backing) { backing.child = new; return; }
|
|
||||||
ast_node::return_statement(backing) { backing.return_value = new; return; }
|
ast_node::return_statement(backing) { backing.return_value = new; return; }
|
||||||
ast_node::assignment_statement(backing) {
|
ast_node::assignment_statement(backing) {
|
||||||
if (backing.to == orig) {
|
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::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::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::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::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::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);)
|
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 serialize
|
||||||
import io
|
import io
|
||||||
|
|
||||||
/*fun to_string(in: bool): string*/
|
ext fun snprintf(to_str: *char, num: ulong, format: *char, ...): int
|
||||||
/*if (in) return string("true")*/
|
fun to_string(in: float): string
|
||||||
/*else return string("false")*/
|
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
|
fun to_string(in: uchar): string
|
||||||
return to_string_num(in)
|
return to_string_num(in)
|
||||||
fun to_string(in: short): string
|
fun to_string(in: short): string
|
||||||
@@ -98,10 +111,6 @@ obj string (Object, Serializable) {
|
|||||||
data.construct(len);
|
data.construct(len);
|
||||||
data.set_size(len);
|
data.set_size(len);
|
||||||
mem::memmove((data.getBackingMemory()) cast *void, (str) cast *void, (len) cast ulong)
|
mem::memmove((data.getBackingMemory()) cast *void, (str) cast *void, (len) cast ulong)
|
||||||
/*while(*str) {*/
|
|
||||||
/*data.addEnd(*str);*/
|
|
||||||
/*str += 1;*/
|
|
||||||
/*}*/
|
|
||||||
// no null terminator
|
// no null terminator
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,6 +3,7 @@ import os:*
|
|||||||
import mem:*
|
import mem:*
|
||||||
import util:*
|
import util:*
|
||||||
|
|
||||||
|
/*#link("pthread")*/
|
||||||
#link(pthread)
|
#link(pthread)
|
||||||
ext fun pthread_attr_init(attr_ptr: *void): int
|
ext fun pthread_attr_init(attr_ptr: *void): int
|
||||||
ext fun pthread_create(thread: *ulong, attr_ptr: *void, func: *void, param: *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) {
|
fun add(index: int, dataIn: ref T) {
|
||||||
|
if (size == 0) {
|
||||||
|
add(dataIn)
|
||||||
|
return
|
||||||
|
}
|
||||||
add(last())
|
add(last())
|
||||||
for (var i = size-2; i > index; i--;) {
|
for (var i = size-2; i > index; i--;) {
|
||||||
data[i] = data[i-1]
|
data[i] = data[i-1]
|
||||||
|
|||||||
Reference in New Issue
Block a user