From 425ef692da7e74112f88f0b368f3286dba84f846 Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Thu, 18 Jun 2020 19:45:40 -0700 Subject: feat: working parser for rc shell language --- sys/cmd/rc/var.c | 108 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 108 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..dbe7c14 --- /dev/null +++ b/sys/cmd/rc/var.c @@ -0,0 +1,108 @@ +#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(Kfor, "for"); + putkw(Kin, "in"); + putkw(Kwhile, "while"); + putkw(Kif, "if"); + putkw(Kelse, "else"); + putkw(Kswitch, "switch"); + putkw(Kcase, "case"); + putkw(Kfunc, "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->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); +} -- cgit v1.2.1