Moved strings to the bottom of the output

This commit is contained in:
Jeremiah Orians 2017-12-14 17:01:30 -05:00
parent b994d05d7d
commit e25401c0b8
No known key found for this signature in database
GPG Key ID: 7457821534D2ACCD
3 changed files with 51 additions and 76 deletions

105
cc.c
View File

@ -28,6 +28,7 @@
struct token_list* global_symbol_list; struct token_list* global_symbol_list;
struct token_list* global_token; struct token_list* global_token;
struct token_list* current_target; struct token_list* current_target;
struct token_list* strings;
/* Imported functions */ /* Imported functions */
int asprintf(char **strp, const char *fmt, ...); int asprintf(char **strp, const char *fmt, ...);
@ -42,36 +43,6 @@ struct token_list* emit(char *s, bool hands_off, struct token_list* head)
return t; return t;
} }
struct token_list* pull_value_off_stack(int register_number, struct token_list* out, char* s)
{
char* label;
if(0 == register_number) asprintf(&label, "POP_eax\t# %s\n", s);
else if(1 == register_number) asprintf(&label, "POP_ebx\t# %s\n", s);
else
{
fprintf(stderr, "%d is not a valid register number\n", register_number);
exit(EXIT_FAILURE);
}
out = emit(label, true, out);
return out;
}
struct token_list* put_value_on_stack(int register_number, struct token_list* out, char* s)
{
char* label;
if(0 == register_number) asprintf(&label, "PUSH_eax\t#%s\n", s);
else if(1 == register_number) asprintf(&label, "PUSH_ebx\n\t#%s\n", s);
else
{
fprintf(stderr, "%d is not a valid register number\n", register_number);
exit(EXIT_FAILURE);
}
out = emit(label, true, out);
return out;
}
struct token_list* sym_declare(char *s, int type, struct type* size) struct token_list* sym_declare(char *s, int type, struct type* size)
{ {
struct token_list* a = calloc(1, sizeof(struct token_list)); struct token_list* a = calloc(1, sizeof(struct token_list));
@ -132,12 +103,7 @@ struct token_list* sym_get_value(char *s, struct token_list* out, struct token_l
case GLOBAL: asprintf(&label, "LOAD_IMMEDIATE_eax &GLOBAL_%s\n", s); break; case GLOBAL: asprintf(&label, "LOAD_IMMEDIATE_eax &GLOBAL_%s\n", s); break;
case LOCAL_VARIABLE: asprintf(&label, "LOAD_EFFECTIVE_ADDRESS %c%d\n", 37, 4 * stack_index(a, function)); break; case LOCAL_VARIABLE: asprintf(&label, "LOAD_EFFECTIVE_ADDRESS %c%d\n", 37, 4 * stack_index(a, function)); break;
case ARGUEMENT: asprintf(&label, "LOAD_EFFECTIVE_ADDRESS %c%d\n", 37, 4 * (stack_index(a, function))); break; case ARGUEMENT: asprintf(&label, "LOAD_EFFECTIVE_ADDRESS %c%d\n", 37, 4 * (stack_index(a, function))); break;
case FUNCTION: case FUNCTION: return out;
{
/* Make space for function */
function->temps = function->temps - 1;
return out;
}
default: exit(EXIT_FAILURE); default: exit(EXIT_FAILURE);
} }
out = emit(label, true, out); out = emit(label, true, out);
@ -185,7 +151,7 @@ struct token_list* primary_expr(struct token_list* out, struct token_list* funct
out = expression(out, function); out = expression(out, function);
require_char("Error in Primary expression\nDidn't get )\n", ')'); require_char("Error in Primary expression\nDidn't get )\n", ')');
} }
else if((global_token->s[0] == 39) & (global_token->s[1] != 0) & (global_token->s[2] == 39) & (global_token->s[3] == 0)) else if(global_token->s[0] == '\'')
{ {
asprintf(&label, "LOAD_IMMEDIATE_eax %c%d\n", 37, global_token->s[1]); asprintf(&label, "LOAD_IMMEDIATE_eax %c%d\n", 37, global_token->s[1]);
out = emit(label, true, out); out = emit(label, true, out);
@ -193,8 +159,19 @@ struct token_list* primary_expr(struct token_list* out, struct token_list* funct
} }
else if(global_token->s[0] == '"') else if(global_token->s[0] == '"')
{ {
out = parse_string(out, global_token->s); static int string_num;
asprintf(&label, "LOAD_IMMEDIATE_eax &STRING_%d\n", string_num);
out = emit(label, true, out);
/* The target */
asprintf(&label, ":STRING_%d\n", string_num);
strings = emit(label, true, strings);
/* Parse the string */
strings = parse_string(strings, global_token->s);
global_token = global_token->next; global_token = global_token->next;
string_num = string_num + 1;
} }
else exit(EXIT_FAILURE); else exit(EXIT_FAILURE);
@ -207,19 +184,21 @@ struct token_list* process_expression_list(struct token_list* out, struct token_
struct token_list* func = sym_lookup(global_token->prev->s, global_symbol_list); struct token_list* func = sym_lookup(global_token->prev->s, global_symbol_list);
global_token = global_token->next; global_token = global_token->next;
int temp = function->temps; int temp = function->temps;
function->temps = function->temps + 1;
if(global_token->s[0] != ')') if(global_token->s[0] != ')')
{ {
char* label;
out = expression(out, function); out = expression(out, function);
out = put_value_on_stack(0, out, "_process_expression1"); asprintf(&label, "PUSH_eax\t#%s\n", "_process_expression1");
out = emit(label, true, out);
function->temps = function->temps + 1; function->temps = function->temps + 1;
while(global_token->s[0] == ',') while(global_token->s[0] == ',')
{ {
global_token = global_token->next; global_token = global_token->next;
out = expression(out, function); out = expression(out, function);
out = put_value_on_stack(0, out, "_process_expression2"); asprintf(&label, "PUSH_eax\t#%s\n", "_process_expression2");
out = emit(label, true, out);
function->temps = function->temps + 1; function->temps = function->temps + 1;
} }
require_char("ERROR in process_expression_list\nNo ) was found\n", ')'); require_char("ERROR in process_expression_list\nNo ) was found\n", ')');
@ -233,23 +212,24 @@ struct token_list* process_expression_list(struct token_list* out, struct token_
for(struct token_list* i = func->arguments; NULL != i; i = i->arguments) for(struct token_list* i = func->arguments; NULL != i; i = i->arguments)
{ {
out = pull_value_off_stack(1, out, "_process_expression_locals"); asprintf(&label, "POP_ebx\t# %s\n", "_process_expression_locals");
out = emit(label, true, out);
} }
/* Pull off function pointer */
function->temps = function->temps + 1;
return out; return out;
} }
struct token_list* common_recursion(struct token_list* (*function) (struct token_list*, struct token_list*), struct token_list* out, struct token_list* func) struct token_list* common_recursion(struct token_list* (*function) (struct token_list*, struct token_list*), struct token_list* out, struct token_list* func)
{ {
char* label;
global_token = global_token->next; global_token = global_token->next;
out = put_value_on_stack(0, out, "_common_recursion"); asprintf(&label, "PUSH_eax\t#%s\n", "_common_recursion");
out = emit(label, true, out);
func->temps = func->temps + 1; func->temps = func->temps + 1;
out = function(out, func); out = function(out, func);
func->temps = func->temps - 1; func->temps = func->temps - 1;
out = pull_value_off_stack(1, out, "_common_recursion"); asprintf(&label, "POP_ebx\t# %s\n", "_common_recursion");
out = emit(label, true, out);
return out; return out;
} }
@ -340,13 +320,17 @@ struct token_list* shift_expr(struct token_list* out, struct token_list* functio
{ {
out = common_recursion(additive_expr, out, function); out = common_recursion(additive_expr, out, function);
// Ugly hack to Work around flaw in x86 // Ugly hack to Work around flaw in x86
out = emit("COPY_eax_to_ecx\nPOP_eax\nSAL_eax_cl\n", true, out->next); struct token_list* old = out->next;
free(out);
out = emit("COPY_eax_to_ecx\nPOP_eax\nSAL_eax_cl\n", true, old);
} }
else if(!strcmp(global_token->s, ">>")) else if(!strcmp(global_token->s, ">>"))
{ {
out = common_recursion(additive_expr, out, function); out = common_recursion(additive_expr, out, function);
// Ugly hack to Work around flaw in x86 // Ugly hack to Work around flaw in x86
out = emit("COPY_eax_to_ecx\nPOP_eax\nSAR_eax_cl\n", true, out->next); struct token_list* old = out->next;
free(out);
out = emit("COPY_eax_to_ecx\nPOP_eax\nSAR_eax_cl\n", true, old);
} }
else else
{ {
@ -520,7 +504,8 @@ struct token_list* collect_local(struct token_list* out, struct token_list* func
function->temps = function->temps + 1; function->temps = function->temps + 1;
require_char("ERROR in collect_local\nMissing ;\n", ';'); require_char("ERROR in collect_local\nMissing ;\n", ';');
out = put_value_on_stack(0, out, a->s); asprintf(&label, "PUSH_eax\t#%s\n", a->s);
out = emit(label, true, out);
return out; return out;
} }
@ -605,10 +590,8 @@ struct token_list* process_asm(struct token_list* out)
require_char("ERROR in process_asm\nMISSING (\n", '('); require_char("ERROR in process_asm\nMISSING (\n", '(');
while('"' == global_token->s[0]) while('"' == global_token->s[0])
{ {
int i;
for(i = 0; 0 != global_token->s[i]; i = i + 1);
global_token->s[i-1] = 10;
out = emit((global_token->s + 1), true, out); out = emit((global_token->s + 1), true, out);
out = emit("\n", true, out);
global_token = global_token->next; global_token = global_token->next;
} }
require_char("ERROR in process_asm\nMISSING )\n", ')'); require_char("ERROR in process_asm\nMISSING )\n", ')');
@ -653,7 +636,9 @@ struct token_list* return_result(struct token_list* out, struct token_list* func
for(struct token_list* i = function->locals; NULL != i; i = i->locals) for(struct token_list* i = function->locals; NULL != i; i = i->locals)
{ {
out = pull_value_off_stack(1, out, "_return_result_locals"); char* label;
asprintf(&label, "POP_ebx\t# %s\n", "_return_result_locals");
out = emit(label, true, out);
function->locals = function->locals->locals; function->locals = function->locals->locals;
} }
out = emit("RETURN\n", true, out); out = emit("RETURN\n", true, out);
@ -676,7 +661,9 @@ struct token_list* recursive_statement(struct token_list* out, struct token_list
{ {
for(struct token_list* i = function->locals; frame != i; i = i->locals) for(struct token_list* i = function->locals; frame != i; i = i->locals)
{ {
out = pull_value_off_stack(1, out, "_recursive_statement_locals"); char* label;
asprintf(&label, "POP_ebx\t# %s\n", "_recursive_statement_locals");
out = emit(label, true, out);
function->locals = function->locals->locals; function->locals = function->locals->locals;
} }
} }
@ -787,10 +774,7 @@ struct token_list* declare_function(struct token_list* out, struct type* type)
global_token = global_token->next; global_token = global_token->next;
} }
for( struct token_list* i = global_symbol_list; current != i; i = i->next) global_symbol_list = current;
{
global_symbol_list = i;
}
return out; return out;
} }
@ -840,6 +824,7 @@ void recursive_output(FILE* out, struct token_list* i)
} }
fprintf(out, "'\t# NONE\n"); fprintf(out, "'\t# NONE\n");
} }
free(i);
} }
/* Our essential organizer */ /* Our essential organizer */
@ -855,6 +840,8 @@ int main(int argc, char **argv)
struct token_list* output_list = program(NULL); struct token_list* output_list = program(NULL);
FILE* output = fopen(argv[2], "w"); FILE* output = fopen(argv[2], "w");
recursive_output(output, output_list); recursive_output(output, output_list);
fprintf(output, "\n# Program strings\n\n");
recursive_output(output, strings);
fclose(output); fclose(output);
return 0; return 0;
} }

