diff options
author | Danny van Kooten <dannyvankooten@users.noreply.github.com> | 2020-03-11 21:11:29 +0100 |
---|---|---|
committer | Danny van Kooten <dannyvankooten@users.noreply.github.com> | 2020-03-11 21:11:29 +0100 |
commit | 615618bb2ad91be24fb74738db0b2f290ccc50a3 (patch) | |
tree | ac49e221d86a6ac32cedd6be3baaed523769674f | |
parent | abe9d3b25be17ea0cb920e54322854bd1e2dd97f (diff) | |
download | unja-615618bb2ad91be24fb74738db0b2f290ccc50a3.tar.gz unja-615618bb2ad91be24fb74738db0b2f290ccc50a3.zip |
start evaluation
-rw-r--r-- | .gitignore | 1 | ||||
-rw-r--r-- | Makefile | 5 | ||||
-rw-r--r-- | hashmap.c | 74 | ||||
-rw-r--r-- | hashmap.h | 10 | ||||
-rw-r--r-- | hyde.c | 126 | ||||
-rw-r--r-- | hyde.dSYM/Contents/Info.plist | 20 | ||||
-rw-r--r-- | index.tpl | 10 |
7 files changed, 216 insertions, 30 deletions
@@ -1 +1,2 @@ hyde +*.dSYM
\ No newline at end of file @@ -1,6 +1,5 @@ -CFLAGS= -Wall -std=c11 -Ivendor/ +CFLAGS= -g -Wall -std=c11 -Ivendor/ LIBS= - -hyde: hyde.c vendor/mpc.c +hyde: hyde.c hashmap.c vendor/mpc.c $(CC) $(CFLAGS) $^ -o $@
\ No newline at end of file diff --git a/hashmap.c b/hashmap.c new file mode 100644 index 0000000..3d9edd0 --- /dev/null +++ b/hashmap.c @@ -0,0 +1,74 @@ +#include <string.h> +#include <stdlib.h> +#include <err.h> +#include "hashmap.h" + +struct node { + char *key; + void *value; + struct node *next; +}; + +struct hashmap *hashmap_new() { + struct hashmap *hm = malloc(sizeof *hm); + if (!hm) err(EXIT_FAILURE, "out of memory"); + for (int i=0; i < 26; i++) { + hm->buckets[i] = NULL; + } + + return hm; +} + +void hashmap_insert(struct hashmap *hm, char *key, void *value) { + int pos = (key[0] - 'a') % 26; + struct node *head = hm->buckets[pos]; + struct node *node = head; + + while (node) { + if (strcmp(node->key, key) == 0) { + node->value = value; + return; + } + node = node->next; + } + + node = malloc(sizeof *node); + node->key = key; + node->value = value; + node->next = head; + hm->buckets[pos] = node; +} + +void *hashmap_get(struct hashmap *hm, char *key) { + int pos = (key[0] - 'a') % 26; + struct node *node = hm->buckets[pos]; + while (node) { + if (strcmp(node->key, key) == 0) { + return node->value; + } + + node = node->next; + } + + return NULL; +} + +void hashmap_remove(char *key) { + +} + +void hashmap_free(struct hashmap *hm) { + struct node *node; + struct node *next; + + for (int i=0; i < 26; i++) { + node = hm->buckets[i]; + while (node) { + next = node->next; + free(node); + node = next; + } + } + + free(hm); +}
\ No newline at end of file diff --git a/hashmap.h b/hashmap.h new file mode 100644 index 0000000..a37d3d6 --- /dev/null +++ b/hashmap.h @@ -0,0 +1,10 @@ + +struct hashmap { + struct node *buckets[26]; +}; + +void hashmap_insert(struct hashmap *hm, char *key, void *value); +void *hashmap_get(struct hashmap *hm, char *key); +void hashmap_remove(char *key); +struct hashmap *hashmap_new(); +void hashmap_free(struct hashmap *hm);
\ No newline at end of file @@ -1,6 +1,13 @@ #include <stdio.h> #include <stdlib.h> -#include "mpc.h" +#include "vendor/mpc.h" +#include "hashmap.h" + + +struct post { + char title[64]; + char tags[8][32]; +}; char *read_file(char *filename) { char *input = malloc(BUFSIZ); @@ -24,43 +31,112 @@ char *read_file(char *filename) { return input; } -int main() { - mpc_parser_t *Symbol = mpc_new("symbol"); - mpc_parser_t *Text = mpc_new("text"); - mpc_parser_t *Var_Open = mpc_new("var_open"); - mpc_parser_t *Var_Close = mpc_new("var_close"); - 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 *Block = mpc_new("block"); - mpc_parser_t *For = mpc_new("for"); - mpc_parser_t *Content = mpc_new("content"); - mpc_parser_t *Template = mpc_new("template"); - mpca_lang(MPCA_LANG_DEFAULT, +int eval(char *dest, mpc_ast_t* t, struct hashmap *ctx) { + printf("%s: %s\n", t->tag, t->contents); + + if (strstr(t->tag, "content|text")) { + strcat(dest, t->contents); + return 0; + } + + if (strstr(t->tag, "content|var")) { + printf("Key: %s\n", t->contents); + char *value = hashmap_get(ctx, t->children[1]->contents); + if (value == NULL) { + return 1; + } + strcat(dest, value); + return 0; + } + + if (strstr(t->tag, "content|for")) { + char *tmp_key = t->children[2]->contents; + char *iterator_key = t->children[4]->contents; + // TODO: Make this dynamic + struct post **posts = hashmap_get(ctx, iterator_key); + for (int i=0; i < 2; i++) { + hashmap_insert(ctx, tmp_key, posts[i]); + eval(dest, t->children[6], ctx); + } + return 0; + } + + for (int i=0; i < t->children_num; i++) { + eval(dest, t->children[i], ctx); + } + + return 0; +} + +mpc_parser_t *parser_init() { + mpc_parser_t *Symbol = mpc_new("symbol"); + mpc_parser_t *Text = mpc_new("text"); + mpc_parser_t *Var_Open = mpc_new("var_open"); + mpc_parser_t *Var_Close = mpc_new("var_close"); + 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 *For = mpc_new("for"); + 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_open : \"{{\" ;" - " var_close : \"}}\" ;" + " var_open : /\{{2} ?/ ;" + " var_close : / ?}{2}/ ;" " var : <var_open> <symbol> <var_close> ;" - " block_open: \"{%\" ;" - " block_close: \"%}\" ;" - " for : <block_open> \"for\" <symbol> \"in\" <symbol> <block_close> <content>* <block_open> \"endfor\" <block_close> ;" + " block_open: /\{\% ?/ ;" + " block_close: / ?\%}/ ;" + " for : <block_open> \"for \" <symbol> \" in \" <symbol> <block_close> <content>* <block_open> \"endfor\" <block_close> ;" " text : /[^{][^{%]*/ ;" " content : <var> | <for> | <text>;" " template : /^/ <content>* /$/ ;", Symbol, Var_Open, Var_Close, Var, Block_Open, Block_Close, For, Text, Content, Template, NULL); + return Template; +} - char *content = read_file("index.tpl"); - - mpc_result_t r; +void template(char *tmpl, struct hashmap *ctx) { + mpc_parser_t *parser = parser_init(); + mpc_result_t r; - if (mpc_parse("input", content, Template, &r)) { + if (mpc_parse("input", tmpl, parser, &r)) { mpc_ast_print(r.output); + + // FIXME: Allocate precisely + char *output = malloc(strlen(tmpl) * 2); + output[0] = '\0'; + eval(output, r.output, ctx); + printf("Template: \n%s", output); + mpc_ast_delete(r.output); + free(output); } else { mpc_err_print(r.error); mpc_err_delete(r.error); } +} + + +int main() { + char *input = read_file("index.tpl"); + + struct hashmap *ctx = hashmap_new(); + hashmap_insert(ctx, "title", "Hello world"); + + struct post home = { + .title = "Homepage", + .tags = { + "Tag 1", "Tag 2" + } + }; + hashmap_insert(ctx, "home", &home); + + struct post posts[] = { + { .title = "Post 1", .tags = { "p1t1" } }, + { .title = "Post 2", .tags = { "p2t1" } }, + }; + hashmap_insert(ctx, "posts", &posts); - mpc_cleanup(11, Symbol, Var_Open, Var_Close, Var, Block_Open, Block_Close, For, Block, Text, Content, Template); - free(content); + template(input, ctx); + hashmap_free(ctx); + free(input); }
\ No newline at end of file diff --git a/hyde.dSYM/Contents/Info.plist b/hyde.dSYM/Contents/Info.plist new file mode 100644 index 0000000..f51e946 --- /dev/null +++ b/hyde.dSYM/Contents/Info.plist @@ -0,0 +1,20 @@ +<?xml version="1.0" encoding="UTF-8"?> +<!DOCTYPE plist PUBLIC "-//Apple Computer//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"> +<plist version="1.0"> + <dict> + <key>CFBundleDevelopmentRegion</key> + <string>English</string> + <key>CFBundleIdentifier</key> + <string>com.apple.xcode.dsym.hyde</string> + <key>CFBundleInfoDictionaryVersion</key> + <string>6.0</string> + <key>CFBundlePackageType</key> + <string>dSYM</string> + <key>CFBundleSignature</key> + <string>????</string> + <key>CFBundleShortVersionString</key> + <string>1.0</string> + <key>CFBundleVersion</key> + <string>1</string> + </dict> +</plist> @@ -1,14 +1,20 @@ -# Title +# List of titles - {{ title }} - {{title}} - {{ title}} - {{title }} # Dot notation -{{ user.name }} +{{ home.title }} # For block {% for p in posts %} - {{ p.title }} + + ( + {% for t in p.tags %} + {{ t }}, + {% endfor %} + ) {% endfor %} |