From: Michael D. Lowis Date: Sat, 30 May 2015 02:05:40 +0000 (-0400) Subject: added string buffer routines for building strings sequentially. Also added line and... X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=714e1a3697eabe6ffad22574e8bd4456f241b629;p=proto%2Fgir.git added string buffer routines for building strings sequentially. Also added line and column tracking --- diff --git a/source/main.c b/source/main.c index e5394e3..11365b2 100644 --- a/source/main.c +++ b/source/main.c @@ -46,10 +46,19 @@ typedef struct AST { struct AST* children[]; } AST; +typedef struct strbuf_t { + size_t index; + size_t capacity; + char* string; +} strbuf_t; + // Globals static FILE* File; static int CurrChar = ' '; +static int Line = 1; +static int Column = 0; static int CurrTok = UNKNOWN; +static strbuf_t Token = {0,0,0}; static intptr_t Token_Buffer[1024]; static intptr_t* Token_Stack = Token_Buffer-1; @@ -88,6 +97,7 @@ static void append(void); static void discard(void); static void expect_ch(int ch); static void lex_error(void); +static void fetch(void); // Tree Routines static AST* Tree(int type, int num_children); @@ -97,6 +107,12 @@ void reduce(int count); void shift_reduce(int type, int nchildren); void push_reduce(int type, int nchildren); +// String Buffer +void strbuf_init(strbuf_t* buf); +void strbuf_putc(strbuf_t* buf, int ch); +void strbuf_print(strbuf_t* buf, const char* str); +char* strbuf_string(strbuf_t* buf); + /* Parsing Rules *****************************************************************************/ static void expression(void) @@ -383,12 +399,6 @@ static int operator(void) /* Lexical Analysis Helpers *****************************************************************************/ -static void lex_error(void) -{ - fprintf(stderr, "Lexer error\n"); - exit(1); -} - static int current(void) { return CurrChar; @@ -396,12 +406,13 @@ static int current(void) static void append(void) { - CurrChar = fgetc(File); + strbuf_putc(&Token, CurrChar); + fetch(); } static void discard(void) { - CurrChar = fgetc(File); + fetch(); } static void expect_ch(int ch) @@ -412,6 +423,23 @@ static void expect_ch(int ch) lex_error(); } +static void lex_error(void) +{ + fprintf(stderr, "Lexer error\n"); + exit(1); +} + +static void fetch(void) +{ + CurrChar = fgetc(File); + if (CurrChar == '\n') { + Line++; + Column = 0; + } else { + Column++; + } +} + /* Tree Routines *****************************************************************************/ AST* Tree(int type, int num_children) @@ -471,6 +499,41 @@ void push_reduce(int type, int nchildren) reduce(nchildren); } +/* String Buffer + *****************************************************************************/ +void strbuf_init(strbuf_t* buf) +{ + buf->index = 0; + buf->capacity = 8; + buf->string = (char*)malloc(buf->capacity); + buf->string[buf->index] = 0; +} + +void strbuf_putc(strbuf_t* buf, int ch) +{ + if (buf->string == NULL) { + strbuf_init(buf); + } else if ((buf->index + 2) >= buf->capacity) { + buf->capacity = buf->capacity << 1; + buf->string = (char*)realloc(buf->string, buf->capacity); + } + buf->string[buf->index++] = ch; + buf->string[buf->index] = '\0'; +} + +void strbuf_print(strbuf_t* buf, const char* str) +{ + while(*str) + strbuf_putc(buf, *str++); +} + +char* strbuf_string(strbuf_t* buf) +{ + char* str = buf->string; + strbuf_init(buf); + return str; +} + /* Main *****************************************************************************/ int main(int argc, char** argv) { @@ -484,6 +547,7 @@ int main(int argc, char** argv) { /* Print and clear */ PrintTree((AST*)*Token_Stack, 0); Token_Stack = Token_Buffer-1; + free(strbuf_string(&Token)); } (void)argc; (void)argv;