#include "../include/ht.h"
#include "../include/array.h"
#include "../include/misc.h"
-#include <string.h>
#include <stdlib.h>
+#include <string.h>
pair_t *init_pair(string_t *key, void *value) {
pair_t *pair = safe_calloc(1, sizeof(pair_t));
return ht;
}
-void ht_add(ht_t *ht, string_t *key, void *value) {
+void *ht_add(ht_t *ht, string_t *key, void *value) {
if (!ht || !key)
- return;
+ return NULL;
unsigned long bnum = hash(key->s);
array_t *bucket = ht->buckets[bnum];
pair_t *p;
for (int i = 0; i < bucket->length; i++) {
pair_t *exp = bucket->items[i];
if (strcmp(exp->key->s, key->s) == 0) {
+ void *x = exp->value;
+ exp->value = value;
+ return x;
}
}
p = init_pair(key, value);
p = init_pair(key, value);
array_push(ht->buckets[bnum], p);
}
+ return NULL;
+}
+
+void pair_free(void *x, void (*freefunc)(void *)) {
+ pair_t *p = x;
+ freefunc(p->value);
+ string_free(p->key);
+ free(p);
}
-unsigned long hash(char *key) {
- return 0;
+void empty_pair_free(void *x) {
+ pair_t *p = x;
+ string_free(p->key);
+ free(p);
+}
+
+void ht_free(ht_t *ht, void (*freefunc)(void *)) {
+ pair_t *p;
+ array_t *a;
+ for (int i = 0; i < ht->size; i++) {
+ a = ht->buckets[i];
+ for (int j = 0; j < a->length; j++) {
+ p = a->items[j];
+ string_free(p->key);
+ freefunc(p->value);
+ free(p);
+ }
+ free(a->items);
+ free(a);
+ }
+ free(ht->buckets);
+ free(ht);
+}
+
+/* DJB2 HASH FUNCTION */
+unsigned long hash(char *str) {
+ unsigned long hash = 5381;
+ int c;
+
+ while ((c = *str++))
+ hash = ((hash << 5) + hash) + c; /* hash * 33 + c */
+
+ return hash;
}
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
+
#include "../include/parser.h"
+#include "../include/misc.h"
+#include "../include/lexer.h"
+
+ast_t *init_ast(string_t *v) {
+ ast_t *a = safe_calloc(1, sizeof(ast_t));
+ a->value = v;
+ return a;
+}
+
+void parser_move(parser_t *p) {
+ if (p->t) {
+ token_free(p->t);
+ p->t = lexer_collect_next(p->l);
+ }
+}
+
+void parser_lmove(parser_t *p) {
+ if (p->t)
+ p->t = lexer_collect_next(p->l);
+}
+
+void parser_consume(parser_t *p, int type) {
+ if (!p->t)
+ parser_error(p);
+ if (p->t->t != type)
+ parser_error(p);
+
+ parser_move(p);
+}
+
+ast_t *parse_type_array(parser_t *p) {
+ ast_t *a = init_ast(NULL);
+ a->subnodes = init_array();
+ parser_consume(p, TT_LBRACKET);
+
+ while (p->t->t != TT_RBRACKET) {
+ array_push(a->subnodes, parse_type(p));
+
+ switch (p->t->t) {
+ case TT_COMMA:
+ parser_consume(p, TT_COMMA);
+ break;
+ case TT_RBRACKET:
+ break;
+ default:
+ parser_error(p);
+ }
+ }
+
+ parser_consume(p, TT_RBRACKET);
+ return a;
+}
+
+ast_t *parse_type_funcall_params(parser_t *p) {
+ ast_t *a = init_ast(NULL);
+ a->subnodes = init_array();
+
+ parser_consume(p, TT_LANGLE);
+
+ while (p->t->t != TT_RANGLE) {
+ array_push(a->subnodes, parse_type(p));
+ switch (p->t->t) {
+ case TT_COMMA:
+ parser_consume(p, TT_COMMA);
+ break;
+ case TT_RANGLE:
+ break;
+ default:
+ parser_error(p);
+ }
+ }
+ parser_consume(p, TT_RANGLE);
+ return a;
+}
+
+ast_t *parse_id(parser_t *p) {
+ string_t *s = p->t->v;
+ if (p->t->t != TT_ID)
+ parser_error(p);
+ parser_lmove(p);
+ ast_t *a = init_ast(s);
+ a->t = AST_ID;
+ return a;
+}
+
+ast_t *parse_type_struct(parser_t *p) {
+ parser_consume(p, TT_LBRACE);
+ ast_t *a = init_ast(NULL);
+ a->t = AST_TYPE_STRUCT;
+ a->subnodes = init_array();
+ ast_t *pair;
+ while (p->t->t != TT_RBRACE) {
+ pair = init_ast(NULL);
+ pair->subnode = parse_id(p);
+ parser_consume(p, TT_COLON);
+ pair->s2 = parse_type(p);
+ array_push(a->subnodes, pair);
+ switch (p->t->t) {
+ case TT_COMMA:
+ parser_consume(p, TT_COMMA);
+ break;
+ case TT_RBRACE:
+ break;
+ default:
+ parser_error(p);
+ }
+ }
+ parser_consume(p, TT_RBRACE);
+ return a;
+}
+
+ast_t *parse_type(parser_t *p) {
+ switch (p->t->t) {
+ case TT_LBRACKET:
+ return parse_type_array(p);
+ case TT_LBRACE:
+ return parse_type_struct(p);
+ default:
+ break;
+ }
+}
+
+ast_t *parse_typedec(parser_t *p) {
+ ast_t *retval = init_ast(p->t->v);
+ retval->t = AST_TYPEDEC;
+ parser_lmove(p);
+ parser_consume(p, TT_ASSIGN);
+ retval->subnode = parse_type(p);
+ parser_consume(p, TT_SEMI);
+ return retval;
+}
+
+ast_t *parse_list(parser_t *p) {
+ ast_t *a = init_ast(NULL);
+ a->subnodes = init_array();
+ parser_consume(p, TT_LBRACKET);
+ while (p->t->t != TT_RBRACKET) {
+ array_push(a->subnodes, parse_expr(p));
+ switch (p->t->t) {
+ case TT_COMMA:
+ parser_consume(p, TT_COMMA);
+ break;
+ case TT_RBRACKET:
+ break;
+ default:
+ parser_error(p);
+ }
+ }
+ parser_consume(p, TT_RBRACKET);
+ return a;
+}
+
+static ast_t *parse_function(parser_t *p) {
+ ast_t *retval = init_ast(NULL);
+ retval->t = AST_FUNC;
+ ast_t *params = init_ast(NULL);
+ retval->t = AST_PARAMS;
+ ast_t *cur_param;
+ string_t *cur;
+
+ parser_consume(p, TT_LPAREN);
+ while (p->t->t != TT_RPAREN) {
+ if (p->t->t != TT_ID)
+ parser_error(p);
+
+ cur = p->t->v;
+ cur_param = init_ast(cur);
+ cur_param->t = AST_ID;
+ parser_lmove(p);
+
+ switch (p->t->t) {
+ case TT_COMMA:
+ parser_consume(p, TT_COMMA);
+ break;
+ case TT_RPAREN:
+ break;
+ default:
+ parser_error(p);
+ }
+ }
+
+ parser_consume(p, TT_RPAREN);
+ retval->subnode = params;
+ retval->s2 = parse_block(p);
+ return retval;
+}
+
+static ast_t *parse_binop(parser_t *p) {
+ if (p->t->t == TT_LPAREN) {
+ } else {
+ }
+ return NULL;
+}
+
+static ast_t *parse_mono_op(parser_t *p) {
+ string_t *val = p->t->v;
+ ast_t *mono_op;
+ if (!(strcmp(val->s, "!") == 0 || strcmp(val->s, "~") == 0)) {
+ parser_error(p);
+ return NULL;
+ }
+ parser_lmove(p);
+ mono_op = init_ast(val);
+ mono_op->t = AST_MONO_OP;
+ mono_op->subnode = parse_expr(p);
+ return mono_op;
+}
+
+ast_t *parse_char(parser_t *p) {
+ ast_t *c = init_ast(p->t->v);
+ parser_lmove(p);
+ c->t = AST_CHAR;
+ return c;
+}
+
+ast_t *parse_string(parser_t *p) {
+ ast_t *c = init_ast(p->t->v);
+ parser_lmove(p);
+ c->t = AST_STR;
+ return c;
+}
+
+ast_t *parse_funcall_params(parser_t *p) {
+ ast_t *funcall_params = init_ast(NULL);
+ funcall_params->t = AST_PARAMS;
+ funcall_params->subnodes = init_array();
+ parser_consume(p, TT_LPAREN);
+ while (p->t->t != TT_RPAREN) {
+ array_push(funcall_params->subnodes, parse_expr(p));
+ switch (p->t->t) {
+ case TT_COMMA:
+ parser_consume(p, TT_COMMA);
+ break;
+ case TT_RPAREN:
+ break;
+ default:
+ parser_error(p);
+ }
+ }
+ return funcall_params;
+}
+
+ast_t *parse_var_or_funcall(parser_t *p) {
+ ast_t *var_or_funcall = init_ast(p->t->v);
+ ast_t *r1;
+ parser_lmove(p);
+ switch (p->t->t) {
+ case TT_LPAREN:
+ r1 = parse_funcall_params(p);
+ var_or_funcall->subnode = r1;
+ return var_or_funcall;
+ case TT_PLUS:
+ case TT_MINUS:
+ case TT_TIMES:
+ case TT_DIVIDE:
+ case TT_MOD:
+
+ case TT_SHR:
+ case TT_SHL:
+ case TT_BAND:
+ case TT_BOR:
+
+ case TT_COLON:
+ r1 = parse_type(p);
+ var_or_funcall->t = AST_VARDEC;
+ var_or_funcall->subnodes = init_array();
+ array_push(var_or_funcall->subnodes, var_or_funcall);
+ array_push(var_or_funcall->subnodes, r1);
+ return var_or_funcall;
+ default:
+ parser_error(p);
+ return NULL;
+ }
+}
+
+ast_t *parse_expr(parser_t *p) {
+ ast_t *a;
+ if (strcmp(p->t->v->s, "fn") == 0) {
+ parser_consume(p, TT_KEYWORD);
+ return parse_function(p);
+ }
+ switch (p->t->t) {
+ case TT_LPAREN:
+ case TT_INT:
+ return parse_binop(p);
+ case TT_NOT:
+ case TT_BNOT:
+ return parse_mono_op(p);
+ case TT_STR:
+ return parse_string(p);
+ case TT_CHAR:
+ return parse_char(p);
+ case TT_ID:
+ return parse_var_or_funcall(p);
+ default:
+ parser_error(p);
+ return NULL;
+ }
+}
+
+ast_t *parse_statement(parser_t *p) {
+ return NULL;
+}
+
+ast_t *parse_block(parser_t *p) {
+ ast_t *block = init_ast(NULL);
+ block->subnodes = init_array();
+ block->t = AST_BLOCK;
+ parser_consume(p, TT_LBRACE);
+
+ while (p->t->t != TT_RBRACE)
+ array_push(block->subnodes, parse_statement(p));
+
+ parser_consume(p, TT_RBRACE);
+ return block;
+}
+
+static ast_t *parse_code(parser_t *p) {
+ string_t *val = p->t->v;
+ ast_t *retval = init_ast(val);
+ parser_lmove(p);
+ int cmp = p->t->t;
+ switch (cmp) {
+ case TT_COLON:
+ parser_consume(p, TT_COLON);
+ retval->subnode = parse_type(p);
+ retval->t = AST_VARDEC;
+ parser_consume(p, TT_SEMI);
+ break;
+ case TT_ASSIGN:
+ parser_consume(p, TT_ASSIGN);
+ retval->subnode = parse_expr(p);
+ retval->t = AST_VARDEF;
+ break;
+ default:
+ parser_error(p);
+ }
+
+ return retval;
+}
+
+ast_t *parse_global(parser_t *p) {
+ char *cmp = p->t->v->s;
+ if (!cmp)
+ parser_error(p);
+
+ if (strcmp(cmp, "type") == 0) {
+ parser_move(p);
+ return parse_typedec(p);
+ }
+ else
+ return parse_code(p);
+}
+
+array_t *parse_all(parser_t *p) {
+ array_t *asts = init_array();
+ while (p->t)
+ array_push(asts, parse_global(p));
+ return asts;
+}
+
+void parser_error(parser_t *p) {
+ printf("PARSER ERROR!!!!\n");
+ exit(1);
+}