aboutsummaryrefslogtreecommitdiff
path: root/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'main.c')
-rw-r--r--main.c251
1 files changed, 251 insertions, 0 deletions
diff --git a/main.c b/main.c
new file mode 100644
index 0000000..e02a9f2
--- /dev/null
+++ b/main.c
@@ -0,0 +1,251 @@
+#include "types.h"
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+typedef struct Token {
+ // identifying tag
+ enum TokenType {
+ t_error,
+ t_size,
+ t_multiply,
+ t_divide,
+ t_add,
+ t_subtract,
+ t_whitespace,
+ t_newline,
+ t_number,
+ } type;
+
+ // change to offset + size, or line + col -- alleviated by helper structure of
+ // ptrs to each newline
+ union Data {
+ i32 number;
+ } data;
+} Token_t;
+
+// 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 Token_t* l_read(char* text, isize text_length, Token_t* dst);
+
+int
+main(int argc, char* argv[]) {
+ if (argc == 2) {
+ FILE* f = NULL;
+ char* contents = NULL;
+ isize content_length = -1;
+ Token_t* tokens = NULL;
+
+ f = fopen(argv[1], "r");
+ if (f == NULL) {
+ fprintf(stdout, "! Failed to open file: %s\n", argv[1]);
+ }
+
+ if (f != NULL) {
+ content_length = f_read(f, &contents);
+ if (content_length > 0) {
+ printf("%s:%ld\n%s\n", argv[1], content_length, contents);
+ }
+ fclose(f);
+ }
+
+ 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]);
+ }
+ }
+ }
+ return 0;
+}
+
+/* Copies the contents of the file stream to *dst.
+ * @param stream An open file stream.
+ * @param dst** Destination buffer. If *dst is NULL allocates a buffer the size
+ * of stream using malloc.
+ * @return The number of bytes copied into dst.
+ * @error returns -1 on error.
+ */
+static isize
+f_read(FILE* stream, char** dst) {
+ i64 file_sz = f_size(stream);
+
+ if (dst == NULL) {
+ fprintf(stderr, "! Got NULL ptr\n");
+ }
+
+ if (dst != NULL && *dst == NULL && file_sz > 0) {
+ *dst = (char*)malloc(file_sz * sizeof(char));
+ }
+
+ if (dst != NULL && *dst == NULL && file_sz > 0) {
+ fprintf(stderr, "! Failed to allocate %ld bytes\n", file_sz * sizeof(char));
+ }
+
+ isize bytes_read = -1;
+ if (dst != NULL && *dst != NULL && file_sz > 0) {
+ bytes_read = fread(*dst, sizeof(char), file_sz, stream);
+ }
+
+ if (bytes_read < file_sz) {
+ fprintf(stderr, "! Failed to read file, read %ld out of %ld bytes\n",
+ bytes_read, file_sz);
+ }
+
+ return bytes_read;
+}
+
+/* Returns the size in bytes and rewinds the stream.
+ * @param stream An open file stream.
+ * @return the size of the file in bytes.
+ * @error Returns -1 on error.
+ */
+static i64
+f_size(FILE* stream) {
+ // Could ftell and rewind to previous position, but scratch that
+ i64 size = -1;
+ i32 error = fseek(stream, 0, SEEK_END);
+
+ if (error) {
+ // TODO: handle pipes (check errno == ESPIPE)
+ fprintf(stderr, "! Failed to seek file: %s\n", strerror(errno));
+ } else {
+ size = ftell(stream);
+ rewind(stream);
+ }
+ return size;
+}
+
+static void
+l_print_token(Token_t token) {
+ switch (token.type) {
+ case t_error:
+ fputs(" error ", stdout);
+ break;
+ case t_size:
+ printf(" [%d] ", token.data.number);
+ break;
+ case t_multiply:
+ fputs(" * ", stdout);
+ break;
+ case t_divide:
+ fputs(" / ", stdout);
+ break;
+ case t_add:
+ fputs(" + ", stdout);
+ break;
+ case t_subtract:
+ fputs(" - ", stdout);
+ break;
+ case t_number:
+ printf("%d", token.data.number);
+ break;
+ default:
+ break;
+ }
+}
+
+/* Reads text and parses it into an array of tokens
+ * @param text A buffer holding the input text
+ * @return a pointer to dst
+ * @error Returns NULL on error.
+ */
+static Token_t*
+l_read(char* text, isize text_length, Token_t* dst) {
+ if (text_length > 0 && dst == NULL) {
+ dst = (Token_t*)malloc(text_length * sizeof(Token_t));
+ }
+
+ if (text_length > 0 && dst == NULL) {
+ fprintf(stderr, "! Failed to allocate %ld bytes\n",
+ text_length * sizeof(Token_t));
+ }
+
+ if (text_length > 0 && dst != NULL) {
+ isize i = 0;
+ isize t = 1;
+ i32 error = 0;
+
+ dst[0].type = t_size;
+ dst[0].data.number = 0;
+
+ // TODO: rewrite to
+ // if token != last-token
+ // dst = token,line,col
+ // last-token = token
+ // t++;
+ // while (last-token != error)
+ do {
+ switch (text[i]) {
+ // case t_size:
+ // break;
+ case '*':
+ dst[t].type = t_multiply;
+ t++;
+ break;
+ case '/':
+ dst[t].type = t_divide;
+ t++;
+ break;
+ case t_add:
+ dst[t].type = t_add;
+ t++;
+ break;
+ case '-':
+ dst[t].type = t_subtract;
+ t++;
+ break;
+
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ dst[t].type = t_number;
+ dst[t].data.number = text[i] - '0';
+ t++;
+ break;
+ case '+':
+ dst[t].type = t_add;
+ t++;
+ break;
+
+ case ' ':
+ case '\t':
+ dst[t].type = t_whitespace;
+ t++;
+ break;
+
+ case '\n':
+ dst[t].type = t_newline;
+ t++;
+ break;
+
+ default:
+ dst[t].type = t_error;
+ t++;
+ error = 1;
+ break;
+ }
+ i++;
+ } while (!error && i < text_length);
+
+ dst[0].data.number = t;
+ }
+
+ return dst;
+}