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:
@@ -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 ;
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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);)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user