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;
}
}
|