summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Makefile2
-rw-r--r--cccl.c6
-rw-r--r--cccl.h7
-rw-r--r--main.c50
-rw-r--r--parser.c11
-rw-r--r--tokenizer.c12
6 files changed, 58 insertions, 30 deletions
diff --git a/Makefile b/Makefile
index 28c5ad9..d98e9bd 100644
--- a/Makefile
+++ b/Makefile
@@ -9,6 +9,8 @@ RM ?= rm -f
 
 all: 3cl
 
+${OBJS}: cccl.h
+
 3cl: ${OBJS}
 	${CC} ${LDFLAGS} -o 3cl ${OBJS} ${LDLIBS}
 
diff --git a/cccl.c b/cccl.c
index 58301f5..eedea7c 100644
--- a/cccl.c
+++ b/cccl.c
@@ -8,6 +8,8 @@ void cccl(struct cccl_File file)
 {
     struct cccl_Token tokens[TOKENS_LIMIT];
 
-    size_t tokens_amount = tokenize(file.buffer, file.size, tokens, TOKENS_LIMIT);
-    printf("Read: %lu\n", tokens_amount);
+    size_t tokens_amount = cccl_tokenize(file.buffer, file.size, tokens, TOKENS_LIMIT);
+    if (verbose)
+        fprintf(stderr, "Read: %lu\n", tokens_amount);
+    struct cccl_Node *parsed = cccl_parse(tokens, tokens_amount, 0, 0);
 }
diff --git a/cccl.h b/cccl.h
index 7e5cc01..48ad499 100644
--- a/cccl.h
+++ b/cccl.h
@@ -6,6 +6,8 @@
 
 #define TOKENS_LIMIT 16384
 
