bug clean up and new functionality

This commit is contained in:
Jeremiah Orians 2018-06-01 20:05:27 -04:00
parent cba66b015b
commit 280b2ade52
No known key found for this signature in database
GPG Key ID: 7457821534D2ACCD
12 changed files with 445 additions and 180 deletions

View File

@ -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

354
cc_core.c
View File

@ -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);
}

View File

@ -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);
}

View File

@ -19,6 +19,7 @@
#include <stdint.h>
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);
}

View File

@ -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;

View File

@ -14,6 +14,7 @@
* You should have received a copy of the GNU General Public License
* along with stage0. If not, see <http://www.gnu.org/licenses/>.
*/
// void* malloc(int size);
void* memset(void* ptr, int value, int num)
{

View File

@ -16,11 +16,15 @@
*/
#include<stdlib.h>
#include<string.h>
// 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;
}

50
test/functions/stat.c Normal file
View File

@ -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 <http://www.gnu.org/licenses/>.
/*
* 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");
}

View File

@ -16,6 +16,7 @@
*/
#include<stdlib.h>
#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;
}

View File

@ -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

View File

@ -1 +1 @@
5fd665e662487bed6c1f52b9f702e4859da01811b6399ff1faa952fcf38ba163 test/test100/proof
f8d4a2a3c5c46005374f9b4485517dd109437a53bf3e24622897af37c9735d31 test/test100/proof

View File

@ -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);