diff options
| author | Kai Stevenson <kai@kaistevenson.com> | 2023-02-15 15:53:33 -0800 |
|---|---|---|
| committer | Kai Stevenson <kai@kaistevenson.com> | 2023-02-15 15:53:33 -0800 |
| commit | f5985c65df468e49109febcad2a3937aea801b89 (patch) | |
| tree | 6c3d9bd1074c972f013f628d72a91374b8d98f5a | |
| parent | 7e696a40e51aa35b003aa9c3fc72139b34cddc71 (diff) | |
types. eq() internal function
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | Makefile | 2 | ||||
| -rw-r--r-- | parse.c | 31 | ||||
| -rw-r--r-- | parse.h | 11 | ||||
| -rw-r--r-- | precedent.c | 67 | ||||
| -rw-r--r-- | precedent.h | 5 |
6 files changed, 100 insertions, 17 deletions
@@ -4,3 +4,4 @@ a.exe precedent *.core vgcore.* +*.dSYM/ @@ -1,4 +1,4 @@ -CFLAGS=-I. -pthread -Wall -Wextra -Wpedantic -std=c99 -march=native -O3 -lm +CFLAGS=-I. -pthread -Wall -Wextra -Wpedantic -std=c99 -O3 -lm CFLAGS+= -Wshadow -Wstrict-prototypes -Wundef -Wpointer-arith -Wcast-align -Wstrict-overflow=5 -Wswitch-default CFLAGS+= -Wunreachable-code -Wswitch-enum -Wformat=2 -g PREFIX ?= /usr @@ -5,6 +5,16 @@ #include "parse.h" #include "hashtable.h" +int symtoi(sym_t* symbol) { + return *((int*)symbol->name); +} +float symtof(sym_t* symbol) { + return *((float*)symbol->name); +} +char* symtos(sym_t* symbol) { + return (char*)symbol->name; +} + void symbol_add_arg(sym_t* symbol, sym_t* arg) { symbol->argCount += 1; if (symbol->argCount == 1) { @@ -46,11 +56,26 @@ symset_t* parse_symbols(char** str) { symbolName[i] = **str; if (**str == ',' || **str == ';') { (*str)++; - symbolName[i] = '\0'; sym_t* symbol = malloc(sizeof(sym_t)); symbol->province = LITERAL; - symbol->name = symbolName; symbol->argCount = 0; + symbolName[i] = '\0'; + /* TODO: float */ + /* string */ + if (isalpha(symbolName[0])) { + symbolName = realloc(symbolName, i * sizeof(char)); + symbol->name = symbolName; + symbol->litType = STRING; + } + /* int */ + else { + int v = atoi(symbolName); + int* vp = malloc(sizeof(int)); + *vp = v; + symbol->name = (void*)vp; + free(symbolName); + symbol->litType = INT; + } symset_add_symbol(symbolSet, symbol); break; } @@ -60,7 +85,7 @@ symset_t* parse_symbols(char** str) { sym_t* symbol = malloc(sizeof(sym_t)); symbol->province = KEY_REF; symbol->argCount = 0; - if(i > 1) { + if (i > 1) { symbol->name = symbolName; } else { @@ -10,8 +10,15 @@ typedef enum SymbolProvince { KEY_REF, LITERAL } prov_t; +typedef enum LiteralType { + NO_TYPE, + INT, + FLOAT, + STRING +} litType_t; typedef struct Symbol { prov_t province; + litType_t litType; void* name; struct Symbol** args; int argCount; @@ -20,6 +27,10 @@ typedef struct SymbolSet { sym_t** symbols; int count; } symset_t; + +int symtoi(sym_t* symbol); +float symtof(sym_t* symbol); +char* symtos(sym_t* symbol); void symbol_add_arg(sym_t* symbol, sym_t* arg); void symset_add_symbol(symset_t* symbolSet, sym_t* symbol); symset_t* parse_symbols(char** str); diff --git a/precedent.c b/precedent.c index 95d62e5..9d60bfd 100644 --- a/precedent.c +++ b/precedent.c @@ -1,13 +1,18 @@ #include <stdlib.h> #include <stdio.h> +#include <string.h> #include "precedent.h" #include "hashtable.h" #include "parse.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("store(print(hello;) myFunc;) myFunc()"); + sym_t* finalSymbol = parse_symbol_final("print(eq(0; 1;))"); printf("drawing program:\n"); write_symbol_visual(finalSymbol, 0); printf("\nexecuting program:\n"); @@ -23,12 +28,12 @@ void exec_all(symset_t symset) { eval(symset.symbols[i]); } } -void* eval(sym_t* symbol) { +sym_t* eval(sym_t* symbol) { if (symbol->province == LITERAL) { - return symbol->name; + return(symbol); } else if (symbol->province == KEY_REF) { - void* ir = try_eval_internal(symbol); + sym_t* ir = try_eval_internal(symbol); if (ir != NULL) { return ir; } @@ -51,30 +56,70 @@ void* eval(sym_t* symbol) { } /* internal functions? this function has side-effects */ -void* try_eval_internal(sym_t* symbol) { +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 (void*)1; + return &trueSym; } 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* 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 (void*)1; + 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")) { - /* TODO: genericize printf type */ - printf("%s\n", (char*)eval(symbol->args[0])); - return (void*)1; + 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; diff --git a/precedent.h b/precedent.h index 5f3eeae..aecf015 100644 --- a/precedent.h +++ b/precedent.h @@ -3,8 +3,9 @@ #ifndef PRECEDENT #define PRECEDENT +void throw(char* error, int symbolLocale); void exec_all(symset_t symset); -void* eval(sym_t* symbol); -void* try_eval_internal(sym_t* symbol); +sym_t* eval(sym_t* symbol); +sym_t* try_eval_internal(sym_t* symbol); #endif |