+extern int verbose;
+
 struct cccl_File
 {
     char *buffer;
@@ -29,7 +31,7 @@ struct cccl_Token
 
 enum cccl_NodeType
 {
-    cccl_Node_CODE,
+    cccl_Node_CODE = 0,
 
     cccl_Node_PUSHZERO,
     cccl_Node_INCREMENT,
@@ -64,6 +66,7 @@ struct cccl_Node
 int cccl_allocfile(const char *path, struct cccl_File *file);
 
 void cccl(struct cccl_File file);
-size_t tokenize(const char *code, size_t size, struct cccl_Token tokens[], size_t tokens_length);
+size_t cccl_tokenize(const char *code, size_t size, struct cccl_Token tokens[], size_t tokens_length);
+struct cccl_Node *cccl_parse(struct cccl_Token tokens[], size_t tokens_length, enum cccl_NodeType type, char value);
 
 #endif /* __CCCL_H__ */
diff --git a/main.c b/main.c
index a5f79e7..262e9b6 100644
--- a/main.c
+++ b/main.c
@@ -3,39 +3,49 @@
 #include <assert.h>
 #include <err.h>
 #include <stdio.h>
+#include <stdlib.h>
 
+#include <unistd.h>
+
+
+int verbose = 0;
 
 int main(int argc, char **argv)
 {
-    if (!argv[1])
+    int ch;
+    while ((ch = getopt(argc, argv, "v")) >= 0)
+    {
+        switch (ch)
+        {
+            case 'v':
+            {
+                verbose = 1;
+            } break;
+            default:
+            {
+                fprintf(stderr, "usage: %s [-v] file\n", argv[0]);
+                exit(1);
+            } break;
+        }
+    }
+    argc -= optind;
+    argv += optind;
+
+    if (!*argv)
         return 1;
 
     struct cccl_File file;
 
-    int error = cccl_allocfile(argv[1], &file);
+    int error = cccl_allocfile(*argv, &file);
     if (error)
         err(1, "cccl_readfile()");
 
-    FILE *f = fopen(argv[1], "r");
+    FILE *f = fopen(*argv, "r");
     if (!f)
         err(1, "fopen()");
-    int bytes_read = 0;
-    while (bytes_read < file.size)
-    {
-        int read_now = fread(
-            file.buffer + bytes_read,
-            sizeof(*file.buffer),
-            (file.size - bytes_read) % 2048,
-            f
-        );
-        if (read_now == 0)
-        {
-            if (ferror(f))
-                errx(1, "couldn't read %s", argv[1]);
-            else
-                break;
-        }
-    }
+    int bytes_read = fread(file.buffer, 1, file.size, f);
+    if (ferror(f) || bytes_read != file.size)
+        errx(1, "couldn't read %s", *argv);
     fclose(f);
 
     cccl(file);
diff --git a/parser.c b/parser.c
index 87eb498..267bcb5 100644
--- a/parser.c
+++ b/parser.c
@@ -3,6 +3,7 @@
 #include <assert.h>
 #include <err.h>
 #include <stddef.h>
+#include <stdio.h>
 #include <stdlib.h>
 
 
@@ -53,6 +54,8 @@ struct cccl_Node *cccl_parse(struct cccl_Token tokens[], size_t tokens_length, e
 
     for (size_t i = 0; i < tokens_length; ++i)
     {
+        if (verbose)
+            fprintf(stderr, "T:[%c:%d] ", tokens[i].value, tokens[i].type);
         switch (tokens[i].type)
         {
         case cccl_Token_COMMAND: case cccl_Token_COMMANDWITHARG: case cccl_Token_BLOCKSTART:
@@ -82,6 +85,7 @@ struct cccl_Node *cccl_parse(struct cccl_Token tokens[], size_t tokens_length, e
         case cccl_Token_COMMANDWITHARG:
         {
             assert(i + 1 != tokens_length);
+            assert(tokens[i + 1].type == cccl_Token_IDENTIFIER);
             res->in[res->in_length - 1] = malloc(sizeof(struct cccl_Node));
             *res->in[res->in_length - 1] = (struct cccl_Node)
             {
@@ -92,6 +96,7 @@ struct cccl_Node *cccl_parse(struct cccl_Token tokens[], size_t tokens_length, e
         case cccl_Token_BLOCKSTART:
         {
             assert(i > 0);
+            assert(tokens[i - 1].type == cccl_Token_IDENTIFIER);
             char opening = tokens[i].value, closing;
             switch (tokens[i].value)
             {
@@ -101,10 +106,12 @@ struct cccl_Node *cccl_parse(struct cccl_Token tokens[], size_t tokens_length, e
             break; case '?': closing = ';';
             }
 
-            size_t oldi = i;
+            size_t oldi = i++;
             int depth = 1;
             for (; i < tokens_length; ++i)
             {
+                if (verbose)
+                    fprintf(stderr, "S:[%c %c %d] ", tokens[i].value, closing, depth);
                 if (tokens[i].value == opening)
                     ++depth;
                 else if (tokens[i].value == closing)
@@ -116,6 +123,8 @@ struct cccl_Node *cccl_parse(struct cccl_Token tokens[], size_t tokens_length, e
             errx(1, "No matching bracket for %c", opening);
 
 end:
+            putchar('\n');
+            puts("Exploring inner...");
             res->in[res->in_length - 1] = cccl_parse(
                 tokens + oldi + 1,
                 i - oldi - 1,
diff --git a/tokenizer.c b/tokenizer.c
index 04e2137..e843ef1 100644
--- a/tokenizer.c
+++ b/tokenizer.c
@@ -2,10 +2,11 @@
 
 #include <assert.h>
 #include <err.h>
+#include <stdio.h>
 #include <stddef.h>
 
 
-size_t tokenize(const char *code, size_t size, struct cccl_Token tokens[], size_t tokens_length)
+size_t cccl_tokenize(const char *code, size_t size, struct cccl_Token tokens[], size_t tokens_length)
 {
     size_t i = 0, tokeni = 0;
     int comment = 0;
@@ -38,11 +39,12 @@ size_t tokenize(const char *code, size_t size, struct cccl_Token tokens[], size_
         case 'A': case 'B': case 'C': case 'D': case 'E': case 'F': case 'G': case 'H': case 'I': 
         case 'J': case 'K': case 'L': case 'M': case 'N': case 'O': case 'P': case 'Q': case 'R': 
         case 'S': case 'T': case 'U': case 'V': case 'W': case 'X': case 'Y': case 'Z':
+        case '_':
             X(IDENTIFIER);
-        case '^': case '+': case '-': case '*': case '~':
+        case '^': case '+': case '-': case '*': case '~': case '#': case ':':
             X(COMMAND);
-        case '%': case '=': case '!': case '$': case '&':
-        case '<': case '>': case '#': case ':': case '@':
+        case '%': case '=': case '!': case '$':
+        case '&': case '<': case '>': case '@':
             X(COMMANDWITHARG);
         case '{': case '(': case '[': case '?':
             X(BLOCKSTART);
@@ -54,7 +56,7 @@ size_t tokenize(const char *code, size_t size, struct cccl_Token tokens[], size_
         {
             if (comment)
                 break;
-            errx(1, "Illegal symbol in a code: [%d] %c", code[i], code[i]);
+            errx(1, "Illegal symbol in a code at byte %lu: [%d] %c", i, code[i], code[i]);
         } break;
 #undef X
         }