summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.gitignore1
-rw-r--r--Makefile2
-rw-r--r--parse.c31
-rw-r--r--parse.h11
-rw-r--r--precedent.c67
-rw-r--r--precedent.h5
6 files changed, 100 insertions, 17 deletions
diff --git a/.gitignore b/.gitignore
index 73aa70a..27fc188 100644
--- a/.gitignore
+++ b/.gitignore
@@ -4,3 +4,4 @@ a.exe
precedent
*.core
vgcore.*
+*.dSYM/
diff --git a/Makefile b/Makefile
index a9b5503..e3dcd83 100644
--- a/Makefile
+++ b/Makefile
@@ -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
diff --git a/parse.c b/parse.c
index 43dbf54..d8a06d0 100644
--- a/parse.c
+++ b/parse.c
@@ -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 {
diff --git a/parse.h b/parse.h
index 44d1c0e..27ce444 100644
--- a/parse.h
+++ b/parse.h
@@ -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