diff --git a/CHANGELOG.org b/CHANGELOG.org index eebb83f..0dbf9ef 100644 --- a/CHANGELOG.org +++ b/CHANGELOG.org @@ -24,15 +24,32 @@ Added support for EOF Added additional debug information to M2-Planet Added line numbers and files names for errors in parsing to help debug Added support for close and fclose +Added prototype support for chmod +Added basic support for escape strings +Added support for continue +Added string_length function to string.c +Added function numerate_string for converting string to integer +Added supporting hex2char, char2hex, dec2char and char2dec functions +Added support bitwise xor ** Changed Improving Documentation to help new programmers get functional +Cleaned up numerate_number to make it more general purpose +Enabled stand alone builds of calloc +Unified bitwise operations +Made string.c more independent ** Fixed Minor cleanup and removal of unneeded whitespace Fixed outstanding bug when struct foo* foo and foo->bar was used +Fixed ":foo bug +Fixed "\n:foo bug +Adjusted all previous references to numerate_number to ensure output is consistent +Fixed up reader so that '\'' and "\"" work correctly now +fixed "\"" bug in string output generation ** Removed +Removed need for memset in numerate_number * 0.1 - 2018-02-23 ** Added diff --git a/cc_core.c b/cc_core.c index acad426..6b7a18e 100644 --- a/cc_core.c +++ b/cc_core.c @@ -30,6 +30,7 @@ char* break_target; /* Imported functions */ char* parse_string(char* string); +int escape_lookup(char* c); char* numerate_number(int a); char* postpend_char(char* s, char a); char* prepend_char(char a, char* s); @@ -94,7 +95,7 @@ int stack_index(struct token_list* a, struct token_list* function) file_print(a->s,stderr); file_print(" does not exist in function ", stderr); file_print(function->s,stderr); - file_print("\x0A",stderr); + file_print("\n",stderr); line_error(); exit(EXIT_FAILURE); } @@ -102,13 +103,13 @@ int stack_index(struct token_list* a, struct token_list* function) struct token_list* expression(struct token_list* out, struct token_list* function); struct token_list* function_call(struct token_list* out, struct token_list* function, char* s, int bool) { - require_match("ERROR in process_expression_list\nNo ( was found\x0A", "("); + require_match("ERROR in process_expression_list\nNo ( was found\n", "("); int passed = 0; if(global_token->s[0] != ')') { out = expression(out, function); - out = emit("PUSH_eax\t#_process_expression1\x0A", out); + out = emit("PUSH_eax\t#_process_expression1\n", out); function->temps = function->temps + 1; passed = 1; @@ -116,7 +117,7 @@ struct token_list* function_call(struct token_list* out, struct token_list* func { global_token = global_token->next; out = expression(out, function); - out = emit("PUSH_eax\t#_process_expression2\x0A", out); + out = emit("PUSH_eax\t#_process_expression2\n", out); function->temps = function->temps + 1; passed = passed + 1; } @@ -127,14 +128,16 @@ struct token_list* function_call(struct token_list* out, struct token_list* func if(2 == bool) { struct token_list* a = sym_lookup(s, function->locals); - out = emit(prepend_string("LOAD_EFFECTIVE_ADDRESS %", numerate_number(stack_index(a, function))), out); - out = emit("LOAD_INTEGER\nCALL_eax\n", out); + out = emit("LOAD_EFFECTIVE_ADDRESS %", out); + out = emit(numerate_number(stack_index(a, function)), out); + out = emit("\nLOAD_INTEGER\nCALL_eax\n", out); } else if(1 == bool) { struct token_list* a = sym_lookup(s, function->arguments); - out = emit(prepend_string("LOAD_EFFECTIVE_ADDRESS %", numerate_number(stack_index(a, function))), out); - out = emit("LOAD_INTEGER\nCALL_eax\n", out); + out = emit("LOAD_EFFECTIVE_ADDRESS %", out); + out = emit(numerate_number(stack_index(a, function)), out); + out = emit("\nLOAD_INTEGER\nCALL_eax\n", out); } else { @@ -143,7 +146,7 @@ struct token_list* function_call(struct token_list* out, struct token_list* func for(; passed > 0; passed = passed - 1) { - out = emit("POP_ebx\t# _process_expression_locals\x0A", out); + out = emit("POP_ebx\t# _process_expression_locals\n", out); function->temps = function->temps - 1; } return out; @@ -165,15 +168,18 @@ struct token_list* sym_get_value(char *s, struct token_list* out, struct token_l { if(!match("(", global_token->s)) { - out = emit(prepend_string("#Loading address of function\nLOAD_EFFECTIVE_ADDRESS %", numerate_number(stack_index(a, function))), out); - out = emit("LOAD_INTEGER\n", out); + out = emit("#Loading address of function\nLOAD_EFFECTIVE_ADDRESS %", out); + out = emit(numerate_number(stack_index(a, function)), out); + out = emit("\nLOAD_INTEGER\n", out); return out; } return function_call(out, function, s, 2); } current_target = a->type; - out = emit(prepend_string("LOAD_EFFECTIVE_ADDRESS %", numerate_number(stack_index(a, function))), out); - if(!match("=", global_token->s)) out = emit("LOAD_INTEGER\x0A", out); + out = emit("LOAD_EFFECTIVE_ADDRESS %", out); + out = emit(numerate_number(stack_index(a, function)), out); + out = emit("\n", out); + if(!match("=", global_token->s)) out = emit("LOAD_INTEGER\n", out); return out; } @@ -185,14 +191,17 @@ struct token_list* sym_get_value(char *s, struct token_list* out, struct token_l { if(!match("(", global_token->s)) { - out = emit(prepend_string("#Loading address of function\nLOAD_EFFECTIVE_ADDRESS %", numerate_number(stack_index(a, function))), out); - out = emit("LOAD_INTEGER\n", out); + out = emit("#Loading address of function\nLOAD_EFFECTIVE_ADDRESS %", out); + out = emit(numerate_number(stack_index(a, function)), out); + out = emit("\nLOAD_INTEGER\n", out); return out; } return function_call(out, function, s, 1); } - out = emit(prepend_string("LOAD_EFFECTIVE_ADDRESS %", numerate_number(stack_index(a, function))), out); - if(!match("=", global_token->s) && !match("argv", s)) out = emit("LOAD_INTEGER\x0A", out); + out = emit("LOAD_EFFECTIVE_ADDRESS %", out); + out = emit(numerate_number(stack_index(a, function)), out); + out = emit("\n", out); + if(!match("=", global_token->s) && !match("argv", s)) out = emit("LOAD_INTEGER\n", out); return out; } @@ -215,12 +224,12 @@ struct token_list* sym_get_value(char *s, struct token_list* out, struct token_l { current_target = a->type; out = emit(prepend_string("LOAD_IMMEDIATE_eax &GLOBAL_", postpend_char(s, LF)), out); - if(!match("=", global_token->s)) out = emit("LOAD_INTEGER\x0A", out); + if(!match("=", global_token->s)) out = emit("LOAD_INTEGER\n", out); return out; } file_print(s ,stderr); - file_print(" is not a defined symbol\x0A", stderr); + file_print(" is not a defined symbol\n", stderr); line_error(); exit(EXIT_FAILURE); } @@ -247,12 +256,20 @@ struct token_list* primary_expr(struct token_list* out, struct token_list* funct { global_token = global_token->next; out = expression(out, function); - require_match("Error in Primary expression\nDidn't get )\x0A", ")"); + require_match("Error in Primary expression\nDidn't get )\n", ")"); } else if(global_token->s[0] == 39) { /* 39 == ' */ out = emit("LOAD_IMMEDIATE_eax %", out); - out = emit(numerate_number(global_token->s[1]), out); + if('\\' == global_token->s[1]) + { + out = emit(numerate_number(escape_lookup(global_token->s + 1)), out); + } + else + { + out = emit(numerate_number(global_token->s[1]), out); + } + out = emit("\n", out); global_token = global_token->next; } else if(global_token->s[0] == 34) @@ -260,10 +277,12 @@ struct token_list* primary_expr(struct token_list* out, struct token_list* funct char* number_string = numerate_number(string_num); out = emit("LOAD_IMMEDIATE_eax &STRING_", out); out = emit(number_string, out); + out = emit("\n", out); /* The target */ strings_list = emit(":STRING_", strings_list); strings_list = emit(number_string, strings_list); + strings_list = emit("\n", strings_list); /* Parse the string */ strings_list = emit(parse_string(global_token->s), strings_list); @@ -275,7 +294,7 @@ struct token_list* primary_expr(struct token_list* out, struct token_list* funct { file_print("Recieved ", stderr); file_print(global_token->s, stderr); - file_print(" in primary_expr\x0A", stderr); + file_print(" in primary_expr\n", stderr); line_error(); exit(EXIT_FAILURE); } @@ -289,7 +308,7 @@ struct token_list* pre_recursion(struct token_list* out, struct token_list* func { last_type = current_target; global_token = global_token->next; - out = emit("PUSH_eax\t#_common_recursion\x0A", out); + out = emit("PUSH_eax\t#_common_recursion\n", out); func->temps = func->temps + 1; return out; } @@ -332,7 +351,7 @@ struct token_list* post_recursion(struct token_list* out, struct token_list* fun { current_target = promote_type(current_target, last_type); func->temps = func->temps - 1; - out = emit("POP_ebx\t# _common_recursion\x0A", out); + out = emit("POP_ebx\t# _common_recursion\n", out); return out; } @@ -377,28 +396,30 @@ struct token_list* postfix_expr(struct token_list* out, struct token_list* funct /* Add support for Ints */ if( 1 != a->indirect->size) { - out = emit(prepend_string("SAL_eax_Immediate8 !", numerate_number(ceil_log2(a->indirect->size))), out); + out = emit("SAL_eax_Immediate8 !", out); + out = emit(numerate_number(ceil_log2(a->indirect->size)), out); + out = emit("\n", out); } - out = emit("ADD_ebx_to_eax\x0A", out); + out = emit("ADD_ebx_to_eax\n", out); current_target = target; if(!match("=", global_token->next->s)) { if( 4 == a->indirect->size) { - out = emit("LOAD_INTEGER\x0A", out); + out = emit("LOAD_INTEGER\n", out); } else { - out = emit("LOAD_BYTE\x0A", out); + out = emit("LOAD_BYTE\n", out); } } - require_match("ERROR in postfix_expr\nMissing ]\x0A", "]"); + require_match("ERROR in postfix_expr\nMissing ]\n", "]"); } else if(match("->", global_token->s)) { - out = emit("# looking up offset\x0A", out); + out = emit("# looking up offset\n", out); global_token = global_token->next; struct type* i; for(i = current_target->members; NULL != i; i = i->members) @@ -411,19 +432,20 @@ struct token_list* postfix_expr(struct token_list* out, struct token_list* funct file_print(current_target->name, stderr); file_print("->", stderr); file_print(global_token->s, stderr); - file_print(" does not exist\x0A", stderr); + file_print(" does not exist\n", stderr); line_error(); exit(EXIT_FAILURE); } if(0 != i->offset) { - out = emit("# -> offset calculation\x0A", out); - out = emit(prepend_string("LOAD_IMMEDIATE_ebx %", numerate_number(i->offset)), out); - out = emit("ADD_ebx_to_eax\x0A", out); + out = emit("# -> offset calculation\n", out); + out = emit("LOAD_IMMEDIATE_ebx %", out); + out = emit(numerate_number(i->offset), out); + out = emit("\nADD_ebx_to_eax\n", out); } if(!match("=", global_token->next->s)) { - out = emit("LOAD_INTEGER\x0A", out); + out = emit("LOAD_INTEGER\n", out); } current_target = i->type; global_token = global_token->next; @@ -444,28 +466,30 @@ struct token_list* unary_expr(struct token_list* out, struct token_list* functio { if(match("-", global_token->s)) { - out = emit("LOAD_IMMEDIATE_eax %0\x0A", out); + out = emit("LOAD_IMMEDIATE_eax %0\n", out); out = pre_recursion(out, function); out = postfix_expr(out, function); out = post_recursion(out, function); - out = emit("SUBTRACT_eax_from_ebx_into_ebx\nMOVE_ebx_to_eax\x0A", out); + out = emit("SUBTRACT_eax_from_ebx_into_ebx\nMOVE_ebx_to_eax\n", out); } else if(match("!", global_token->s)) { - out = emit("LOAD_IMMEDIATE_eax %1\x0A", out); + out = emit("LOAD_IMMEDIATE_eax %1\n", out); out = pre_recursion(out, function); out = postfix_expr(out, function); out = post_recursion(out, function); - out = emit("XOR_ebx_eax_into_eax\x0A", out); + out = emit("XOR_ebx_eax_into_eax\n", out); } else if(match("sizeof", global_token->s)) { global_token = global_token->next; - require_match("ERROR in unary_expr\nMissing (\x0A", "("); + require_match("ERROR in unary_expr\nMissing (\n", "("); struct type* a = type_name(); - require_match("ERROR in unary_expr\nMissing )\x0A", ")"); + require_match("ERROR in unary_expr\nMissing )\n", ")"); - out = emit(prepend_string("LOAD_IMMEDIATE_eax %", numerate_number(a->size)), out); + out = emit("LOAD_IMMEDIATE_eax %", out); + out = emit(numerate_number(a->size), out); + out = emit("\n", out); } else out = postfix_expr(out, function); @@ -492,35 +516,35 @@ struct token_list* additive_expr(struct token_list* out, struct token_list* func out = pre_recursion(out, function); out = unary_expr(out, function); out = post_recursion(out, function); - out = emit("ADD_ebx_to_eax\x0A", out); + out = emit("ADD_ebx_to_eax\n", out); } else if(match("-", global_token->s)) { out = pre_recursion(out, function); out = unary_expr(out, function); out = post_recursion(out, function); - out = emit("SUBTRACT_eax_from_ebx_into_ebx\nMOVE_ebx_to_eax\x0A", out); + out = emit("SUBTRACT_eax_from_ebx_into_ebx\nMOVE_ebx_to_eax\n", out); } else if(match("*", global_token->s)) { out = pre_recursion(out, function); out = unary_expr(out, function); out = post_recursion(out, function); - out = emit("MULTIPLY_eax_by_ebx_into_eax\x0A", out); + out = emit("MULTIPLY_eax_by_ebx_into_eax\n", out); } else if(match("/", global_token->s)) { out = pre_recursion(out, function); out = unary_expr(out, function); out = post_recursion(out, function); - out = emit("XCHG_eax_ebx\nLOAD_IMMEDIATE_edx %0\nDIVIDE_eax_by_ebx_into_eax\x0A", out); + out = emit("XCHG_eax_ebx\nLOAD_IMMEDIATE_edx %0\nDIVIDE_eax_by_ebx_into_eax\n", out); } else if(match("%", global_token->s)) { out = pre_recursion(out, function); out = unary_expr(out, function); out = post_recursion(out, function); - out = emit("XCHG_eax_ebx\nLOAD_IMMEDIATE_edx %0\nMODULUS_eax_from_ebx_into_ebx\nMOVE_edx_to_eax\x0A", out); + out = emit("XCHG_eax_ebx\nLOAD_IMMEDIATE_edx %0\nMODULUS_eax_from_ebx_into_ebx\nMOVE_edx_to_eax\n", out); } else return out; } @@ -546,7 +570,7 @@ struct token_list* shift_expr(struct token_list* out, struct token_list* functio /* Ugly hack to Work around flaw in x86 */ struct token_list* old = out->next; free(out); - out = emit("COPY_eax_to_ecx\nPOP_eax\nSAL_eax_cl\x0A", old); + out = emit("COPY_eax_to_ecx\nPOP_eax\nSAL_eax_cl\n", old); } else if(match(">>", global_token->s)) { @@ -556,7 +580,7 @@ struct token_list* shift_expr(struct token_list* out, struct token_list* functio /* Ugly hack to Work around flaw in x86 */ struct token_list* old = out->next; free(out); - out = emit("COPY_eax_to_ecx\nPOP_eax\nSAR_eax_cl\x0A", old); + out = emit("COPY_eax_to_ecx\nPOP_eax\nSAR_eax_cl\n", old); } else { @@ -584,28 +608,28 @@ struct token_list* relational_expr(struct token_list* out, struct token_list* fu out = pre_recursion(out, function); out = shift_expr(out, function); out = post_recursion(out, function); - out = emit("CMP\nSETL\nMOVEZBL\x0A", out); + out = emit("CMP\nSETL\nMOVEZBL\n", out); } else if(match("<=", global_token->s)) { out = pre_recursion(out, function); out = shift_expr(out, function); out = post_recursion(out, function); - out = emit("CMP\nSETLE\nMOVEZBL\x0A", out); + out = emit("CMP\nSETLE\nMOVEZBL\n", out); } else if(match(">=", global_token->s)) { out = pre_recursion(out, function); out = shift_expr(out, function); out = post_recursion(out, function); - out = emit("CMP\nSETGE\nMOVEZBL\x0A", out); + out = emit("CMP\nSETGE\nMOVEZBL\n", out); } else if(match(">", global_token->s)) { out = pre_recursion(out, function); out = shift_expr(out, function); out = post_recursion(out, function); - out = emit("CMP\nSETG\nMOVEZBL\x0A", out); + out = emit("CMP\nSETG\nMOVEZBL\n", out); } else return out; } @@ -628,14 +652,14 @@ struct token_list* equality_expr(struct token_list* out, struct token_list* func out = pre_recursion(out, function); out = relational_expr(out, function); out = post_recursion(out, function); - out = emit("CMP\nSETE\nMOVEZBL\x0A", out); + out = emit("CMP\nSETE\nMOVEZBL\n", out); } else if(match("!=", global_token->s)) { out = pre_recursion(out, function); out = relational_expr(out, function); out = post_recursion(out, function); - out = emit("CMP\nSETNE\nMOVEZBL\x0A", out); + out = emit("CMP\nSETNE\nMOVEZBL\n", out); } else return out; } @@ -646,37 +670,35 @@ struct token_list* equality_expr(struct token_list* out, struct token_list* func * equality-expr * bitwise-and-expr & equality-expr */ -struct token_list* bitwise_and_expr(struct token_list* out, struct token_list* function) +struct token_list* bitwise(struct token_list* out, struct token_list* function) { out = equality_expr(out, function); - while(global_token->s[0] == '&') + while(1) { - out = pre_recursion(out, function); - out = equality_expr(out, function); - out = post_recursion(out, function); - out = emit("AND_eax_ebx\x0A", out); + if(global_token->s[0] == '&') + { + out = pre_recursion(out, function); + out = equality_expr(out, function); + out = post_recursion(out, function); + out = emit("AND_eax_ebx\n", out); + } + else if(global_token->s[0] == '|') + { + out = pre_recursion(out, function); + out = equality_expr(out, function); + out = post_recursion(out, function); + out = emit("OR_eax_ebx\n", out); + } + else if(global_token->s[0] == '^') + { + out = pre_recursion(out, function); + out = equality_expr(out, function); + out = post_recursion(out, function); + out = emit("XOR_ebx_eax_into_eax\n", out); + } + else return out; } - return out; -} - -/* - * bitwise-or-expr: - * bitwise-and-expr - * bitwise-and-expr | bitwise-or-expr - */ -struct token_list* bitwise_or_expr(struct token_list* out, struct token_list* function) -{ - out = bitwise_and_expr(out, function); - - while(global_token->s[0] == '|') - { - out = pre_recursion(out, function); - out = bitwise_and_expr(out, function); - out = post_recursion(out, function); - out = emit("OR_eax_ebx\x0A", out); - } - return out; } /* @@ -686,7 +708,7 @@ struct token_list* bitwise_or_expr(struct token_list* out, struct token_list* fu */ struct token_list* expression(struct token_list* out, struct token_list* function) { - out = bitwise_or_expr(out, function); + out = bitwise(out, function); if(global_token->s[0] == '=') { @@ -698,15 +720,15 @@ struct token_list* expression(struct token_list* out, struct token_list* functio if(member) { - if(1 == target->indirect->size) out = emit("STORE_CHAR\x0A", out); + if(1 == target->indirect->size) out = emit("STORE_CHAR\n", out); else if(4 == target->indirect->size) { - out = emit("STORE_INTEGER\x0A", out); + out = emit("STORE_INTEGER\n", out); } } else { - out = emit("STORE_INTEGER\x0A", out); + out = emit("STORE_INTEGER\n", out); } } return out; @@ -717,7 +739,7 @@ struct token_list* expression(struct token_list* out, struct token_list* functio struct token_list* collect_local(struct token_list* out, struct token_list* function) { struct type* type_size = type_name(); - out = emit(prepend_string("# Defining local ", prepend_string(global_token->s, "\x0A")), out); + out = emit(prepend_string("# Defining local ", prepend_string(global_token->s, "\n")), out); struct token_list* a = sym_declare(global_token->s, type_size, function->locals); function->locals = a; @@ -731,9 +753,9 @@ struct token_list* collect_local(struct token_list* out, struct token_list* func } function->temps = function->temps + 1; - require_match("ERROR in collect_local\nMissing ;\x0A", ";"); + require_match("ERROR in collect_local\nMissing ;\n", ";"); - out = emit(prepend_string("PUSH_eax\t#", prepend_string(a->s, "\x0A")), out); + out = emit(prepend_string("PUSH_eax\t#", prepend_string(a->s, "\n")), out); return out; } @@ -746,26 +768,35 @@ struct token_list* process_if(struct token_list* out, struct token_list* functio char* number_string = numerate_number(if_count); if_count = if_count + 1; - out = emit(prepend_string("# IF_", number_string), out); + out = emit("# IF_", out); + out = emit(number_string, out); + out = emit("\n", out); global_token = global_token->next; - require_match("ERROR in process_if\nMISSING (\x0A", "("); + require_match("ERROR in process_if\nMISSING (\n", "("); out = expression(out, function); - out = emit(prepend_string("TEST\nJUMP_EQ %ELSE_", number_string), out); + out = emit("TEST\nJUMP_EQ %ELSE_", out); + out = emit(number_string, out); + out = emit("\n", out); - require_match("ERROR in process_if\nMISSING )\x0A", ")"); + require_match("ERROR in process_if\nMISSING )\n", ")"); out = statement(out, function); - out = emit(prepend_string("JUMP %_END_IF_", number_string), out); - out = emit(prepend_string(":ELSE_", number_string), out); + out = emit("JUMP %_END_IF_", out); + out = emit(number_string, out); + out = emit("\n:ELSE_", out); + out = emit(number_string, out); + out = emit("\n", out); if(match("else", global_token->s)) { global_token = global_token->next; out = statement(out, function); } - out = emit(prepend_string(":_END_IF_", number_string), out); + out = emit(":_END_IF_", out); + out = emit(number_string, out); + out = emit("\n", out); return out; } @@ -780,36 +811,50 @@ struct token_list* process_for(struct token_list* out, struct token_list* functi break_locals = function->locals; break_target = prepend_string("FOR_END_", number_string); - out = emit(prepend_string("# FOR_initialization_", number_string), out); + out = emit("# FOR_initialization_", out); + out = emit(number_string, out); + out = emit("\n", out); global_token = global_token->next; - require_match("ERROR in process_for\nMISSING (\x0A", "("); + require_match("ERROR in process_for\nMISSING (\n", "("); if(!match(";",global_token->s)) { out = expression(out, function); } - out = emit(prepend_string(":FOR_", number_string), out); + out = emit(":FOR_", out); + out = emit(number_string, out); + out = emit("\n", out); - require_match("ERROR in process_for\nMISSING ;1\x0A", ";"); + require_match("ERROR in process_for\nMISSING ;1\n", ";"); out = expression(out, function); - out = emit(prepend_string("TEST\nJUMP_EQ %FOR_END_", number_string), out); - out = emit(prepend_string("JUMP %FOR_THEN_", number_string), out); - out = emit(prepend_string(":FOR_ITER_", number_string), out); + out = emit("TEST\nJUMP_EQ %FOR_END_", out); + out = emit(number_string, out); + out = emit("\nJUMP %FOR_THEN_", out); + out = emit(number_string, out); + out = emit("\n:FOR_ITER_", out); + out = emit(number_string, out); + out = emit("\n", out); - require_match("ERROR in process_for\nMISSING ;2\x0A", ";"); + require_match("ERROR in process_for\nMISSING ;2\n", ";"); out = expression(out, function); - out = emit(prepend_string("JUMP %FOR_", number_string), out); - out = emit(prepend_string(":FOR_THEN_", number_string), out); + out = emit("JUMP %FOR_", out); + out = emit(number_string, out); + out = emit("\n:FOR_THEN_", out); + out = emit(number_string, out); + out = emit("\n", out); - require_match("ERROR in process_for\nMISSING )\x0A", ")"); + require_match("ERROR in process_for\nMISSING )\n", ")"); out = statement(out, function); - out = emit(prepend_string("JUMP %FOR_ITER_", number_string), out); - out = emit(prepend_string(":FOR_END_", number_string), out); + out = emit("JUMP %FOR_ITER_", out); + out = emit(number_string, out); + out = emit("\n:FOR_END_", out); + out = emit(number_string, out); + out = emit("\n", out); break_target = nested_break; break_locals = nested_locals; @@ -820,15 +865,15 @@ struct token_list* process_for(struct token_list* out, struct token_list* functi struct token_list* process_asm(struct token_list* out) { global_token = global_token->next; - require_match("ERROR in process_asm\nMISSING (\x0A", "("); + require_match("ERROR in process_asm\nMISSING (\n", "("); while(34 == global_token->s[0]) {/* 34 == " */ out = emit((global_token->s + 1), out); - out = emit("\x0A", out); + out = emit("\n", out); global_token = global_token->next; } - require_match("ERROR in process_asm\nMISSING )\x0A", ")"); - require_match("ERROR in process_asm\nMISSING ;\x0A", ";"); + require_match("ERROR in process_asm\nMISSING )\n", ")"); + require_match("ERROR in process_asm\nMISSING ;\n", ";"); return out; } @@ -844,19 +889,24 @@ struct token_list* process_do(struct token_list* out, struct token_list* functio break_locals = function->locals; break_target = prepend_string("DO_END_", number_string); - out = emit(prepend_string(":DO_", number_string), out); + out = emit(":DO_", out); + out = emit(number_string, out); + out = emit("\n", out); global_token = global_token->next; out = statement(out, function); - require_match("ERROR in process_do\nMISSING while\x0A", "while"); - require_match("ERROR in process_do\nMISSING (\x0A", "("); + require_match("ERROR in process_do\nMISSING while\n", "while"); + require_match("ERROR in process_do\nMISSING (\n", "("); out = expression(out, function); - require_match("ERROR in process_do\nMISSING )\x0A", ")"); - require_match("ERROR in process_do\nMISSING ;\x0A", ";"); + require_match("ERROR in process_do\nMISSING )\n", ")"); + require_match("ERROR in process_do\nMISSING ;\n", ";"); - out = emit(prepend_string("TEST\nJUMP_NE %DO_", number_string), out); - out = emit(prepend_string(":DO_END_", number_string), out); + out = emit("TEST\nJUMP_NE %DO_", out); + out = emit(number_string, out); + out = emit("\n:DO_END_", out); + out = emit(number_string, out); + out = emit("\n", out); break_locals = nested_locals; break_target = nested_break; @@ -877,20 +927,28 @@ struct token_list* process_while(struct token_list* out, struct token_list* func break_target = prepend_string("END_WHILE_", number_string); - out = emit(prepend_string(":WHILE_", number_string), out); + out = emit(":WHILE_", out); + out = emit(number_string, out); + out = emit("\n", out); global_token = global_token->next; - require_match("ERROR in process_while\nMISSING (\x0A", "("); + require_match("ERROR in process_while\nMISSING (\n", "("); out = expression(out, function); - out = emit(prepend_string("TEST\nJUMP_EQ %END_WHILE_", number_string), out); - out = emit(prepend_string("# THEN_while_", number_string), out); + out = emit("TEST\nJUMP_EQ %END_WHILE_", out); + out = emit(number_string, out); + out = emit("\n# THEN_while_", out); + out = emit(number_string, out); + out = emit("\n", out); - require_match("ERROR in process_while\nMISSING )\x0A", ")"); + require_match("ERROR in process_while\nMISSING )\n", ")"); out = statement(out, function); - out = emit(prepend_string("JUMP %WHILE_", number_string), out); - out = emit(prepend_string(":END_WHILE_", number_string), out); + out = emit("JUMP %WHILE_", out); + out = emit(number_string, out); + out = emit("\n:END_WHILE_", out); + out = emit(number_string, out); + out = emit("\n", out); break_locals = nested_locals; break_target = nested_break; @@ -903,14 +961,14 @@ struct token_list* return_result(struct token_list* out, struct token_list* func global_token = global_token->next; if(global_token->s[0] != ';') out = expression(out, function); - require_match("ERROR in return_result\nMISSING ;\x0A", ";"); + require_match("ERROR in return_result\nMISSING ;\n", ";"); struct token_list* i; for(i = function->locals; NULL != i; i = i->next) { - out = emit("POP_ebx\t# _return_result_locals\x0A", out); + out = emit("POP_ebx\t# _return_result_locals\n", out); } - out = emit("RETURN\x0A", out); + out = emit("RETURN\n", out); return out; } @@ -931,9 +989,9 @@ struct token_list* recursive_statement(struct token_list* out, struct token_list struct token_list* i; for(i = function->locals; frame != i; i = i->next) { - if(!match("RETURN\x0A", out->s)) + if(!match("RETURN\n", out->s)) { - out = emit( "POP_ebx\t# _recursive_statement_locals\x0A", out); + out = emit( "POP_ebx\t# _recursive_statement_locals\n", out); } function->locals = function->locals->next; } @@ -969,7 +1027,7 @@ struct token_list* statement(struct token_list* out, struct token_list* function else if(':' == global_token->s[0]) { out = emit(global_token->s, out); - out = emit("\t#C goto label\x0A", out); + out = emit("\t#C goto label\n", out); global_token = global_token->next; } else if((NULL == sym_lookup(global_token->s, function->locals)) && @@ -1002,9 +1060,9 @@ struct token_list* statement(struct token_list* out, struct token_list* function else if(match("goto", global_token->s)) { global_token = global_token->next; - out = emit(prepend_string("JUMP %", prepend_string(global_token->s, "\x0A")), out); + out = emit(prepend_string("JUMP %", prepend_string(global_token->s, "\n")), out); global_token = global_token->next; - require_match("ERROR in statement\nMissing ;\x0A", ";"); + require_match("ERROR in statement\nMissing ;\n", ";"); } else if(match("return", global_token->s)) { @@ -1022,17 +1080,23 @@ struct token_list* statement(struct token_list* out, struct token_list* function while(i != break_locals) { if(NULL == i) break; - out = emit("POP_ebx\t# break_cleanup_locals\x0A", out); + out = emit("POP_ebx\t# break_cleanup_locals\n", out); i = i->next; } global_token = global_token->next; - out = emit(prepend_string("JUMP %", prepend_string(break_target, "\x0A")), out); - require_match("ERROR in statement\nMissing ;\x0A", ";"); + out = emit(prepend_string("JUMP %", prepend_string(break_target, "\n")), out); + require_match("ERROR in statement\nMissing ;\n", ";"); + } + else if(match("continue", global_token->s)) + { + global_token = global_token->next; + out = emit("\n#continue statement\n",out); + require_match("ERROR in statement\nMissing ;\n", ";"); } else { out = expression(out, function); - require_match("ERROR in statement\nMISSING ;\x0A", ";"); + require_match("ERROR in statement\nMISSING ;\n", ";"); } return out; } @@ -1080,14 +1144,14 @@ struct token_list* declare_function(struct token_list* out, struct type* type) if(global_token->s[0] == ';') global_token = global_token->next; else { - out = emit(prepend_string("# Defining function ", prepend_string(essential, "\x0A")), out); - out = emit(prepend_string(":FUNCTION_", prepend_string(essential, "\x0A")), out); + out = emit(prepend_string("# Defining function ", prepend_string(essential, "\n")), out); + out = emit(prepend_string(":FUNCTION_", prepend_string(essential, "\n")), out); out = statement(out, func); /* Prevent duplicate RETURNS */ - if(!match("RETURN\x0A", out->s)) + if(!match("RETURN\n", out->s)) { - out = emit("RETURN\x0A", out); + out = emit("RETURN\n", out); } } return out; @@ -1137,8 +1201,8 @@ new_type: global_symbol_list = sym_declare(global_token->prev->s, type_size, global_symbol_list); /* Ensure 4 bytes are allocated for the global */ - globals_list = emit(prepend_string(":GLOBAL_", prepend_string(global_token->prev->s, "\x0A")), globals_list); - globals_list = emit("NOP\x0A", globals_list); + globals_list = emit(prepend_string(":GLOBAL_", prepend_string(global_token->prev->s, "\n")), globals_list); + globals_list = emit("NOP\n", globals_list); global_token = global_token->next; } @@ -1147,7 +1211,7 @@ new_type: { file_print("Recieved ", stderr); file_print(global_token->s, stderr); - file_print(" in program\x0A", stderr); + file_print(" in program\n", stderr); line_error(); exit(EXIT_FAILURE); } diff --git a/cc_reader.c b/cc_reader.c index 4a24cfa..6dcf089 100644 --- a/cc_reader.c +++ b/cc_reader.c @@ -42,8 +42,13 @@ char consume_byte(struct token_list* current, char c) char consume_word(struct token_list* current, char c, char frequent) { - c = consume_byte(current, c); - while(c != frequent) c = consume_byte(current, c); + int escape = FALSE; + do + { + if(!escape && '\\' == c ) escape = TRUE; + else escape = FALSE; + c = consume_byte(current, c); + } while(escape || (c != frequent)); return fgetc(input); } diff --git a/cc_strings.c b/cc_strings.c index 24b6b1f..81f7fbd 100644 --- a/cc_strings.c +++ b/cc_strings.c @@ -19,6 +19,7 @@ #include struct token_list* emit(char *s, struct token_list* head); +int char2hex(int c); char upcase(char a) { @@ -30,30 +31,21 @@ char upcase(char a) return a; } -int hex(int c, int high) +int hexify(int c, int high) { - if (c >= '0' && c <= '9') - { - c = (c - 48); - } - else if (c >= 'a' && c <= 'z') - { - c = (c - 87); - } - else if (c >= 'A' && c <= 'Z') - { - c = (c - 55); - } - else + int i = char2hex(c); + + if(0 > i) { + file_print("Tried to print non-hex number\n", stderr); exit(EXIT_FAILURE); } if(high) { - c = c << 4; + i = i << 4; } - return c; + return i; } int weird(char* string) @@ -65,6 +57,16 @@ int weird(char* string) { if('0' == string[2]) return TRUE; else if('1' == string[2]) return TRUE; + else if('2' == string[2]) + { + if('2' == string[3]) return TRUE; + else return weird(string+3); + } + else if('3' == string[2]) + { + if('A' == string[3]) return TRUE; + else return weird(string+3); + } else if('8' == string[2]) return TRUE; else if('9' == string[2]) return TRUE; else if('a' == string[2]) return TRUE; @@ -83,12 +85,14 @@ int weird(char* string) } else if('n' == string[1]) { + if(':' == string[2]) return TRUE; return weird(string+2); } else if('t' == string[1]) { return weird(string+2); } + else if('"' == string[1]) return TRUE; else { return weird(string+3); @@ -97,6 +101,28 @@ int weird(char* string) return weird(string+1); } +/* Lookup escape values */ +int escape_lookup(char* c) +{ + if((c[0] == '\\') & (c[1] == 'x')) + { + int t1 = hexify(c[2], TRUE); + int t2 = hexify(c[3], FALSE); + return t1 + t2; + } + else if((c[0] == '\\') & (c[1] == 'n')) return 10; + else if((c[0] == '\\') & (c[1] == 't')) return 9; + else if((c[0] == '\\') & (c[1] == '\\')) return 92; + else if((c[0] == '\\') & (c[1] == '\'')) return 39; + else if((c[0] == '\\') & (c[1] == '"')) return 34; + else if((c[0] == '\\') & (c[1] == 'r')) return 13; + + file_print("Unknown escape recieved: ", stderr); + file_print(c, stderr); + file_print(" Unable to process\n", stderr); + exit(EXIT_FAILURE); +} + /* Deal with human strings */ char* collect_regular_string(char* string) { @@ -110,19 +136,12 @@ char* collect_regular_string(char* string) { if((string[j] == '\\') & (string[j + 1] == 'x')) { - int t1 = hex(string[j + 2], TRUE); - int t2 = hex(string[j + 3], FALSE); - message[i] = t1 + t2; + message[i] = escape_lookup(string + j); j = j + 4; } - else if((string[j] == '\\') & (string[j + 1] == 'n')) + else if(string[j] == '\\') { - message[i] = 10; - j = j + 2; - } - else if((string[j] == '\\') & (string[j + 1] == 't')) - { - message[i] = 9; + message[i] = escape_lookup(string + j); j = j + 2; } else @@ -193,6 +212,6 @@ char* collect_weird_string(char* string) char* parse_string(char* string) { /* the string */ - if(weird(string)) return collect_weird_string(string); + if((weird(string)) || ':' == string[1]) return collect_weird_string(string); else return collect_regular_string(string); } diff --git a/cc_types.c b/cc_types.c index e0d9094..7383cf5 100644 --- a/cc_types.c +++ b/cc_types.c @@ -70,7 +70,16 @@ void initialize_types() /* FUNCTION* has the same properties as FUNCTION */ e->indirect = e; + /* Define FUNCTION */ + struct type* f = calloc(1, sizeof(struct type)); + f->name = "unsigned"; + f->size = 4; + f->type = f; + /* unsigned* has the same properties as unsigned */ + f->indirect = f; + /* Finalize type list */ + e->next = f; d->next = e; c->next = d; a->next = c; diff --git a/test/functions/calloc.c b/test/functions/calloc.c index 0ef3c40..bff961f 100644 --- a/test/functions/calloc.c +++ b/test/functions/calloc.c @@ -14,6 +14,7 @@ * You should have received a copy of the GNU General Public License * along with stage0. If not, see . */ +// void* malloc(int size); void* memset(void* ptr, int value, int num) { diff --git a/test/functions/numerate_number.c b/test/functions/numerate_number.c index 77a2b1c..157573f 100644 --- a/test/functions/numerate_number.c +++ b/test/functions/numerate_number.c @@ -16,11 +16,15 @@ */ #include #include +// void* calloc(int count, int size); +#define TRUE 1 +//CONSTANT TRUE 1 +#define FALSE 0 +//CONSTANT FALSE 0 char* numerate_number(int a) { - char* result = malloc(16); - memset(result, 0, 16); + char* result = calloc(16, sizeof(char)); int i = 0; /* Deal with Zero case */ @@ -53,6 +57,93 @@ char* numerate_number(int a) i = i + 1; } - result[i] = 10; return result; } + +int char2hex(int c) +{ + if (c >= '0' && c <= '9') return (c - 48); + else if (c >= 'a' && c <= 'f') return (c - 87); + else if (c >= 'A' && c <= 'F') return (c - 55); + else return -1; +} + +int hex2char(int c) +{ + if((c >= 0) && (c <= 9)) return (c + 48); + else if((c >= 10) && (c <= 15)) return (c + 55); + else return -1; +} + +int char2dec(int c) +{ + if (c >= '0' && c <= '9') return (c - 48); + else return -1; +} + +int dec2char(int c) +{ + if((c >= 0) && (c <= 9)) return (c + 48); + else return -1; +} + +int numerate_string(char *a) +{ + int count = 0; + int index; + int negative; + + /* If NULL string */ + if(0 == a[0]) + { + return 0; + } + /* Deal with hex */ + else if (a[0] == '0' && a[1] == 'x') + { + if('-' == a[2]) + { + negative = TRUE; + index = 3; + } + else + { + negative = FALSE; + index = 2; + } + + while(0 != a[index]) + { + if(-1 == char2hex(a[index])) return 0; + count = (16 * count) + char2hex(a[index]); + index = index + 1; + } + } + /* Deal with decimal */ + else + { + if('-' == a[0]) + { + negative = TRUE; + index = 1; + } + else + { + negative = FALSE; + index = 0; + } + + while(0 != a[index]) + { + if(-1 == char2dec(a[index])) return 0; + count = (10 * count) + char2dec(a[index]); + index = index + 1; + } + } + + if(negative) + { + count = count * -1; + } + return count; +} diff --git a/test/functions/stat.c b/test/functions/stat.c new file mode 100644 index 0000000..001f3b3 --- /dev/null +++ b/test/functions/stat.c @@ -0,0 +1,50 @@ +## Copyright (C) 2016 Jeremiah Orians +## This file is part of stage0. +## +## stage0 is free software: you an redistribute it and/or modify +## it under the terms of the GNU General Public License as published by +## the Free Software Foundation, either version 3 of the License, or +## (at your option) any later version. +## +## stage0 is distributed in the hope that it will be useful, +## but WITHOUT ANY WARRANTY; without even the implied warranty of +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +## GNU General Public License for more details. +## +## You should have received a copy of the GNU General Public License +## along with stage0. If not, see . + +/* + * chmod() changes the mode of the file specified whose pathname is given in + * pathname, which is dereferenced if it is a symbolic link. + * fchmod() changes the mode of the file referred to by the open file + * descriptor fd. + * The new file mode is specified in mode, which is a bit mask created by + * ORing together zero or more of the following: + * S_ISUID (04000) set-user-ID (set process effective user ID on execve(2)) + * S_ISGID (02000) set-group-ID (set process effective group ID on execve(2) + * mandatory locking, as described in fcntl(2); take a new file's group from + * parent directory, as described in chown(2) and mkdir(2)) + * S_ISVTX (01000) sticky bit (restricted deletion flag, as described in + * unlink(2)) + * S_IRUSR (00400) read by owner + * S_IWUSR (00200) write by owner + * S_IXUSR (00100) execute/search by owner ("search" applies for directories + * , and means that entries within the directory can be accessed) + * S_IRGRP (00040) read by group + * S_IWGRP (00020) write by group + * S_IXGRP (00010) execute/search by group + * S_IROTH (00004) read by others + * S_IWOTH (00002) write by others + * S_IXOTH (00001) execute/search by others + */ + +int chmod(char *pathname, int mode) +{ + asm("LOAD_EFFECTIVE_ADDRESS_ebx %8" + "LOAD_INTEGER_ebx" + "LOAD_EFFECTIVE_ADDRESS_ecx %4" + "LOAD_INTEGER_ecx" + "LOAD_IMMEDIATE_eax %15" + "INT_80"); +} diff --git a/test/functions/string.c b/test/functions/string.c index 488437a..b3ce349 100644 --- a/test/functions/string.c +++ b/test/functions/string.c @@ -16,6 +16,7 @@ */ #include #define MAX_STRING 4096 +//CONSTANT MAX_STRING 4096 char* copy_string(char* target, char* source) { @@ -50,3 +51,10 @@ char* prepend_string(char* add, char* base) copy_string(copy_string(ret, add), base); return ret; } + +int string_length(char* a) +{ + int i = 0; + while(0 != a[i]) i = i + 1; + return i; +} diff --git a/test/test.answers b/test/test.answers index d4a5195..2bc59e9 100644 --- a/test/test.answers +++ b/test/test.answers @@ -9,7 +9,7 @@ d27eb315d694324650b11a421d6990eee60ac5921a5625bbccb43d806f09e156 test/results/t 8cc38294fb1261843cfc3956fad5a451c95bbc2ed687435d4e2d59df2c4a8567 test/results/test08-binary cc8f252877a85c0d7832094ff574d7173ac33940917bc1591358b8970651a81c test/results/test09-binary 3857aee4183de41bd00b014d616a5d73f4bfc57aa60a6073bb4113d6ff2fb8d5 test/results/test10-binary -cde9093d770a2c9c4b76953006468da02a68d3b5895e6e4a2842bf72b99a3e1b test/results/test100-binary +3a807e11ca778b882e11f301b44833124e820f8012d74a1fe56b909b3b52adec test/results/test100-binary dce2f0b35323cf6a2b01f74a9335100f2d8626028af545832dbdb503573db0e5 test/results/test11-binary 88602970fa07b5da7a42b4f2b2486fe03accc6796e05453c4ab934e986790bef test/results/test12-binary c85a57b5b1d65288efd47a3b12c6fca1efade9e7ec91e65efda5531d2c40d293 test/results/test13-binary @@ -18,6 +18,6 @@ ca2c1321cbcbf3f551860fc0857d0a816660ba541987f9ed7f92f8553cd6b06b test/results/t 7b0ae42a9ac9e8387900c1a95b3310e9c7fbe4f244d8d7522285dc1cef2f38ec test/results/test16-binary 15f1fc51d559b74d7515d3e978a835f7edc765f0763fdbae328f4b03a6b2b92b test/results/test17-binary 6405e331d3626c0ed1eca16eecc7fb628d8e1dc54dff3a6106e5f5bb063c896c test/results/test18-binary -3beeba3bdf2d0b8a8eb2f113d35c3a79a04dcb4330f97fad817f0c484b7c7b70 test/results/test19-binary +33f7802c581d3b6382a1b63211564529419769a9788b5a5cac856e45b9eac57c test/results/test19-binary 6fa44153ee3f27f0df49b282c0bb3017dbfaea906073c8c02b8bf5ad4d4a7860 test/results/test20-binary ba3d9623c6512bc327cf934d994e5327e5fad3f7500896e2d8458467fae9b9e9 test/results/test99-binary diff --git a/test/test100/proof.answer b/test/test100/proof.answer index 97d0824..c279db7 100644 --- a/test/test100/proof.answer +++ b/test/test100/proof.answer @@ -1 +1 @@ -5fd665e662487bed6c1f52b9f702e4859da01811b6399ff1faa952fcf38ba163 test/test100/proof +f8d4a2a3c5c46005374f9b4485517dd109437a53bf3e24622897af37c9735d31 test/test100/proof diff --git a/test/test19/getopt.c b/test/test19/getopt.c index ea2e656..cf49f4c 100644 --- a/test/test19/getopt.c +++ b/test/test19/getopt.c @@ -47,6 +47,7 @@ void sum_file(FILE* input, FILE* output) } write_string(numerate_number(sum), output); + fputc(10, output); } int match(char* a, char* b);