Added in extern global variables and printing of *char and string to stderr with printlnerr, printerr. Note that this will still compile in a previous version, but instead of extern, stderr will be newly declared. This is ok, because this version of the compiler never uses it, so we'll only use it after this one is bootstrapped in.

This commit is contained in:
Nathan Braswell
2016-05-22 13:08:10 -07:00
parent a64e79c789
commit 12dfa837e3
5 changed files with 49 additions and 30 deletions

View File

@@ -140,7 +140,7 @@ access_operation = unarad WS "." WS identifier | unarad WS "->" WS identifier |
assignment_statement = factor WS "=" WS boolean_expression | factor WS "\+=" WS boolean_expression | factor WS "-=" WS boolean_expression | factor WS "\*=" WS boolean_expression | factor WS "/=" WS boolean_expression ;
# if it's being assigned to, we allow type inferencing
declaration_statement = "var" WS identifier WS "=" WS boolean_expression | "var" WS identifier WS dec_type WS "=" WS boolean_expression | "var" WS identifier WS dec_type | "var" WS identifier WS "." WS identifier WS "\(" WS opt_parameter_list WS "\)" WS dec_type ;
declaration_statement = "var" WS identifier WS "=" WS boolean_expression | "var" WS identifier WS dec_type WS "=" WS boolean_expression | "var" WS identifier WS dec_type | "ext" WS "var" WS identifier WS dec_type | "var" WS identifier WS "." WS identifier WS "\(" WS opt_parameter_list WS "\)" WS dec_type ;
hexadecimal = "0x([0-9]|[a-f])+" ;
integer = numeric | hexadecimal ;
floating_literal = numeric "." float_end ;

View File

