summaryrefslogtreecommitdiff
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
parent9df04950a492da2d51277a388bab7f1e87ae50f5 (diff)
a lot of stuff. exec/eval works now
-rw-r--r--.gitignore1
-rw-r--r--hashtable.c27
-rw-r--r--hashtable.h5
-rw-r--r--parse.c8
-rw-r--r--precedent.c73
-rw-r--r--precedent.h6
-rw-r--r--scope.c2
-rw-r--r--scope.h4
8 files changed, 102 insertions, 24 deletions
diff --git a/.gitignore b/.gitignore
index a1c9445..73aa70a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -3,3 +3,4 @@ a.exe
*.swp
precedent
*.core
+vgcore.*
diff --git a/hashtable.c b/hashtable.c
index ce4c65a..7cb253c 100644
--- a/hashtable.c
+++ b/hashtable.c
@@ -1,9 +1,22 @@
#include <stdlib.h>
+#include <stdio.h>
#include "hashtable.h"
const unsigned int fnvPrime = 16777619;
const unsigned int fnvOffset = 2166136261U;
+pair_t* init_pair(char* key, void* value) {
+ pair_t* p = malloc(sizeof(pair_t));
+ p->key = key;
+ p->value = value;
+ return p;
+}
+hashtable_t* init_hashtable(unsigned int capacity) {
+ hashtable_t* ht = malloc(sizeof(hashtable_t));
+ ht->pairs = calloc(capacity, sizeof(pair_t*));
+ ht->capacity = capacity;
+ return ht;
+}
//FNV-1a hash
unsigned int get_hash(char* str) {
unsigned int hash = fnvOffset;
@@ -13,19 +26,11 @@ unsigned int get_hash(char* str) {
}
return hash;
}
-hashtable_t* init_hashtable(unsigned int capacity) {
- hashtable_t* ht = malloc(sizeof(hashtable_t));
- ht->pairs = calloc(capacity, sizeof(pair_t*));
- ht->capacity = capacity;
- return ht;
-}
/* TODO: handle collision
TODO: return 0 if something goes wrong */
-unsigned int hashtable_add_pair(hashtable_t* hashtable, pair_t pair) {
- unsigned int hash = get_hash(pair.key);
- pair_t* memPair = malloc(sizeof(pair_t));
- *memPair = pair;
- hashtable->pairs[hash % hashtable->capacity] = memPair;
+unsigned int hashtable_add_pair(hashtable_t* hashtable, pair_t* pair) {
+ unsigned int hash = get_hash(pair->key);
+ hashtable->pairs[hash % hashtable->capacity] = pair;
return hash;
}
pair_t* hashtable_get_pair(hashtable_t* hashtable, char* key) {
diff --git a/hashtable.h b/hashtable.h
index be45964..43ab23a 100644
--- a/hashtable.h
+++ b/hashtable.h
@@ -5,14 +5,15 @@ typedef struct HashPair {
char* key;
void* value;
} pair_t;
+pair_t* init_pair(char* key, void* value);
typedef struct HashTable {
pair_t** pairs;
int capacity;
int itemCount;
} hashtable_t;
-unsigned int get_hash(char* str);
hashtable_t* init_hashtable(unsigned int capacity);
-unsigned int hashtable_add_pair(hashtable_t* hashtable, pair_t pair);
+unsigned int get_hash(char* str);
+unsigned int hashtable_add_pair(hashtable_t* hashtable, pair_t* pair);
pair_t* hashtable_get_pair(hashtable_t* hashtable, char* key);
#endif
diff --git a/parse.c b/parse.c
index e48adda..43dbf54 100644
--- a/parse.c
+++ b/parse.c
@@ -35,10 +35,7 @@ symset_t* parse_symbols(char** str) {
}
if (**str == ')') {
(*str)++;
- if (**str == ';') {
- (*str)++;
- return symbolSet;
- }
+ return symbolSet;
}
else if (**str == '\0') {
return symbolSet;
@@ -62,11 +59,12 @@ symset_t* parse_symbols(char** str) {
symbolName[i] = '\0';
sym_t* symbol = malloc(sizeof(sym_t));
symbol->province = KEY_REF;
+ symbol->argCount = 0;
if(i > 1) {
symbol->name = symbolName;
}
else {
- symbol->name = "fork";
+ symbol->name = "root";
}
symset_t* symbols = parse_symbols(str);
for (int s = 0; s < symbols->count; s++) {
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;
+ }
+}
diff --git a/precedent.h b/precedent.h
index 4449f83..5f3eeae 100644
--- a/precedent.h
+++ b/precedent.h
@@ -1,8 +1,10 @@
#include "parse.h"
+#include "hashtable.h"
#ifndef PRECEDENT
#define PRECEDENT
-void execute_imperative(sym_t symbol);
-void* eval_symbol(sym_t symbol);
+void exec_all(symset_t symset);
+void* eval(sym_t* symbol);
+void* try_eval_internal(sym_t* symbol);
#endif
diff --git a/scope.c b/scope.c
index 4cc5249..afb9d5c 100644
--- a/scope.c
+++ b/scope.c
@@ -8,7 +8,7 @@ scope_t* init_scope(scope_t parent) {
*(scope->parent) = parent;
return scope;
}
-pair_t* get_pair_global(char* key, scope_t* scope) {
+pair_t* get_pair_global(scope_t* scope, char* key) {
while (scope->parent != NULL) {
pair_t* pair = hashtable_get_pair(scope->hashtable, key);
if (pair != NULL) {
diff --git a/scope.h b/scope.h
index 7847e06..d1cda0d 100644
--- a/scope.h
+++ b/scope.h
@@ -7,7 +7,7 @@ typedef struct Scope {
struct Scope* parent;
} scope_t;
scope_t* init_scope(scope_t parent);
-pair_t* get_pair_global(char* key, scope_t* scope);
-pair_t* get_pair_local(char* key, scope_t* scope);
+pair_t* get_pair_global(scope_t* scope, char* key);
+pair_t* get_pair_local(scope_t* scope, char* key);
#endif