diff options
| -rw-r--r-- | main.c | 144 | ||||
| -rw-r--r-- | program.input | 4 |
2 files changed, 109 insertions, 39 deletions
@@ -4,6 +4,16 @@ #include <stdlib.h> #include <string.h> +// Location in the source file +typedef struct Location { + // Offset in file of the first character + i32 line; + // Offset on the line of the first character + u16 column; + // Length in bytes + u16 size; +} Location_t; + typedef struct Token { // identifying tag enum TokenType { @@ -18,18 +28,33 @@ typedef struct Token { t_number, } type; - // change to offset + size, or line + col -- alleviated by helper structure of - // ptrs to each newline - union Data { - i32 number; - } data; + // Offset(s) in the buffer where the token occurs. + // If type is t_size, then location is an i64 "size" -- only used to store the + // number of tokens. + // If type is t_newline, then location is a Location_t line, where `line` + // holds the offset into the text buffer where the newline is located, column + // holds the line number, + // and size holds the length of the line. + union { + Location_t location; + Location_t line; + i64 size; + } location; } Token_t; +// #define Location_to_i64(location) \ +// (i64)(((i64)location.line << 32) | (location.column << 16) | location.size) +// #define i64_to_Location(long_int) \ +// (Location_t) { \ +// .line = (long_int >> 32), .column = (long_int >> 16) & ((1 << 16) - 1), \ +// .size = long_int & ((1 << 16) - 1), \ +// } + // Should also add helper structure with pointers to each line static isize f_read(FILE* stream, char** dst); static i64 f_size(FILE* stream); -static void l_print_token(Token_t token); +static void l_print_token(Token_t token, char* text); static Token_t* l_read(char* text, isize text_length, Token_t* dst); int @@ -55,14 +80,15 @@ main(int argc, char* argv[]) { if (content_length > 0) { tokens = l_read(contents, strlen(contents), NULL); - free(contents); } if (tokens != NULL) { - printf("%d tokens\n", tokens[0].data.number); - for (int t = 0; t < tokens[0].data.number; t++) { - l_print_token(tokens[t]); + i64 num_tokens = tokens[0].location.size; + printf("%ld tokens\n", num_tokens); + for (int t = 0; t < num_tokens; t++) { + l_print_token(tokens[t], contents); } + free(contents); } } return 0; @@ -126,13 +152,15 @@ f_size(FILE* stream) { } static void -l_print_token(Token_t token) { +l_print_token(Token_t token, char* text) { + fprintf(stdout, "[%d,%d:%d]", token.location.location.line + 1, + token.location.location.column + 1, token.location.location.size); switch (token.type) { case t_error: fputs(" error ", stdout); break; case t_size: - printf(" [%d] ", token.data.number); + fprintf(stdout, "size"); break; case t_multiply: fputs(" * ", stdout); @@ -147,11 +175,18 @@ l_print_token(Token_t token) { fputs(" - ", stdout); break; case t_number: - printf("%d", token.data.number); + fputs("number:", stdout); + fwrite(&text[token.location.location.line + token.location.location.column], + token.location.location.size, sizeof(char), stdout); + break; + case t_newline: + fprintf(stdout, "\\n offset:%d line:%d length:%d", token.location.line.line, + token.location.line.column, token.location.line.size); break; default: break; } + puts(""); } /* Reads text and parses it into an array of tokens @@ -171,12 +206,23 @@ l_read(char* text, isize text_length, Token_t* dst) { } if (text_length > 0 && dst != NULL) { - isize i = 0; - isize t = 1; - i32 error = 0; + // Offset in text (used for Location.line + isize i = 0; + // Column counter + u16 c = 0; + // Line offset + i32 l = 0; + // Token counter + isize t = 2; + i32 error = 0; + enum TokenType token_previous = t_error; + enum TokenType token = t_error; - dst[0].type = t_size; - dst[0].data.number = 0; + dst[1].type = t_newline; + Location_t* line_current = &(dst[1].location.line); + line_current->line = 0; + line_current->column = l; + line_current->size = 0; // TODO: rewrite to // if token != last-token @@ -189,20 +235,16 @@ l_read(char* text, isize text_length, Token_t* dst) { // case t_size: // break; case '*': - dst[t].type = t_multiply; - t++; + token = t_multiply; break; case '/': - dst[t].type = t_divide; - t++; + token = t_divide; break; case t_add: - dst[t].type = t_add; - t++; + token = t_add; break; case '-': - dst[t].type = t_subtract; - t++; + token = t_subtract; break; case '0': @@ -215,36 +257,62 @@ l_read(char* text, isize text_length, Token_t* dst) { case '7': case '8': case '9': - dst[t].type = t_number; - dst[t].data.number = text[i] - '0'; - t++; + token = t_number; break; case '+': - dst[t].type = t_add; - t++; + token = t_add; break; case ' ': case '\t': - dst[t].type = t_whitespace; - t++; + token = t_whitespace; break; case '\n': - dst[t].type = t_newline; - t++; + token = t_newline; break; default: - dst[t].type = t_error; - t++; + token = t_error; error = 1; break; } + + if (token == t_newline) { + l++; + line_current->size = c; + dst[t].type = token; + dst[t].location.line.line = i + 1; + dst[t].location.line.column = l; + dst[t].location.line.size = 0; + + line_current = &dst[t].location.line; + c = 0; + t++; + token_previous = token; + } else if (token == token_previous) { + dst[t - 1].location.location.size++; + c++; + } else { + dst[t].type = token; + dst[t].location.location.line = l; + dst[t].location.location.column = c; + dst[t].location.location.size = 1; + c++; + t++; + token_previous = token; + } + i++; } while (!error && i < text_length); - dst[0].data.number = t; + dst[0].type = t_size; + dst[0].location.size = t; + + if (dst[t - 1].type != t_newline) { + l++; + line_current->size = c; + } } return dst; diff --git a/program.input b/program.input index b43bef7..45fd4cb 100644 --- a/program.input +++ b/program.input @@ -1 +1,3 @@ -2 + 2 * 2 +2 + 22 * 2 + +1337 * 2
\ No newline at end of file |
