diff options
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | cccl.c | 6 | ||||
| -rw-r--r-- | cccl.h | 7 | ||||
| -rw-r--r-- | main.c | 50 | ||||
| -rw-r--r-- | parser.c | 11 | ||||
| -rw-r--r-- | tokenizer.c | 12 |
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 } |