/* 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 "cc.h" FILE* input; struct token_list* token; int line; char* file; int clearWhiteSpace(int c) { if((32 == c) || (9 == c)) return clearWhiteSpace(fgetc(input)); else if (10 == c) { line = line + 1; return clearWhiteSpace(fgetc(input)); } return c; } int string_index; int consume_byte(struct token_list* current, int c) { current->s[string_index] = c; string_index = string_index + 1; return fgetc(input); } int consume_word(struct token_list* current, int c, int frequent) { int escape = FALSE; do { if(!escape && '\\' == c ) escape = TRUE; else escape = FALSE; c = consume_byte(current, c); } while(escape || (c != frequent)); return fgetc(input); } void fixup_label(struct token_list* current) { int hold = ':'; int prev; int i = 0; do { prev = hold; hold = current->s[i]; current->s[i] = prev; i = i + 1; } while(0 != hold); } int preserve_keyword(struct token_list* current, int c) { while((('a' <= c) & (c <= 'z')) | (('A' <= c) & (c <= 'Z')) | (('0' <= c) & (c <= '9')) | (c == '_')) { c = consume_byte(current, c); } if(':' == c) { fixup_label(current); return 32; } return c; } int preserve_symbol(struct token_list* current, int c) { while((c == '<') | (c == '=') | (c == '>') | (c == '|') | (c == '&') | (c == '!') | (c == '-')) { c = consume_byte(current, c); } return c; } int purge_macro(int ch) { while(10 != ch) ch = fgetc(input); return ch; } int get_token(int c) { struct token_list* current = calloc(1, sizeof(struct token_list)); current->s = calloc(MAX_STRING, sizeof(char)); reset: string_index = 0; c = clearWhiteSpace(c); if('#' == c) { c = purge_macro(c); goto reset; } else if((('a' <= c) & (c <= 'z')) | (('A' <= c) & (c <= 'Z')) | (('0' <= c) & (c <= '9')) | (c == '_')) { c = preserve_keyword(current, c); } else if((c == '<') | (c == '=') | (c == '>') | (c == '|') | (c == '&') | (c == '!') | ( c == '-')) { c = preserve_symbol(current, c); } else if(c == 39) { /* 39 == ' */ c = consume_word(current, c, 39); } else if(c == '"') { c = consume_word(current, c, '"'); } else if(c == '/') { c = consume_byte(current, c); if(c == '*') { c = fgetc(input); while(c != '/') { while(c != '*') { c = fgetc(input); if(10 == c) line = line + 1; } c = fgetc(input); if(10 == c) line = line + 1; } c = fgetc(input); goto reset; } else if(c == '/') { c = fgetc(input); goto reset; } } else if(c == EOF) { free(current); return c; } else { c = consume_byte(current, c); } current->prev = token; current->next = token; current->linenumber = line; current->filename = file; token = current; return c; } struct token_list* reverse_list(struct token_list* head) { struct token_list* root = NULL; while(NULL != head) { struct token_list* next = head->next; head->next = root; root = head; head = next; } return root; } struct token_list* read_all_tokens(FILE* a, struct token_list* current, char* filename) { input = a; line = 1; file = filename; token = current; int ch =fgetc(input); while(EOF != ch) ch = get_token(ch); return token; }