From 32e1f700bc5a9c53148b22df518faa6cd3f606b9 Mon Sep 17 00:00:00 2001 From: Jeremiah Orians Date: Wed, 8 Nov 2017 18:05:54 -0500 Subject: [PATCH] Isolated global_token to cc.c and added FOR Loop support along with example --- cc.c | 59 ++++++++++++++++++++++++++++++++++++++++++++------ cc.h | 7 ------ cc_reader.c | 18 ++++++++++----- cc_strings.c | 20 ++++++++--------- example/for.c | 36 ++++++++++++++++++++++++++++++ example/for.sh | 22 +++++++++++++++++++ 6 files changed, 133 insertions(+), 29 deletions(-) create mode 100644 example/for.c create mode 100755 example/for.sh diff --git a/cc.c b/cc.c index c1f1e9e..75b5f4e 100644 --- a/cc.c +++ b/cc.c @@ -18,20 +18,26 @@ #include "cc.h" #include + +#define GLOBAL 1 +#define FUNCTION 2 +#define LOCAL_VARIABLE 4 +#define ARGUEMENT 8 + /* Globals */ struct token_list* global_symbol_list; struct token_list* global_stack; +struct token_list* global_token; /* Imported functions */ int asprintf(char **strp, const char *fmt, ...); -void read_all_tokens(char* source_file); +struct token_list* read_all_tokens(char* source_file); struct token_list* emit(char *s, bool hands_off, struct token_list* head) { struct token_list* t = calloc(1, sizeof(struct token_list)); t->next = head; t->hands_off = hands_off; - head = t; t->s = s; return t; } @@ -141,7 +147,7 @@ void require_char(char* message, char required) } struct token_list* expression(struct token_list* out); -struct token_list* parse_string(struct token_list* out); +struct token_list* parse_string(struct token_list* output_list, char* string); /* * primary-expr: @@ -178,7 +184,7 @@ struct token_list* primary_expr(struct token_list* out) } else if(global_token->s[0] == '"') { - out = parse_string(out); + out = parse_string(out, global_token->s); global_token = global_token->next; } else exit(EXIT_FAILURE); @@ -471,6 +477,44 @@ struct token_list* process_if(struct token_list* out) return out; } +int for_count; +struct token_list* process_for(struct token_list* out) +{ + char* label; + int number = for_count; + for_count = for_count + 1; + + asprintf(&label, "# FOR_initialization_%d\n", number); + out = emit(label, true, out); + + global_token = global_token->next; + + require_char("ERROR in process_for\nMISSING (\n", '('); + out = expression(out); + + asprintf(&label, ":FOR_%d\n", number); + out = emit(label, true, out); + + require_char("ERROR in process_for\nMISSING ;1\n", ';'); + out = expression(out); + + asprintf(&label, "TEST\nJUMP_EQ %c%s_%d\nJUMP %c%s_%d\n:FOR_ITER_%d\n", 37, "FOR_END", number, 37, "FOR_THEN", number, number); + out = emit(label, true, out); + + require_char("ERROR in process_for\nMISSING ;2\n", ';'); + out = expression(out); + + asprintf(&label, "JUMP %c%s_%d\n:FOR_THEN_%d\n", 37, "FOR", number, number); + out = emit(label, true, out); + + require_char("ERROR in process_for\nMISSING )\n", ')'); + out = statement(out); + + asprintf(&label, "JUMP %c%s_ITER_%d\n:FOR_END_%d\n", 37, "FOR", number, number); + out = emit(label, true, out); + return out; +} + /* Process while loops */ int while_count; struct token_list* process_while(struct token_list* out) @@ -533,6 +577,7 @@ struct token_list* recursive_statement(struct token_list* out) * if ( expression ) statement * if ( expression ) statement else statement * while ( expression ) statement + * for ( expression ; expression ; expression ) statement * return ; * expr ; */ @@ -542,6 +587,7 @@ struct token_list* statement(struct token_list* out) else if((!strcmp(global_token->s, "char")) | (!strcmp(global_token->s, "int"))) out = collect_local(out); else if(!strcmp(global_token->s, "if")) out = process_if(out); else if(!strcmp(global_token->s, "while")) out = process_while(out); + else if(!strcmp(global_token->s, "for")) out = process_for(out); else if(!strcmp(global_token->s, "return")) out = return_result(out); else { @@ -586,8 +632,7 @@ struct token_list* declare_global(struct token_list* out) sym_declare(global_token->prev->s, GLOBAL); global_token = global_token->next; - out = emit("NOP\n", true, out); - return out; + return emit("NOP\n", true, out); } struct token_list* declare_function(struct token_list* out) @@ -674,7 +719,7 @@ int main(int argc, char **argv) exit(EXIT_FAILURE); } - read_all_tokens(argv[1]); + global_token = read_all_tokens(argv[1]); struct token_list* output_list = program(NULL); FILE* output = fopen(argv[2], "w"); recursive_output(output, output_list); diff --git a/cc.h b/cc.h index c7b970c..d0ef667 100644 --- a/cc.h +++ b/cc.h @@ -20,11 +20,6 @@ #include #include -#define GLOBAL 1 -#define FUNCTION 2 -#define LOCAL_VARIABLE 4 -#define ARGUEMENT 8 - struct token_list { struct token_list* next; @@ -41,5 +36,3 @@ struct token_list bool hands_off; }; }; - -struct token_list* global_token; diff --git a/cc_reader.c b/cc_reader.c index 6b86b42..bc6d527 100644 --- a/cc_reader.c +++ b/cc_reader.c @@ -17,6 +17,7 @@ #include "cc.h" FILE* input; +struct token_list* token; char clearWhiteSpace(char c) { @@ -39,8 +40,15 @@ char consume_word(struct token_list* current, char c, char frequent) return consume_byte(current, c); } +char purge_macro(int ch) +{ + while(10 != ch) ch = fgetc(input); + return ch; +} + int get_token(int c) { + if('#' == c) c = purge_macro(c); bool w = true; struct token_list* current = calloc(1, sizeof(struct token_list)); @@ -77,9 +85,9 @@ int get_token(int c) } } - current->prev = global_token; - current->next = global_token; - global_token = current; + current->prev = token; + current->next = token; + token = current; return c; } @@ -96,11 +104,11 @@ struct token_list* reverse_list(struct token_list* head) return root; } -void read_all_tokens(char* source_file) +struct token_list* read_all_tokens(char* source_file) { input = fopen(source_file, "r"); int ch =fgetc(input); while(EOF != ch) ch = get_token(ch); - global_token = reverse_list(global_token); + return reverse_list(token); } diff --git a/cc_strings.c b/cc_strings.c index 1adf3b7..7985bb9 100644 --- a/cc_strings.c +++ b/cc_strings.c @@ -67,7 +67,7 @@ bool weird(char c) /* Parse string to deal with hex characters*/ 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) +struct token_list* parse_string(struct token_list* output_list, char* string) { char* label; static int string_num; @@ -79,25 +79,25 @@ struct token_list* parse_string(struct token_list* output_list) bool hexit = false; message[0] = '"'; - while(global_token->s[j] != '"') + while(string[j] != '"') { hold[k] = ' '; - if((global_token->s[j] == 92) & (global_token->s[j + 1] == 'x')) + if((string[j] == 92) & (string[j + 1] == 'x')) { - hold[k + 1] = upcase(global_token->s[j + 2]); - hold[k + 2] = upcase(global_token->s[j + 3]); - int t1 = hex(global_token->s[j + 2], true); - int t2 = hex(global_token->s[j + 3], false); + hold[k + 1] = upcase(string[j + 2]); + hold[k + 2] = upcase(string[j + 3]); + int t1 = hex(string[j + 2], true); + int t2 = hex(string[j + 3], false); message[i] = t1 + t2; if(weird(message[i])) hexit = true; j = j + 4; } else { - hold[k + 1] = table[(global_token->s[j] >> 4)]; - hold[k + 2] = table[(global_token->s[j] & 15)]; - message[i] = global_token->s[j]; + hold[k + 1] = table[(string[j] >> 4)]; + hold[k + 2] = table[(string[j] & 15)]; + message[i] = string[j]; j = j + 1; } diff --git a/example/for.c b/example/for.c new file mode 100644 index 0000000..4b398e1 --- /dev/null +++ b/example/for.c @@ -0,0 +1,36 @@ +/* Copyright (C) 2016 Jeremiah Orians + * This file is part of stage0. + * + * stage0 is free software: you can 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 . + */ + +#include +int putchar(int); + +int main() +{ + int max = 90; + int i; + int j; + for(i = 65; i <= max; i = i + 1) + { + putchar(i); + for(j = i + 1; j <= max; j = j + 1) + { + putchar(j); + } + putchar(10); + } + return 0; +} diff --git a/example/for.sh b/example/for.sh new file mode 100755 index 0000000..0779986 --- /dev/null +++ b/example/for.sh @@ -0,0 +1,22 @@ +#!/bin/bash +## 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 . + +# example for compiling example For loop test +M2-Planet for.c for.o +M1-Macro -f x86_defs.M1 -f for.o --LittleEndian --Architecture 1 -o for.hex2 +hex2-linker -f cc_lib.hex2 -f for.hex2 --LittleEndian --Architecture 1 --BaseAddress 0x8048000 -o for --exec_enable +./for