aboutsummaryrefslogtreecommitdiff
path: root/demos/sample-files/lbp-skeleton.c
diff options
context:
space:
mode:
authorkartofen <kartofen.mail.0@protonmail.com>2025-09-24 00:06:54 +0300
committerkartofen <kartofen.mail.0@protonmail.com>2025-09-24 00:06:54 +0300
commitfec8e3a95becfb3dc2a3eb0f512a120a7a4551c5 (patch)
tree8d3da9f0c3fa36f5e06bc49cc1bfdc0db3099ea1 /demos/sample-files/lbp-skeleton.c
parentdb1b9c8dcb0d115217a33c2fe8e0760d49143e11 (diff)
debug info through the lr parser
Diffstat (limited to 'demos/sample-files/lbp-skeleton.c')
-rw-r--r--demos/sample-files/lbp-skeleton.c267
1 files changed, 196 insertions, 71 deletions
diff --git a/demos/sample-files/lbp-skeleton.c b/demos/sample-files/lbp-skeleton.c
index bf7bdca..1ee54d8 100644
--- a/demos/sample-files/lbp-skeleton.c
+++ b/demos/sample-files/lbp-skeleton.c
@@ -3,12 +3,20 @@
#include <string.h>
#include <stdint.h>
#include <ctype.h>
+#include <stdarg.h>
-// TODO: - lr parser is bad for debugging
-// - deal with errors
+// TODO: - lr parser is bad for debugging (now its better)
+// - deal with errors (the token queue for example)!!!!
+// - debuginfo in the token that gets propagaded through the
+// stack_items and lr_parse returns a generic errorinfo
+// with user-implemented compilation error messages
+// - ast should show the specific operation (match, assignment, etc)
+
+#define MIN(a, b) ((a) > (b) ? (b) : (a))
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define INPUT_CAP 4096
-#define ARENA_CAP 8192 //4096
+#define ARENA_CAP 4096 * 3
#define ARENA_IMPLEMENTATION
#include "util/arena.h"
@@ -51,40 +59,75 @@ static void xfree(void *ptr) { (void)ptr; return; }
#include "util/list.h"
-struct ast_strlist { char *str; struct list_head list; };
+struct datatype {
+ int typeflags;
+ // TODO: add ptr
+ char *iden;
+ struct list_head *function_exprlist;
+};
+
+struct strlist { char *str; struct list_head list; };
+
+// TODO:
+// - type of each each exprlist, be it assignement, match, function call, etc
+// - revise expr types, etc
+
+// struct ast_exprlist {
+// enum { AST_OP_ASSIGNMENT, AST_OP_TYPE, AST_OP_CALL } type;
+// struct list_head *exprlist;
+// }
+
+// struct ast_exprlist {
+// enum { AST_OP_ASSIGNMENT, AST_OP_IMPLEMENT, AST_OP_MATCH, AST_OP_EQUAL, AST_OP_CALL } type;
+// struct list_head *exprlist;
+// };
+
+// struct ast_expr {
+// enum { AST_LITERAL, AST_IDENTIFIER, AST_DECLARATION, AST_SUB } type;
+
+// struct datatype datatype;
+// struct list_head list;
+// }
struct ast_expr {
- enum { AST_NUMBER, AST_VARIABLE, AST_FIELDLIST, AST_DECLARATION, AST_DEFINITION, AST_OPERATION, AST_PARENLIST } type;
+ enum { AST_NUMBER, AST_VARIABLE, AST_DECLARATION, AST_FIELDLIST, AST_OPERATION, AST_PARENLIST, AST_BRACELIST } type;
union {
int number;
struct ast_vrbl { int is_atom; char *iden; } variable;
struct ast_fiel { struct ast_vrbl variable; struct list_head *fields_strlist; } fieldlist;
- struct ast_decl { struct ast_vrbl variable; int typed; } declaration;
- struct ast_defn { struct ast_decl declartion; struct list_head *block_exprlist; } definition;
+
struct ast_oprn { enum { AST_OP_AND, AST_OP_OR } optype; struct list_head *left_exprlist; struct list_head *right_exprlist; } operation;
- struct list_head *paren_exprlist;
+ struct list_head *exprlist;
};
+
+ struct datatype datatype;
struct list_head list;
};
-#define NEW(t, ...) ((struct ast_##t){__VA_ARGS__})
-#define g_NEW(t, ...) ((stack_item){.t = (struct ast_##t){__VA_ARGS__}})
+#define AST(t, ...) ((struct ast_##t){__VA_ARGS__})
+#define g_AST(t, ...) ((stack_item){.t = {__VA_ARGS__}})
-#define LST(v) ({ typeof(v) *r = xalloc(sizeof(v)); *r = v; LIST_EMPTY(&r->list); &r->list; })
-#define g_LST(v) ((stack_item){.list = LST(v)})
+#define NEW(t, ...) ((struct t){__VA_ARGS__})
+#define g_NEW(t, ...) ((stack_item){.t = {__VA_ARGS__}})
-void ast_vrbl_print(struct ast_vrbl *vrbl);
-void ast_fiel_print(struct ast_fiel *fiel);
-void ast_decl_print(struct ast_decl *decl);
-void ast_defn_print(struct ast_defn *defn);
-void ast_oprn_print(struct ast_oprn *oprn);
-void ast_expr_print(struct ast_expr *expr);
-void ast_exprlist_print(struct list_head *list);
+#define LST(v) ({ typeof(v) *r = malloc(sizeof(v)); *r = v; LIST_EMPTY(&r->list); &r->list; })
+#define g_LST(v) ((stack_item){.list = LST(v)})
-void ast_exprlist_free(struct list_head *list);
+// void ast_decide_datatype(struct list_head *list);
+void ast_print(struct list_head *list);
+void ast_free(struct list_head *list);
// generated
#include "bin/lbp.h"
+
+enum { DATATYPE_INT = 0, DATATYPE_STRUCT, DATATYPE_ENUM };
+enum { SUBTYPE_FUNCTION = 1 << 0, SUBTYPE_LITTLE = 1 << 1,
+ SUBTYPE_BIG = 1 << 2, SUBTYPE_NATIVE = 1 << 3 };
+
+#define TYPEFLAGS(type, subtype) (((subtype) << 3) | (type))
+#define flags2type(flags) ((flags) & 7)
+#define flags2subtype(flags) ((flags) >> 3)
+
#include "bin/lbp.c"
#include "util/dict.h"
@@ -107,32 +150,31 @@ static uint8_t dict_lowercase_char_to_bit[256] = {
['y'] = 26, ['z'] = 27, [ 0 ] = 1, [' '] = 1
};
+static inline char *substring(char *str, size_t sub_end);
+static inline char *linestart(char *strstart, char *pos);
+static inline size_t tillch(char *str, size_t len, char ch);
+#define strdup(...) _strdup(__VA_ARGS__)
+static inline char *_strdup(char *str);
+
#include "parts/toklist.h"
struct token {
symbol s;
stack_item v;
};
#define TOKEN_INIT(sym, val) (struct token){ .s = sym, .v = val }
-static void print_token(struct token *t);
-
symbol token_sym(struct token *t) { return t->s; }
intptr_t token_val(struct token *t) { return (intptr_t)&t->v; }
+static void print_token(struct token *t);
-static char *input;
static size_t line = 1;
static size_t active_region;
static char *next_token(char *str);
-static inline char *substring(char *str, size_t sub_end);
-static inline char *linestart(char *strstart, char *pos);
-static inline size_t tillch(char *str, size_t len, char ch);
-#define strdup(...) _strdup(__VA_ARGS__)
-static inline char *_strdup(char *str);
-
-
#include "util/queue.h"
QUEUE_GENERATE(tokbuf, struct token, 16)
+static char *input;
+
struct token *toklist_eat()
{
static struct token t;
@@ -147,13 +189,22 @@ struct token *toklist_peek() {
return &t;
}
+struct debuginfo {
+ size_t line;
+ size_t active_region;
+ char *end_ptr;
+};
+#define debuginfo_merge(out, ...) _debuginfo_merge(out, __VA_ARGS__, NULL);
+void _debuginfo_merge(struct debuginfo *out, ...);
+
+void errmsg_print(char *filename, char *input_buf, struct debuginfo *debuginfo, char *message);
+
// #define _LR_PARSER_DEBUG
#include "lr-parser.c"
int main(void)
{
- char *filename = "stdin";
-
+ static char *filename = "stdin";
static char input_buf[INPUT_CAP];
if(fread(input_buf, INPUT_CAP, 1, stdin) == INPUT_CAP) {
fprintf(stderr, "INPUT_CAP reached\n");
@@ -174,26 +225,17 @@ int main(void)
// if(token_sym(tok) == END_INPUT) break;
// } return 0;
- stack_item value;
- struct lr_errinfo *errinfo;
- if((errinfo = lr_parser(&value))) {
- char *l = linestart(input_buf, input);
-
- fprintf(stderr, "%s:%zu:%zu: ERROR: %s\n", filename, line, input - l - active_region+1, lr_err_str(errinfo));
-
- size_t indent = fprintf(stderr, " %zu ", line);
- fprintf(stderr, "| %s\n", substring(l, tillch(l, strlen(l), '\n')));
-
- fprintf(stderr, "%*s| %*s", indent, "", input - l - active_region, "");
- if(active_region == 0) active_region = 1;
- fprintf(stderr, "^"); for(size_t i = 0; i < active_region-1; i++) fprintf(stderr, "~");
-
- fprintf(stderr, "\n\n");
+ struct lr_parseinfo parseinfo;
+ void *value = lr_parser(&parseinfo);
+ if(parseinfo.type == LR_ABORTED) {
+ goto cleanup;
+ } else if(parseinfo.type) {
+ errmsg_print(filename, input_buf, NULL, lr_err_str(&parseinfo));
goto cleanup;
}
- ast_exprlist_print(value.list);
- // ast_exprlist_free(value.list);
+ ast_print(((stack_item *)value)->list);
+ ast_free(((stack_item *)value)->list);
cleanup:
dict_free(&types_dict);
@@ -213,6 +255,46 @@ static void print_token(struct token *tok)
}
}
+void _debuginfo_merge(struct debuginfo *out, ...)
+{
+ va_list ap;
+ va_start(ap, out);
+
+ *out = *va_arg(ap, struct debuginfo *);
+
+ struct debuginfo *arg;
+ while((arg = va_arg(ap, struct debuginfo *))) {
+ intptr_t start = MIN((intptr_t)out->end_ptr - out->active_region,
+ (intptr_t)arg->end_ptr - arg->active_region);
+ intptr_t end = MAX((intptr_t)out->end_ptr, (intptr_t)arg->end_ptr);
+
+ out->active_region = end - start;
+ out->end_ptr = (char *)end;
+ }
+
+ va_end(ap);
+}
+
+void errmsg_print(char *filename, char *input_buf, struct debuginfo *debuginfo, char *message)
+{
+ if(!debuginfo) debuginfo = &(struct debuginfo){.line = line, .active_region = active_region, .end_ptr = input};
+
+ char *l = linestart(input_buf, debuginfo->end_ptr);
+
+ fprintf(stderr, "%s:%zu:%zu: ERROR: %s\n", filename, debuginfo->line,
+ debuginfo->end_ptr - l - debuginfo->active_region+1,
+ message);
+
+ int indent = fprintf(stderr, " %zu ", debuginfo->line);
+ fprintf(stderr, "| %s\n", substring(l, tillch(l, strlen(l), '\n')));
+
+ fprintf(stderr, "%*s| %*s", indent, "", debuginfo->end_ptr - l - debuginfo->active_region, "");
+ if(active_region == 0) debuginfo->active_region = 1;
+ for(size_t i = 0; i < debuginfo->active_region; i++) fprintf(stderr, "~");
+
+ fprintf(stderr, "\n");
+}
+
// STR UTIL
#define strdup(...) _strdup(__VA_ARGS__)
@@ -336,9 +418,10 @@ static char *next_token(char *str)
sub_off = tillch(str + 1, off - 1, ':') + 1;
if(hasfield) tokbuf_enqueue(&TOKEN_INIT(COLON, { .num=0 }));
+ int skip = hasfield || str[0] == ':';
tokbuf_enqueue(
- &TOKEN_INIT((!hasfield && str[0] == ':') ? ATOM : IDEN,
- { .str = strdup(substring(str+hasfield, sub_off-hasfield))}));
+ &TOKEN_INIT((skip && !hasfield) ? ATOM : IDEN,
+ { .str = strdup(substring(str+skip, sub_off-skip))}));
} while(hasfield = 1, str += sub_off, off -= sub_off, off > 0);
return str;
@@ -357,6 +440,34 @@ fail:
// ast printing
+int ident = 0;
+#define INDENT() printf("%*s", ident*2, "");
+
+void ast_exprlist_print(struct list_head *list);
+
+void datatype_print(struct datatype *datatype)
+{
+ // TOOD: fix, very messy
+ switch(flags2type(datatype->typeflags)) {
+ case DATATYPE_INT: printf("int"); break;
+ case DATATYPE_ENUM: printf("enum"); break;
+ case DATATYPE_STRUCT: printf("struct"); break;
+ }
+
+ if(datatype->iden) printf("(%s)", datatype->iden);
+
+ for(int i = 0; i < 3; i++)
+ switch(flags2subtype(datatype->typeflags) & (1 << i)) {
+ case 0: break;
+ case SUBTYPE_FUNCTION:
+ printf("-function(");
+ ast_exprlist_print(datatype->function_exprlist);
+ printf(")");
+ break;
+ default: printf("-%d", i); break;
+ }
+}
+
void ast_vrbl_print(struct ast_vrbl *vrbl)
{
printf("%s%s", vrbl->is_atom ? ":" : "", vrbl->iden);
@@ -365,25 +476,25 @@ void ast_vrbl_print(struct ast_vrbl *vrbl)
void ast_fiel_print(struct ast_fiel *fiel)
{
ast_vrbl_print(&fiel->variable);
- list_for_each_entry(struct ast_strlist, entry, list, fiel->fields_strlist) {
+ list_for_each_entry(struct strlist, entry, list, fiel->fields_strlist) {
printf(":%s", entry->str);
}
}
-void ast_decl_print(struct ast_decl *decl)
-{
- // TODO: implement
-}
-
-void ast_defn_print(struct ast_defn *defn)
+void ast_decl_print(struct ast_vrbl *vrbl, struct datatype *datatype)
{
- // TODO: implement
+ ast_vrbl_print(vrbl);
+ printf("/");
+ datatype_print(datatype);
}
void ast_oprn_print(struct ast_oprn *oprn)
{
ast_exprlist_print(oprn->left_exprlist);
+
if(oprn->optype == AST_OP_AND) printf(",\n"); else printf(";\n");
+ INDENT();
+
ast_exprlist_print(oprn->right_exprlist);
}
@@ -396,21 +507,34 @@ void ast_exprlist_print(struct list_head *list)
case AST_NUMBER: printf("%d", entry->number); break;
case AST_VARIABLE: ast_vrbl_print(&entry->variable); break;
case AST_FIELDLIST: ast_fiel_print(&entry->fieldlist); break;
- case AST_DECLARATION: ast_decl_print(&entry->declaration); break;
+ case AST_DECLARATION: ast_decl_print(&entry->variable, &entry->datatype); break;
case AST_OPERATION: ast_oprn_print(&entry->operation); break;
case AST_PARENLIST:
- printf("(");
- ast_exprlist_print(entry->paren_exprlist);
- printf(")");
+ printf("(\n"); ident++;
+ INDENT(); ast_exprlist_print(entry->exprlist);
+ printf("\n"); ident--;
+ INDENT(); printf(")");
+ break;
+ case AST_BRACELIST:
+ printf("{\n"); ident++;
+ INDENT(); ast_exprlist_print(entry->exprlist);
+ printf(".\n"); ident--;
+ INDENT(); printf("}");
break;
default: fprintf(stderr, "UNKNOWN TYPE: %d\n", entry->type);
}
- printf(" ");
+
+ if(entry->list.next) printf(" ");
}
- printf("\n");
}
-void ast_exprlist_free(struct list_head *list)
+void ast_print(struct list_head *list)
+{
+ ast_exprlist_print(list);
+ printf(".\n");
+}
+
+void ast_free(struct list_head *list)
{
list_for_each_safe(l, list) {
struct ast_expr *entry = list_entry(l, typeof(*entry), list);
@@ -420,18 +544,19 @@ void ast_exprlist_free(struct list_head *list)
case AST_VARIABLE: break;
case AST_FIELDLIST:
list_for_each_safe(l, entry->fieldlist.fields_strlist)
- free(list_entry(l, struct ast_strlist, list));
+ free(list_entry(l, struct strlist, list));
break;
case AST_DECLARATION: break;
- case AST_DEFINITION: break;
case AST_OPERATION:
- ast_exprlist_free(entry->operation.left_exprlist);
- ast_exprlist_free(entry->operation.right_exprlist);
+ ast_free(entry->operation.left_exprlist);
+ ast_free(entry->operation.right_exprlist);
break;
- case AST_PARENLIST: ast_exprlist_free(entry->paren_exprlist); break;
+ case AST_BRACELIST:
+ case AST_PARENLIST: ast_free(entry->exprlist); break;
default: fprintf(stderr, "UNKNOWN TYPE: %d\n", entry->type);
}
+ ast_free(entry->datatype.function_exprlist);
free(entry);
}
}