aboutsummaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'main.c')
-rw-r--r--main.c144
1 files changed, 106 insertions, 38 deletions
diff --git a/main.c b/main.c
index e02a9f2..f07629d 100644
--- a/main.c
+++ b/main.c
@@ -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;