summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authortomsmeding <tom.smeding@gmail.com>2016-08-20 13:34:26 +0200
committertomsmeding <tom.smeding@gmail.com>2016-08-20 13:34:26 +0200
commit44602cb35735575c15cfcb92779337778649df8a (patch)
treecbc84a873f407f0e1e9fd86ad215f98a4834043f
parenteade4187ba0ae04fe8e6eed9a1e33bfd44b73c06 (diff)
Intern symbols
-rw-r--r--interpreter.c38
-rw-r--r--interpreter.h2
2 files changed, 39 insertions, 1 deletions
diff --git a/interpreter.c b/interpreter.c
index 5a3d66a..333b8c9 100644
--- a/interpreter.c
+++ b/interpreter.c
@@ -80,3 +80,41 @@ void inter_destroy(InterState *is){
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);
+}
diff --git a/interpreter.h b/interpreter.h
index 66edce0..e643494 100644
--- a/interpreter.h
+++ b/interpreter.h
@@ -7,4 +7,4 @@ typedef struct InterState InterState;
InterState* inter_make(void);
void inter_destroy(InterState *is);
-void inter_runcode(AST *ast); //updates symbol id's
+void inter_runcode(InterState *is,AST *ast); //updates symbol id's