summaryrefslogtreecommitdiff
path: root/precedent.c
diff options
context:
space:
mode:
authorKai Stevenson <kai@kaistevenson.com>2023-02-14 16:52:54 -0800
committerKai Stevenson <kai@kaistevenson.com>2023-02-14 16:52:54 -0800
commit7e696a40e51aa35b003aa9c3fc72139b34cddc71 (patch)
treee11bdb6734f7580157e8bedfec4ceb88a640cd5a /precedent.c
parent9df04950a492da2d51277a388bab7f1e87ae50f5 (diff)
a lot of stuff. exec/eval works now
Diffstat (limited to 'precedent.c')
-rw-r--r--precedent.c73
1 files changed, 72 insertions, 1 deletions
diff --git a/precedent.c b/precedent.c
index df7ac33..95d62e5 100644
--- a/precedent.c
+++ b/precedent.c
@@ -4,8 +4,79 @@
#include "hashtable.h"
#include "parse.h"
+hashtable_t* ht;
+
int main() {
- sym_t* finalSymbol = parse_symbol_final("store(5; test;); print(read(test;);); (hello; hello2;);");
+ sym_t* finalSymbol = parse_symbol_final("store(print(hello;) myFunc;) myFunc()");
+ printf("drawing program:\n");
write_symbol_visual(finalSymbol, 0);
+ printf("\nexecuting program:\n");
+ ht = init_hashtable(1000);
+ eval(finalSymbol);
return 0;
}
+/* TODO: read base hashtable from file to allow modularity
+pair value value? */
+void exec_all(symset_t symset) {
+ for (int i = 0; i < symset.count; i++) {
+ /* dispose of result */
+ eval(symset.symbols[i]);
+ }
+}
+void* eval(sym_t* symbol) {
+ if (symbol->province == LITERAL) {
+ return symbol->name;
+ }
+ else if (symbol->province == KEY_REF) {
+ void* ir = try_eval_internal(symbol);
+ if (ir != NULL) {
+ return ir;
+ }
+ else {
+ /* not an internal function, search hashtable for
+ next symbol */
+ /* TODO: scope */
+ pair_t* p = hashtable_get_pair(ht, (char*)symbol->name);
+ if (p != NULL) {
+ return eval((sym_t*)p->value);
+ }
+ else {
+ return NULL;
+ }
+ }
+ }
+ else {
+ return NULL;
+ }
+}
+/* internal functions?
+this function has side-effects */
+void* try_eval_internal(sym_t* symbol) {
+ unsigned int hash = get_hash((char*)symbol->name);
+ if (hash == get_hash("root")) {
+ /* execute all args as roots */
+ symset_t symset;
+ symset.symbols = symbol->args;
+ symset.count = symbol->argCount;
+ exec_all(symset);
+ return (void*)1;
+ }
+ else if (hash == get_hash("store")) {
+ /* TODO: scope */
+ /* first arg is value, remaining args are names */
+ /* TODO: recursion for multiple pairs */
+ char* key = (char*)eval(symbol->args[1]);
+ sym_t* value = symbol->args[0];
+ pair_t* p = init_pair(key, (void*)value);
+ hashtable_add_pair(ht, p);
+ return (void*)1;
+ }
+ else if (hash == get_hash("print")) {
+ /* TODO: genericize printf type */
+ printf("%s\n", (char*)eval(symbol->args[0]));
+ return (void*)1;
+ }
+ else {
+ return NULL;
+ }
+}