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
|
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#include "interpreter.h"
#include "util.h"
int namehash(const char *name,int mod){
int h=0;
for(int i=0;name[i];i++)h+=name[i];
return h%mod;
}
#define VMAP_HASHSZ (61)
typedef struct Vllist{
char *name;
AST *value;
struct Vllist *next;
} Vllist;
typedef struct Scope{
Vllist *vmap[VMAP_HASHSZ];
struct Scope *next;
} Scope;
typedef struct Symbolstore{
int sz,len;
char **syms;
} Symbolstore;
struct InterState{
Scope *scope;
Symbolstore ss;
};
Scope* scope_make(void){
Scope *scope=malloc(1,Scope);
memset(scope->vmap,0,VMAP_HASHSZ*sizeof(Vllist*));
scope->next=NULL;
return scope;
}
InterState* inter_make(void){
InterState *is=malloc(1,InterState);
is->scope=scope_make();
is->ss.sz=16;
is->ss.len=0;
is->ss.syms=malloc(is->ss.sz,char*);
return is;
}
static void scope_destroy(Scope *scope,bool recursive){
do {
for(int i=0;i<VMAP_HASHSZ;i++){
while(scope->vmap[i]){
Vllist *ll=scope->vmap[i];
free(ll->name);
ast_free(ll->value);
scope->vmap[i]=ll->next;
free(ll);
}
}
Scope *next=scope->next;
free(scope);
scope=next;
} while(recursive&&scope);
}
void inter_destroy(InterState *is){
assert(is);
scope_destroy(is->scope,true);
for(int i=0;i<is->ss.len;i++)free(is->ss.syms[i]);
free(is->ss.syms);
}
static void intern_symbols(InterState *is,AST *ast){
switch(ast->type){
case AST_LIST:
for(int i=0;i<ast->l.len;i++)intern_symbols(is,ast->l.nodes[i]);
break;
case AST_SYMBOL:{
if(ast->s.symid>=0&&ast->s.symid<is->ss.len&&strcmp(ast->s.name,is->ss.syms[ast->s.symid])==0){
break;
}
int i;
for(i=0;i<is->ss.len;i++){
if(strcmp(is->ss.syms[i],ast->s.name)==0)break;
}
if(i<is->ss.len){
ast->s.symid=i;
break;
}
if(is->ss.len==is->ss.sz){
is->ss.sz*=2;
is->ss.syms=realloc(is->ss.syms,is->ss.sz,char*);
}
is->ss.syms[is->ss.len++]=copystring(ast->s.name);
break;
}
case AST_WORD:
case AST_NUMBER:
case AST_STRING:
break;
}
}
void inter_runcode(InterState *is,AST *ast){
intern_symbols(is,ast);
}
|