#include #include #include #include #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;ivmap[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;iss.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;il.len;i++)intern_symbols(is,ast->l.nodes[i]); break; case AST_SYMBOL:{ if(ast->s.symid>=0&&ast->s.symidss.len&&strcmp(ast->s.name,is->ss.syms[ast->s.symid])==0){ break; } int i; for(i=0;iss.len;i++){ if(strcmp(is->ss.syms[i],ast->s.name)==0)break; } if(iss.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); }