diff options
author | tomsmeding <tom.smeding@gmail.com> | 2016-08-20 13:34:26 +0200 |
---|---|---|
committer | tomsmeding <tom.smeding@gmail.com> | 2016-08-20 13:34:26 +0200 |
commit | 44602cb35735575c15cfcb92779337778649df8a (patch) | |
tree | cbc84a873f407f0e1e9fd86ad215f98a4834043f | |
parent | eade4187ba0ae04fe8e6eed9a1e33bfd44b73c06 (diff) |
Intern symbols
-rw-r--r-- | interpreter.c | 38 | ||||
-rw-r--r-- | interpreter.h | 2 |
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 |