From 6f2cac23a7e759c464ef52103fac929e1eeb6b10 Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Sat, 9 Oct 2021 10:30:50 -0700 Subject: feat(rc): added shell --- sys/cmd/rc/var.c | 129 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 129 insertions(+) create mode 100644 sys/cmd/rc/var.c (limited to 'sys/cmd/rc/var.c') diff --git a/sys/cmd/rc/var.c b/sys/cmd/rc/var.c new file mode 100644 index 0000000..d442369 --- /dev/null +++ b/sys/cmd/rc/var.c @@ -0,0 +1,129 @@ +#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); +} -- cgit v1.2.1