#include "rc.h" Var *globals[1021] = { 0 }; struct Keyword { ushort type; char *name; struct Keyword *link; } *keywords[41]; // ----------------------------------------------------------------------- // utility static int hash(char *s, int n) { int i = 1, h = 0; while (*s) h += *s++*i++; h %= n; return (h<0)?h+n:h; } // ----------------------------------------------------------------------- // keywords static void putkw(int type, char *name) { struct Keyword *kw; int h = hash(name, arrlen(keywords)); alloc(kw); kw->type = type; kw->name = name; kw->link = keywords[h]; keywords[h] = kw; } void initkw(void) { putkw(Tfor, "for"); putkw(Tin, "in"); putkw(Twhile, "while"); putkw(Tif, "if"); putkw(Telse, "else"); putkw(Tswitch, "switch"); putkw(Tcase, "case"); putkw(Tfunc, "func"); } int kwlookup(char *name) { int t; struct Keyword *it; for(t=-1,it = keywords[hash(name, arrlen(keywords))];it;it = it->link) if(!strcmp(it->name, name)) t = it->type; return t; } // ----------------------------------------------------------------------- // variables Var * newvar(char *name, Var *link) { Var *v; alloc(v); v->name = name; v->val = 0; v->func = nil; v->funcnew = 0; v->new = 0; v->update = nil; v->link = link; return v; } /* only global lookup */ Var * gvlookup(char *name) { Var *v; int h = hash(name, arrlen(globals)); for (v = globals[h]; v; v = v->link) if (!strcmp(v->name, name)) return v; return globals[h] = newvar(strdup(name), globals[h]); } /* local + global lookup */ Var * vlookup(char *name) { Var *v; if (shell) for (v = shell->local; v; v = v->link) if (!strcmp(v->name, name)) return v; return gvlookup(name); } static void set(char *name, Word *val, int call) { Var *v = vlookup(name); freelist(v->val); v->val = val; v->new = 1; if (call && v->update) v->update(v); } void setvar(char *name, Word *val) { set(name, val, 1); }