diff options
-rw-r--r-- | src/hashmap.c | 5 | ||||
-rw-r--r-- | src/parser.c | 94 | ||||
-rw-r--r-- | src/template.c | 57 | ||||
-rw-r--r-- | tests/test_hashmap.c | 2 |
4 files changed, 129 insertions, 29 deletions
diff --git a/src/hashmap.c b/src/hashmap.c index 9f36a58..6797475 100644 --- a/src/hashmap.c +++ b/src/hashmap.c @@ -11,6 +11,7 @@ struct node { struct node *next; }; +/* allocate a new hashmap */ struct hashmap *hashmap_new() { struct hashmap *hm = malloc(sizeof *hm); if (!hm) err(EXIT_FAILURE, "out of memory"); @@ -21,6 +22,7 @@ struct hashmap *hashmap_new() { return hm; } +/* insert key-value into hashmap */ void hashmap_insert(struct hashmap *hm, char *key, void *value) { int pos = HASH(key); struct node *head = hm->buckets[pos]; @@ -41,6 +43,7 @@ void hashmap_insert(struct hashmap *hm, char *key, void *value) { hm->buckets[pos] = node; } +/* retrieve value by key */ void *hashmap_get(struct hashmap *hm, char *key) { int pos = HASH(key); struct node *node = hm->buckets[pos]; @@ -55,6 +58,7 @@ void *hashmap_get(struct hashmap *hm, char *key) { return NULL; } +/* retrieve value by key, handles dot notation for nested hashmaps */ void *hashmap_resolve(struct hashmap *hm, char *key) { char tmp_key[64]; int i = 0; @@ -83,6 +87,7 @@ void hashmap_remove(char *key) { // TODO: Implement this } +/* free hashmap related memory */ void hashmap_free(struct hashmap *hm) { struct node *node; struct node *next; diff --git a/src/parser.c b/src/parser.c new file mode 100644 index 0000000..e61b1e5 --- /dev/null +++ b/src/parser.c @@ -0,0 +1,94 @@ + +#include <stdlib.h> +#include <string.h> + +struct text { + char *str; +}; + +struct symbol { + char *value; +}; + +struct expression { + struct symbol symbol; +}; + +struct statement { + +}; + +/* discard during parsing phase */ +struct comment {}; + + +enum node_type { + NODE_EXPR, + NODE_COMMENT, + NODE_TEXT, +}; + +struct node { + enum node_type type; + union content { + struct expression expr; + struct comment comment; + struct text text; + } content; +}; + +struct ast { + int size; + int cap; + struct node **nodes; +}; + +enum token_type { + TOK_EOF, + TOK_EXPR_OPEN, + TOK_EXPR_CLOSE, + TOK_COMMENT_OPEN, + TOK_COMMENT_CLOSE, + TOK_STMT_OPEN, + TOK_STMT_CLOSE, + TOK_MINUS, + TOK_SYMBOL, + TOK_TEXT, +}; + +struct token { + enum token_type type; + char *literal; +}; + +struct token gettoken(char *str) { + struct token t; + switch (str[0]) { + case '{': + + break; + + case '}': + + break; + + case '\0': + t.type = TOK_EOF; + break; + } + + return t; +}; + +struct ast* parse(char *str) { + struct ast* ast = malloc(sizeof *ast); + ast->size = 0; + ast->cap = 64; + ast->nodes = malloc(ast->cap * sizeof *ast->nodes); + + for (struct token t = gettoken(str); t.type != TOK_EOF; t= gettoken(str)) { + + } + + return ast; +}
\ No newline at end of file diff --git a/src/template.c b/src/template.c index 12bd8df..6211b19 100644 --- a/src/template.c +++ b/src/template.c @@ -43,7 +43,7 @@ char *trim_leading_whitespace(char *str) { int eval(char *dest, mpc_ast_t* t, struct hashmap *ctx) { static int trim_whitespace = 0; - if (strstr(t->tag, "content|var")) { + if (strstr(t->tag, "content|expression|")) { // maybe eat whitespace going backward if (strstr(t->children[1]->contents, "-")) { dest = trim_trailing_whitespace(dest); @@ -96,39 +96,40 @@ int eval(char *dest, mpc_ast_t* t, struct hashmap *ctx) { } mpc_parser_t *parser_init() { - mpc_parser_t *Symbol = mpc_new("symbol"); - mpc_parser_t *Text = mpc_new("text"); - mpc_parser_t *Var = mpc_new("var"); - mpc_parser_t *Block_Open = mpc_new("block_open"); - mpc_parser_t *Block_Close = mpc_new("block_close"); - mpc_parser_t *Comment = mpc_new("comment"); - mpc_parser_t *For = mpc_new("for"); - mpc_parser_t *Body = mpc_new("body"); - mpc_parser_t *Content = mpc_new("content"); - mpc_parser_t *Template = mpc_new("template"); + mpc_parser_t *symbol = mpc_new("symbol"); + mpc_parser_t *text = mpc_new("text"); + mpc_parser_t *expression = mpc_new("expression"); + mpc_parser_t *statement = mpc_new("statement_open"); + mpc_parser_t *statement_open = mpc_new("statement_open"); + mpc_parser_t *statement_close = mpc_new("statement_close"); + mpc_parser_t *comment = mpc_new("comment"); + mpc_parser_t *for_statement = mpc_new("for"); + mpc_parser_t *body = mpc_new("body"); + mpc_parser_t *content = mpc_new("content"); + mpc_parser_t *template = mpc_new("template"); mpca_lang(MPCA_LANG_WHITESPACE_SENSITIVE, " symbol : /[a-zA-Z_.]+/ ;" - " var : \"{{\" /-? ?/ <symbol> / ?-?/ \"}}\" ;" - " block_open: /\{\% ?/ ;" - " block_close: / ?\%}/ ;" + " text : /[^{][^{%#]*/ ;" + " expression : \"{{\" /-? */ <symbol> / *-?/ \"}}\" ;" " comment : \"{#\" /[^#][^#}]*/ \"#}\" ;" - " for : <block_open> \"for \" <symbol> \" in \" <symbol> <block_close> <body> <block_open> \"endfor\" <block_close> ;" - " text : /[^{][^{%]*/ ;" - " content : <var> | <for> | <text> | <comment>;" + " statement_open: \"{%\" /-? */;" + " statement_close: / *-?/ \"%}\";" + " for : <statement_open> \"for \" <symbol> \" in \" <symbol> <statement_close> <body> <statement_open> \"endfor\" <statement_close> ;" + " content : <expression> | <for> | <text> | <comment>;" " body : <content>* ;" " template : /^/ <body> /$/ ;", - Symbol, - Var, - Block_Open, - Block_Close, - Comment, - For, - Text, - Content, - Body, - Template, + symbol, + expression, + statement_open, + statement_close, + comment, + for_statement, + text, + content, + body, + template, NULL); - return Template; + return template; } char *template(char *tmpl, struct hashmap *ctx) { diff --git a/tests/test_hashmap.c b/tests/test_hashmap.c index b9e1cfd..14ec552 100644 --- a/tests/test_hashmap.c +++ b/tests/test_hashmap.c @@ -12,7 +12,6 @@ TEST(hashmap) { hashmap_free(hm); } - TEST(dot_notation) { struct hashmap *user = hashmap_new(); hashmap_insert(user, "name", "Danny"); @@ -21,6 +20,7 @@ TEST(dot_notation) { assert(hashmap_resolve(hm, "user") == user, "expected user hashmap, got something else"); char *value = (char *) hashmap_resolve(hm, "user.name"); assert_str(value, "Danny"); + hashmap_free(user); hashmap_free(hm); } |