@@ -815,8 +815,8 @@ obj assignment_statement (Object) {
return to == other.to && from == other.from
}
}
fun ast_declaration_statement_ptr(ident: *ast_node, expression: *ast_node): *ast_node {
var to_ret.construct(ident, expression): declaration_statement
fun ast_declaration_statement_ptr(ident: *ast_node, expression: *ast_node, is_extern: bool): *ast_node {
var to_ret.construct(ident, expression, is_extern): declaration_statement
var ptr = new<ast_node>()
ptr->copy_construct(&ast_node::declaration_statement(to_ret))
return ptr
@@ -831,16 +831,19 @@ obj declaration_statement (Object) {
var identifier: *ast_node
var expression: *ast_node
var init_method_call: *ast_node
fun construct(identifier_in: *ast_node, expression_in: *ast_node): *declaration_statement {
var is_extern: bool
fun construct(identifier_in: *ast_node, expression_in: *ast_node, is_extern_in: bool): *declaration_statement {
identifier = identifier_in
expression = expression_in
init_method_call = null<ast_node>()
is_extern = is_extern_in
return this
}
fun copy_construct(old: *declaration_statement) {
identifier = old->identifier
expression = old->expression
init_method_call = old->init_method_call
is_extern = old->is_extern
}
fun destruct() {
}
@@ -849,7 +852,7 @@ obj declaration_statement (Object) {
copy_construct(&other)
}
fun operator==(other: ref declaration_statement): bool {
return identifier == other.identifier && expression == other.expression && init_method_call == other.init_method_call
return identifier == other.identifier && expression == other.expression && init_method_call == other.init_method_call && is_extern == other.is_extern
}
}
fun ast_if_comp_ptr(): *ast_node {

View File

@@ -620,7 +620,7 @@ obj ast_transformation (Object) {
}
if (!identifier->identifier.type) error(node, "declaration statement with no type or expression from which to inference type")
if (identifier->identifier.type->is_none() || (identifier->identifier.type->indirection == 0 && identifier->identifier.type->is_void())) error(node, "declaration statement with bad type")
var declaration = ast_declaration_statement_ptr(identifier, expression)
var declaration = ast_declaration_statement_ptr(identifier, expression, get_node("\"ext\"", node) != null<tree<symbol>>())
// ok, deal with the possible init position method call
if (identifiers.size == 2) {
var parameters = get_nodes("parameter", node).map(fun(child: *tree<symbol>): *ast_node return transform(get_node("boolean_expression", child), scope, template_replacements);)

View File

@@ -463,7 +463,7 @@ obj c_generator (Object) {
vert->adt_def.options.for_each(fun(option: *ast_node) {
add_to_enum += string("enum_opt_") + get_name(option) + ","
if (!option->identifier.type->is_empty_adt_option())
add_to_structs += generate_declaration_statement(ast_declaration_statement_ptr(option, null<ast_node>()), null<ast_node>(), null<ast_node>(), null<stack<pair<bool,stack<*ast_node>>>>(), false).one_string() + ";\n"
add_to_structs += generate_declaration_statement(ast_declaration_statement_ptr(option, null<ast_node>(), false), null<ast_node>(), null<ast_node>(), null<stack<pair<bool,stack<*ast_node>>>>(), false).one_string() + ";\n"
})
structs += string("enum { ") + add_to_enum + " } flag;\n"
structs += string("union { ") + add_to_structs + " } data;\n"
@@ -533,7 +533,10 @@ obj c_generator (Object) {
var ident_type = identifier->identifier.type
// we do the declaration in the pre now so that we can take it's address to close over it for things like recursive closures
// we only make it first if it's a function type though, so that global levels still work
var to_ret = code_triple(type_to_c(identifier->identifier.type) + " " + get_name(identifier), string(), string())
var pre_stuff = type_to_c(identifier->identifier.type) + " " + get_name(identifier)
if (node->declaration_statement.is_extern)
pre_stuff = string("extern ") + pre_stuff
var to_ret = code_triple(pre_stuff, string(), string())
if (node->declaration_statement.expression) {
if (ident_type->indirection == 0 && (ident_type->is_adt() || (ident_type->is_object() && has_method(ident_type->type_def, "copy_construct", vector(get_ast_type(node->declaration_statement.expression)->clone_with_increased_indirection()))))) {
to_ret.pre += ";\n"
@@ -629,7 +632,7 @@ obj c_generator (Object) {
if (function_return_type->is_ref)
temp_ident_type = temp_ident_type->clone_with_increased_indirection()
var temp_ident = ast_identifier_ptr(string("temporary_return")+get_id(), temp_ident_type, null<ast_node>())
var declaration = ast_declaration_statement_ptr(temp_ident, null<ast_node>())
var declaration = ast_declaration_statement_ptr(temp_ident, null<ast_node>(), false)
// have to pass false to the declaration generator, so can't do it through generate_statement
to_ret.pre = generate_declaration_statement(declaration, enclosing_object, enclosing_func, defer_stack, false).one_string() + ";\n"
if ((function_return_type->is_object() || return_value_type->is_object()) && !function_return_type->equality(return_value_type, false))
@@ -697,7 +700,7 @@ obj c_generator (Object) {
var option_str = generate(case_node->case_statement.option, enclosing_object, enclosing_func, defer_stack, false).one_string()
var to_ret_case = code_triple("/*case ") + option_str + "*/ if(" + matching_value.value + ".flag == " + string("enum_opt_") + option_str + ") {\n"
if (case_node->case_statement.unpack_ident) {
to_ret_case += generate_declaration_statement(ast_declaration_statement_ptr(case_node->case_statement.unpack_ident, null<ast_node>()), null<ast_node>(), null<ast_node>(), null<stack<pair<bool,stack<*ast_node>>>>(), false).one_string()
to_ret_case += generate_declaration_statement(ast_declaration_statement_ptr(case_node->case_statement.unpack_ident, null<ast_node>(), false), null<ast_node>(), null<ast_node>(), null<stack<pair<bool,stack<*ast_node>>>>(), false).one_string()
to_ret_case += string(" = ") + matching_value.value + ".data." + option_str + ";\n"
} else {
to_ret_case += "/*no unpack_ident*/\n"
@@ -734,7 +737,7 @@ obj c_generator (Object) {
}
if (need_variable) {
var temp_ident = ast_identifier_ptr(string("temporary_value")+get_id(), get_ast_type(node), null<ast_node>())
var declaration = ast_declaration_statement_ptr(temp_ident, null<ast_node>())
var declaration = ast_declaration_statement_ptr(temp_ident, null<ast_node>(), false)
// have to pass false to the declaration generator, so can't do it through generate_statement
var trip_ret = code_triple()
// trip_ret.pre += generate_declaration_statement(declaration, enclosing_object, enclosing_func, null<stack<pair<bool,stack<*ast_node>>>>(), false).one_string() + " = " + to_ret + ";\n"
@@ -877,7 +880,7 @@ obj c_generator (Object) {
var param_type = get_ast_type(param)
if (!in_function_param_type->is_ref && param_type->indirection == 0 && (param_type->is_adt() || (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(string("temporary_param")+get_id(), param_type->clone_without_ref(), null<ast_node>())
var declaration = ast_declaration_statement_ptr(temp_ident, null<ast_node>())
var declaration = ast_declaration_statement_ptr(temp_ident, null<ast_node>(), false)
// have to pass false to the declaration generator, so can't do it through generate_statement
call_string.pre += generate_declaration_statement(declaration, enclosing_object, enclosing_func, null<stack<pair<bool,stack<*ast_node>>>>(), false).one_string() + ";\n"
call_string.pre += generate_statement(ast_statement_ptr(make_method_call(temp_ident, "copy_construct", vector(make_operator_call("&", vector(param))))), enclosing_object, enclosing_func, null<stack<pair<bool,stack<*ast_node>>>>()).one_string()
@@ -892,7 +895,7 @@ obj c_generator (Object) {
if (!func_return_type->is_ref && (needs_temp_for_destruct || (!func_return_type->is_void() && need_variable)) ) {
// kind of ugly combo here of
var temp_ident = ast_identifier_ptr(string("temporary_return")+get_id(), func_return_type, null<ast_node>())
var declaration = ast_declaration_statement_ptr(temp_ident, null<ast_node>())
var declaration = ast_declaration_statement_ptr(temp_ident, null<ast_node>(), false)
// have to pass false to the declaration generator, so can't do it through generate_statement
call_string.pre += generate_declaration_statement(declaration, enclosing_object, enclosing_func, null<stack<pair<bool,stack<*ast_node>>>>(), false).one_string() + ";\n"
pre_call = generate_identifier(temp_ident, enclosing_object, enclosing_func).one_string()
@@ -913,7 +916,7 @@ obj c_generator (Object) {
// lambda
if (pre_call == "" && (!func_return_type->is_void() || func_return_type->indirection)) {
var temp_ident = ast_identifier_ptr(string("temporary_return")+get_id(), func_return_type, null<ast_node>())
var declaration = ast_declaration_statement_ptr(temp_ident, null<ast_node>())
var declaration = ast_declaration_statement_ptr(temp_ident, null<ast_node>(), false)
// have to pass false to the declaration generator, so can't do it through generate_statement
call_string.pre += generate_declaration_statement(declaration, enclosing_object, enclosing_func, null<stack<pair<bool,stack<*ast_node>>>>(), false).one_string() + ";\n"
pre_call = generate_identifier(temp_ident, enclosing_object, enclosing_func).one_string()

View File

@@ -2,43 +2,56 @@ import string;
import vector;
import mem:*
fun println() : void {
print("\n");
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
fun printlnerr<T>(toPrint: T) : void {
printerr(toPrint)
printerr("\n")
}
fun printerr(toPrint: string::string) : void {
var charArr = toPrint.toCharArray()
printerr(charArr)
delete(charArr)
}
fun printerr(toPrint: *char) : void {
fprintf(stderr, "%s", toPrint)
fflush(0)
}
fun println<T>(toPrint: T) : void {
print(toPrint)
print("\n")
}
fun print<T>(toPrint: *T)
print((toPrint) cast ulong)
ext fun printf(fmt_str: *char, ...): int
ext fun fflush(file: int): int
fun print(toPrint: *char) : void {
printf("%s", toPrint)
fflush(0)
}
fun println()
print("\n")
fun print<T>(toPrint: *T) {
print("ptr:<")
print((toPrint) cast ulong)
print(">")
}
fun print(toPrint: char) : void
print(string::string(toPrint))
fun print(toPrint: string::string) : void {
var charArr = toPrint.toCharArray()
defer delete(charArr)
print(charArr);
print(charArr)
delete(charArr)
}
fun print(toPrint: bool): void {
fun print(toPrint: bool) {
if (toPrint)
print("true")
else
print("false")
return;
}
ext fun snprintf(to_str: *char, num: ulong, format: *char, ...): int
fun print(toPrint: float)
print((toPrint) cast double)
@@ -55,7 +68,7 @@ fun print<T>(toPrint: T): void
// Ok, just some DEAD simple file io for now
ext fun fopen(path: *char, mode: *char): *void
ext fun fclose(file: *void): int
ext fun fprintf(file: *void, format: *char, ...): int
// fprintf is already used for stderr above
ext fun ftell(file: *void): long
ext fun fseek(file: *void, offset: long, whence: int): int
ext fun fread(ptr: *void, size: ulong, nmemb: ulong, file: *void): ulong