View File

@ -37,7 +37,7 @@ char consume_word(struct token_list* current, char c, char frequent)
{ {
c = consume_byte(current, c); c = consume_byte(current, c);
while(c != frequent) c = consume_byte(current, c); while(c != frequent) c = consume_byte(current, c);
return consume_byte(current, c); return fgetc(input);
} }
char purge_macro(int ch) char purge_macro(int ch)

View File

@ -69,8 +69,6 @@ bool weird(char c)
char table[16] = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46}; char table[16] = {0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46};
struct token_list* parse_string(struct token_list* output_list, char* string) struct token_list* parse_string(struct token_list* output_list, char* string)
{ {
char* label;
static int string_num;
int i = 1; int i = 1;
int j = 1; int j = 1;
int k = 0; int k = 0;
@ -79,11 +77,11 @@ struct token_list* parse_string(struct token_list* output_list, char* string)
bool hexit = false; bool hexit = false;
message[0] = '"'; message[0] = '"';
while(string[j] != '"') while(string[j] != 0)
{ {
hold[k] = ' '; hold[k] = ' ';
if((string[j] == 92) & (string[j + 1] == 'x')) if((string[j] == '\\') & (string[j + 1] == 'x'))
{ {
hold[k + 1] = upcase(string[j + 2]); hold[k + 1] = upcase(string[j + 2]);
hold[k + 2] = upcase(string[j + 3]); hold[k + 2] = upcase(string[j + 3]);
@ -111,27 +109,17 @@ struct token_list* parse_string(struct token_list* output_list, char* string)
message[i] = '"'; message[i] = '"';
message[i + 1] = '\n'; message[i + 1] = '\n';
/* call ... */
output_list = emit("CALL_IMMEDIATE ", true, output_list);
asprintf(&label, "%c_STRING_%d\n", 37, string_num);
output_list = emit(label, true, output_list);
/* the string */ /* the string */
if(hexit) if(hexit)
{ {
output_list = emit(hold, false, output_list); output_list = emit(hold, false, output_list);
free(message);
} }
else else
{ {
output_list = emit(message, true, output_list); output_list = emit(message, true, output_list);
free(hold);
} }
/* The target */
asprintf(&label, ":_STRING_%d\n", string_num);
output_list = emit(label, true, output_list);
/* The cleanup */
output_list = emit("POP_eax\n", true, output_list);
string_num = string_num + 1;
return output_list; return output_list;
} }