Isolated global_token to cc.c and added FOR Loop support along with example
This commit is contained in:
parent
f3e3b6eb5b
commit
32e1f700bc
59
cc.c
59
cc.c
|
@ -18,20 +18,26 @@
|
||||||
#include "cc.h"
|
#include "cc.h"
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
|
|
||||||
|
|
||||||
|
#define GLOBAL 1
|
||||||
|
#define FUNCTION 2
|
||||||
|
#define LOCAL_VARIABLE 4
|
||||||
|
#define ARGUEMENT 8
|
||||||
|
|
||||||
/* Globals */
|
/* Globals */
|
||||||
struct token_list* global_symbol_list;
|
struct token_list* global_symbol_list;
|
||||||
struct token_list* global_stack;
|
struct token_list* global_stack;
|
||||||
|
struct token_list* global_token;
|
||||||
|
|
||||||
/* Imported functions */
|
/* Imported functions */
|
||||||
int asprintf(char **strp, const char *fmt, ...);
|
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* emit(char *s, bool hands_off, struct token_list* head)
|
||||||
{
|
{
|
||||||
struct token_list* t = calloc(1, sizeof(struct token_list));
|
struct token_list* t = calloc(1, sizeof(struct token_list));
|
||||||
t->next = head;
|
t->next = head;
|
||||||
t->hands_off = hands_off;
|
t->hands_off = hands_off;
|
||||||
head = t;
|
|
||||||
t->s = s;
|
t->s = s;
|
||||||
return t;
|
return t;
|
||||||
}
|
}
|
||||||
|
@ -141,7 +147,7 @@ void require_char(char* message, char required)
|
||||||
}
|
}
|
||||||
|
|
||||||
struct token_list* expression(struct token_list* out);
|
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:
|
* primary-expr:
|
||||||
|
@ -178,7 +184,7 @@ struct token_list* primary_expr(struct token_list* out)
|
||||||
}
|
}
|
||||||
else if(global_token->s[0] == '"')
|
else if(global_token->s[0] == '"')
|
||||||
{
|
{
|
||||||
out = parse_string(out);
|
out = parse_string(out, global_token->s);
|
||||||
global_token = global_token->next;
|
global_token = global_token->next;
|
||||||
}
|
}
|
||||||
else exit(EXIT_FAILURE);
|
else exit(EXIT_FAILURE);
|
||||||
|
@ -471,6 +477,44 @@ struct token_list* process_if(struct token_list* out)
|
||||||
return 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 */
|
/* Process while loops */
|
||||||
int while_count;
|
int while_count;
|
||||||
struct token_list* process_while(struct token_list* out)
|
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
|
||||||
* if ( expression ) statement else statement
|
* if ( expression ) statement else statement
|
||||||
* while ( expression ) statement
|
* while ( expression ) statement
|
||||||
|
* for ( expression ; expression ; expression ) statement
|
||||||
* return ;
|
* return ;
|
||||||
* expr ;
|
* 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, "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, "if")) out = process_if(out);
|
||||||
else if(!strcmp(global_token->s, "while")) out = process_while(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 if(!strcmp(global_token->s, "return")) out = return_result(out);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -586,8 +632,7 @@ struct token_list* declare_global(struct token_list* out)
|
||||||
sym_declare(global_token->prev->s, GLOBAL);
|
sym_declare(global_token->prev->s, GLOBAL);
|
||||||
|
|
||||||
global_token = global_token->next;
|
global_token = global_token->next;
|
||||||
out = emit("NOP\n", true, out);
|
return emit("NOP\n", true, out);
|
||||||
return out;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct token_list* declare_function(struct token_list* out)
|
struct token_list* declare_function(struct token_list* out)
|
||||||
|
@ -674,7 +719,7 @@ int main(int argc, char **argv)
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
|
|
||||||
read_all_tokens(argv[1]);
|
global_token = read_all_tokens(argv[1]);
|
||||||
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);
|
||||||
|
|
7
cc.h
7
cc.h
|
@ -20,11 +20,6 @@
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#define GLOBAL 1
|
|
||||||
#define FUNCTION 2
|
|
||||||
#define LOCAL_VARIABLE 4
|
|
||||||
#define ARGUEMENT 8
|
|
||||||
|
|
||||||
struct token_list
|
struct token_list
|
||||||
{
|
{
|
||||||
struct token_list* next;
|
struct token_list* next;
|
||||||
|
@ -41,5 +36,3 @@ struct token_list
|
||||||
bool hands_off;
|
bool hands_off;
|
||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
struct token_list* global_token;
|
|
||||||
|
|
18
cc_reader.c
18
cc_reader.c
|
@ -17,6 +17,7 @@
|
||||||
|
|
||||||
#include "cc.h"
|
#include "cc.h"
|
||||||
FILE* input;
|
FILE* input;
|
||||||
|
struct token_list* token;
|
||||||
|
|
||||||
char clearWhiteSpace(char c)
|
char clearWhiteSpace(char c)
|
||||||
{
|
{
|
||||||
|
@ -39,8 +40,15 @@ char consume_word(struct token_list* current, char c, char frequent)
|
||||||
return consume_byte(current, c);
|
return consume_byte(current, c);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char purge_macro(int ch)
|
||||||
|
{
|
||||||
|
while(10 != ch) ch = fgetc(input);
|
||||||
|
return ch;
|
||||||
|
}
|
||||||
|
|
||||||
int get_token(int c)
|
int get_token(int c)
|
||||||
{
|
{
|
||||||
|
if('#' == c) c = purge_macro(c);
|
||||||
bool w = true;
|
bool w = true;
|
||||||
|
|
||||||
struct token_list* current = calloc(1, sizeof(struct token_list));
|
struct token_list* current = calloc(1, sizeof(struct token_list));
|
||||||
|
@ -77,9 +85,9 @@ int get_token(int c)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
current->prev = global_token;
|
current->prev = token;
|
||||||
current->next = global_token;
|
current->next = token;
|
||||||
global_token = current;
|
token = current;
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -96,11 +104,11 @@ struct token_list* reverse_list(struct token_list* head)
|
||||||
return root;
|
return root;
|
||||||
}
|
}
|
||||||
|
|
||||||
void read_all_tokens(char* source_file)
|
struct token_list* read_all_tokens(char* source_file)
|
||||||
{
|
{
|
||||||
input = fopen(source_file, "r");
|
input = fopen(source_file, "r");
|
||||||
int ch =fgetc(input);
|
int ch =fgetc(input);
|
||||||
while(EOF != ch) ch = get_token(ch);
|
while(EOF != ch) ch = get_token(ch);
|
||||||
|
|
||||||
global_token = reverse_list(global_token);
|
return reverse_list(token);
|
||||||
}
|
}
|
||||||
|
|
20
cc_strings.c
20
cc_strings.c
|
@ -67,7 +67,7 @@ bool weird(char c)
|
||||||
|
|
||||||
/* Parse string to deal with hex characters*/
|
/* 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};
|
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;
|
char* label;
|
||||||
static int string_num;
|
static int string_num;
|
||||||
|
@ -79,25 +79,25 @@ struct token_list* parse_string(struct token_list* output_list)
|
||||||
bool hexit = false;
|
bool hexit = false;
|
||||||
|
|
||||||
message[0] = '"';
|
message[0] = '"';
|
||||||
while(global_token->s[j] != '"')
|
while(string[j] != '"')
|
||||||
{
|
{
|
||||||
hold[k] = ' ';
|
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 + 1] = upcase(string[j + 2]);
|
||||||
hold[k + 2] = upcase(global_token->s[j + 3]);
|
hold[k + 2] = upcase(string[j + 3]);
|
||||||
int t1 = hex(global_token->s[j + 2], true);
|
int t1 = hex(string[j + 2], true);
|
||||||
int t2 = hex(global_token->s[j + 3], false);
|
int t2 = hex(string[j + 3], false);
|
||||||
message[i] = t1 + t2;
|
message[i] = t1 + t2;
|
||||||
if(weird(message[i])) hexit = true;
|
if(weird(message[i])) hexit = true;
|
||||||
j = j + 4;
|
j = j + 4;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
hold[k + 1] = table[(global_token->s[j] >> 4)];
|
hold[k + 1] = table[(string[j] >> 4)];
|
||||||
hold[k + 2] = table[(global_token->s[j] & 15)];
|
hold[k + 2] = table[(string[j] & 15)];
|
||||||
message[i] = global_token->s[j];
|
message[i] = string[j];
|
||||||
j = j + 1;
|
j = j + 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
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;
|
||||||
|
}
|
|
@ -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 <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# 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
|
Loading…
Reference in New Issue