diff options
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | doc/example.pcdt | 2 | ||||
| -rw-r--r-- | eval.c | 123 | ||||
| -rw-r--r-- | eval.h | 9 | ||||
| -rw-r--r-- | example.pcdt | 3 | ||||
| -rw-r--r-- | parse.c | 5 | ||||
| -rw-r--r-- | precedent.c | 140 | ||||
| -rw-r--r-- | precedent.h | 7 |
9 files changed, 167 insertions, 125 deletions
@@ -5,3 +5,4 @@ precedent *.core vgcore.* *.dSYM/ +/*.pcdt @@ -5,7 +5,7 @@ PREFIX ?= /usr BINDIR ?= ${PREFIX}/bin generate: - $(CC) -o precedent precedent.c hashtable.c scope.c parse.c $(CFLAGS) + $(CC) -o precedent precedent.c hashtable.c scope.c parse.c eval.c $(CFLAGS) clean: rm precedent diff --git a/doc/example.pcdt b/doc/example.pcdt new file mode 100644 index 0000000..68d0a84 --- /dev/null +++ b/doc/example.pcdt @@ -0,0 +1,2 @@ +store(hello;myVar;) +print(myVar()) @@ -0,0 +1,123 @@ +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include "eval.h" +#include "hashtable.h" +#include "parse.h" + +hashtable_t* ht; +const int hashtableSize = 1000; +const int trueVal = 1; +sym_t trueSym = {LITERAL, INT, (void*)&trueVal, NULL, 0}; +const int falseVal = 0; +sym_t falseSym = {LITERAL, INT, (void*)&falseVal, NULL, 0}; + +void init_eval() { + ht = init_hashtable(hashtableSize); +} +/* 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]); + } +} +sym_t* eval(sym_t* symbol) { + if (symbol->province == LITERAL) { + return(symbol); + } + else if (symbol->province == KEY_REF) { + sym_t* 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 { + printf("no matching pair in hashtable\n"); + return NULL; + } + } + } + else { + printf("no symbol province\n"); + return NULL; + } +} +/* internal functions? +this function has side-effects */ +sym_t* try_eval_internal(sym_t* symbol) { + unsigned int hash = get_hash((char*)symbol->name); + /* TODO: return last arg. that's the function return line */ + 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 &trueSym; + } + else if (hash == get_hash("store")) { + /* TODO: scope */ + /* first arg is value, remaining args are names */ + /* TODO: recursion for multiple pairs */ + char* k = symtos(eval(symbol->args[1])); + sym_t* v = eval(symbol->args[0]); + pair_t* p = init_pair(k, (void*)v); + hashtable_add_pair(ht, p); + return &trueSym; + } + else if (hash == get_hash("eq")) { + litType_t type = NO_TYPE; + void* lastVal = NULL; + for (int i = 0; i < symbol->argCount; i++) { + sym_t* v = eval(symbol->args[i]); + /* initialize */ + if (type == NO_TYPE) { + type = v->litType; + lastVal = v->name; + } + else { + /* interpret type */ + if (type == INT) { + if (symtoi(v) != *((int*)lastVal)) { + return &falseSym; + } + } + if (type == STRING) { + if (strcmp(symtos(v), (char*)lastVal) != 0) { + return &falseSym; + } + } + /* TODO: float */ + } + } + return &trueSym; + } + else if (hash == get_hash("print")) { + sym_t* v = eval(symbol->args[0]); + switch (v->litType) { + case NO_TYPE: + break; + case INT: + printf("%d\n", symtoi(v)); + break; + case FLOAT: + break; + case STRING: + printf("%s\n", symtos(v)); + break; + } + return &trueSym; + } + else { + return NULL; + } +} @@ -0,0 +1,9 @@ +#include "parse.h" +#ifndef EVAL +#define EVAL +void init_eval(void); +void throw(char* error, int symbolLocale); +void exec_all(symset_t symset); +sym_t* eval(sym_t* symbol); +sym_t* try_eval_internal(sym_t* symbol); +#endif diff --git a/example.pcdt b/example.pcdt deleted file mode 100644 index 6c4dd92..0000000 --- a/example.pcdt +++ /dev/null @@ -1,3 +0,0 @@ -store(5; myVar;); -print(read(myVar;);); -(hello; hello2;) @@ -63,7 +63,7 @@ symset_t* parse_symbols(char** str) { /* TODO: float */ /* string */ if (isalpha(symbolName[0])) { - symbolName = realloc(symbolName, i * sizeof(char)); + //symbolName = realloc(symbolName, i * sizeof(char)); symbol->name = symbolName; symbol->litType = STRING; } @@ -110,6 +110,7 @@ sym_t* parse_symbol_final(char* str) { sym_t* root = malloc(sizeof(sym_t)); root->name = "root"; root->province = KEY_REF; + root->argCount = 0; for (int s = 0; s < finalSymset->count; s++) { symbol_add_arg(root, finalSymset->symbols[s]); } @@ -119,7 +120,7 @@ void write_symbol_visual(sym_t* symbol, int offset) { for (int o = 0; o < offset; o++) { printf(" "); } - printf("%s (%s)\n", (char*)(symbol->name), symbol->province == 1 ? "KEY" : "LITERAL"); + printf("%s (%s)\n", (char*)(symbol->name), symbol->province == KEY_REF ? "KEY" : "LITERAL"); for (int i = 0; i < symbol->argCount; i++) { write_symbol_visual(symbol->args[i], offset + 4); } diff --git a/precedent.c b/precedent.c index 9d60bfd..38fc617 100644 --- a/precedent.c +++ b/precedent.c @@ -4,124 +4,38 @@ #include "precedent.h" #include "hashtable.h" #include "parse.h" +#include "eval.h" -hashtable_t* ht; -const int trueVal = 1; -sym_t trueSym = {LITERAL, INT, (void*)&trueVal, NULL, 0}; -const int falseVal = 0; -sym_t falseSym = {LITERAL, INT, (void*)&falseVal, NULL, 0}; - -int main() { - sym_t* finalSymbol = parse_symbol_final("print(eq(0; 1;))"); +int main(int argc, char** argv) { + if (argc > 1) { + if (strcmp("--version", argv[1]) == 0) { + printf("precedent, version 0.1\n"); + printf("Copyright 2023 Kai Stevenson\n"); + printf("This software was licensed under the MIT license;\n"); + printf("for more information, see the license file.\n"); + return 0; + } + else if (strcmp("--help", argv[1]) == 0) { + printf("usage: precedent [--version] [--help] <file>\n"); + return 0; + } + } + sym_t* finalSymbol = parse_symbol_final(read_file(argv[1])); printf("drawing program:\n"); write_symbol_visual(finalSymbol, 0); printf("\nexecuting program:\n"); - ht = init_hashtable(1000); + init_eval(); 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]); - } -} -sym_t* eval(sym_t* symbol) { - if (symbol->province == LITERAL) { - return(symbol); - } - else if (symbol->province == KEY_REF) { - sym_t* 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 */ -sym_t* try_eval_internal(sym_t* symbol) { - unsigned int hash = get_hash((char*)symbol->name); - /* TODO: return last arg. that's the function return line */ - 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 &trueSym; - } - else if (hash == get_hash("store")) { - /* TODO: scope */ - /* first arg is value, remaining args are names */ - /* TODO: recursion for multiple pairs */ - sym_t* v = eval(symbol->args[0]); - char* key = symtos(v); - sym_t* value = symbol->args[0]; - pair_t* p = init_pair(key, (void*)value); - hashtable_add_pair(ht, p); - return &trueSym; - } - else if (hash == get_hash("eq")) { - litType_t type = NO_TYPE; - void* lastVal = NULL; - for (int i = 0; i < symbol->argCount; i++) { - sym_t* v = eval(symbol->args[i]); - /* initialize */ - if (type == NO_TYPE) { - type = v->litType; - lastVal = v->name; - } - else { - /* interpret type */ - if (type == INT) { - if (symtoi(v) != *((int*)lastVal)) { - return &falseSym; - } - } - if (type == STRING) { - if (strcmp(symtos(v), (char*)lastVal) != 0) { - return &falseSym; - } - } - /* TODO: float */ - } - } - return &trueSym; - } - else if (hash == get_hash("print")) { - sym_t* v = eval(symbol->args[0]); - switch (v->litType) { - case NO_TYPE: - break; - case INT: - printf("%d\n", symtoi(v)); - break; - case FLOAT: - break; - case STRING: - printf("%s\n", symtos(v)); - break; - } - return &trueSym; - } - else { - return NULL; - } +char* read_file(char* path) { + FILE* file = fopen(path, "r"); + fseek(file, 0, SEEK_END); + unsigned long int length = ftell(file); + fseek(file, 0, SEEK_SET); + char* out = malloc((length + 1) * sizeof(char)); + fread(out, length, 1, file); + fclose(file); + out[length] = '\0'; + return out; } diff --git a/precedent.h b/precedent.h index aecf015..a1302d4 100644 --- a/precedent.h +++ b/precedent.h @@ -1,11 +1,6 @@ #include "parse.h" #include "hashtable.h" #ifndef PRECEDENT +char* read_file(char* path); #define PRECEDENT - -void throw(char* error, int symbolLocale); -void exec_all(symset_t symset); -sym_t* eval(sym_t* symbol); -sym_t* try_eval_internal(sym_t* symbol); - #endif |
