summaryrefslogtreecommitdiff
path: root/precedent.c
blob: 9d60bfd08045eca2f36a8e6bc0776087ab3c77cf (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
#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("print(eq(0; 1;))");
	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]);
	}
}
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;
	}
}