package server import ( "regexp" ) type env struct { m map[string]string } const varNamePattern = "[a-zA-Z][a-zA-Z0-9]*" var isValidVarName = regexp.MustCompile("^" + varNamePattern + "$").MatchString var varTokenRe = regexp.MustCompile("@" + varNamePattern) func (e *env) get(key string) (string, bool) { v, ok := e.m[key] return v, ok } func (e *env) set(key string, value string) { if e.m == nil { e.m = make(map[string]string) } e.m[key] = value } func (e *env) del(key string) bool { if e.m == nil { return false } if _, ok := e.m[key]; !ok { return false } delete(e.m, key) return true } func (e *env) each(f func (string, string) bool) { for k, v := range e.m { if !f(k, v) { break } } } func (e *env) clear() { e.m = nil } func varGet(r *request) { r.expect(1) if v, ok := r.c.s.env.get(r.args[0]); ok { r.Print(v) } else { r.Fatal("no such variable") } } func varSet(r *request) { r.expect(2) if !isValidVarName(r.args[0]) { r.Fatal("bad variable name") } r.c.s.env.set(r.args[0], r.args[1]) } func varDel(r *request) { r.expect(1) if !r.c.s.env.del(r.args[0]) { r.Fatal("no such variable") } } func varShow(r *request) { r.c.s.env.each(func (k string, v string) bool { r.Println(k, v) return true }) } func varClear(r *request) { r.c.s.env.clear() } func init() { newCmd(varGet, "var get") newCmd(varSet, "var set") newCmd(varDel, "var del") newCmd(varShow, "var show") newCmd(varClear, "var clear") }