func newi(as []string) *ts.Interpreter { i := ts.New() args := i.Accessor("args") i.Import("system").Set(args, ts.Wrap(as)) path := os.Getenv("HOME") + "/.tsirc" if _, e := os.Stat(path); e == nil { i.Load(path) } readline.LoadHistory(os.Getenv("HOME") + "/.tsihistory") readline.SetWordBreaks(" \t\n\"\\+-*/><=!:;|&[{()}].") readline.Completer = func(query, ctx string) []string { var src, res []string p := len(ctx) - len(query) - 1 if p > 0 && ctx[p] == '.' { src = i.ListAccessors() } else { src = i.ListDefined() } for _, x := range src { if strings.HasPrefix(x, query) { res = append(res, x) } } return res } return i }
func pkg(itpr *ts.Interpreter) map[string]*ts.Object { reada := itpr.Accessor("readByte") writea := itpr.Accessor("writeByte") readByte := func(s *ts.Object) (byte, bool) { b := s.Call(reada) if b == ts.False { return 0, false } return byte(b.ToInt()), true } writeByte := func(s *ts.Object, b byte) { s.Call(writea, ts.Wrap(b)) } return map[string]*ts.Object{ "read8": ts.Wrap(func(o, s *ts.Object) *ts.Object { bs := make([]byte, 0, 6) var b byte var m bool for b, m = readByte(s); m && b&0x80 != 0; b, m = readByte(s) { bs = append(bs, b) } if !m { return ts.False } bs = append(bs, b) r, _ := utf8.DecodeRune(bs) if r == utf8.RuneError { panic("bad character") } return ts.Wrap(string(r)) }), "write8": ts.Wrap(func(o, s, c *ts.Object) *ts.Object { bs := make([]byte, 6) size := utf8.EncodeRune(bs, rune(c.ToInt())) for i := 0; i < size; i++ { writeByte(s, bs[i]) } return ts.Nil }), } }
func pkg(itpr *ts.Interpreter) map[string]*ts.Object { MutexClass := ts.ObjectClass.Extend(itpr, "Mutex", ts.UserData, []ts.Slot{ ts.MSlot("create", func(o *ts.Object) *ts.Object { o.SetUserData(new(sync.Mutex)) return ts.Nil }), ts.MSlot("lock", func(o *ts.Object) *ts.Object { o.UserData().(*sync.Mutex).Lock() return ts.Nil }), ts.MSlot("unlock", func(o *ts.Object) *ts.Object { o.UserData().(*sync.Mutex).Unlock() return ts.Nil }), ts.MSlot("with", func(o, f *ts.Object) *ts.Object { m := o.UserData().(*sync.Mutex) m.Lock() defer m.Unlock() return f.Call(nil) }), }) ChanClass := ts.ObjectClass.Extend(itpr, "Channel", ts.UserData, []ts.Slot{ ts.MSlot("create", func(o *ts.Object) *ts.Object { o.SetUserData(make(chan *ts.Object)) return ts.Nil }), ts.MSlot("send", func(o, x *ts.Object) *ts.Object { o.UserData().(chan *ts.Object) <- x return ts.Nil }), ts.MSlot("receive", func(o *ts.Object) *ts.Object { return <-o.UserData().(chan *ts.Object) }), }) return map[string]*ts.Object{ "spawn": ts.Wrap(func(o, f *ts.Object) *ts.Object { go f.Call(nil) return ts.Nil }), "Mutex": MutexClass.Object(), "Channel": ChanClass.Object(), } }
func pkg(it *ts.Interpreter) map[string]*ts.Object { var Regex *ts.Class read := it.Accessor("readChar") Regex = ts.ObjectClass.Extend(it, "Regex", ts.UserData, []ts.Slot{ ts.MSlot("create", func(o, expr *ts.Object) *ts.Object { re := regexp.MustCompile(expr.ToString()) o.SetUserData(re) return ts.Nil }), ts.MSlot("match", func(o, src *ts.Object) *ts.Object { re := o.UserData().(*regexp.Regexp) r := runeReader{read, src} return ts.Wrap(re.FindReaderSubmatchIndex(r)) }), }) return map[string]*ts.Object{ "Regex": Regex.Object(), } }
func pkg(itpr *ts.Interpreter) map[string]*ts.Object { var File, Stream *ts.Class newStream := func(x interface{}) *ts.Object { s := Stream.New() s.SetUserData(x) return s } File = ts.ObjectClass.Extend(itpr, "File", 0, []ts.Slot{ ts.FSlot("path", ts.Nil), ts.MSlot("read", func(o, f *ts.Object) *ts.Object { fl, err := os.Open(File.Get(o, 0).ToString()) if err != nil { panic(err) } defer fl.Close() return f.Call(nil, newStream(fl)) }), ts.MSlot("create", func(o, p *ts.Object) *ts.Object { File.Set(o, 0, p) return ts.Nil }), ts.MSlot("exists", func(o *ts.Object) *ts.Object { _, err := os.Stat(File.Get(o, 0).ToString()) return ts.Wrap(err == nil) }), ts.MSlot("open", func(o, f, p *ts.Object) *ts.Object { path := File.Get(o, 0).ToString() flags, perm := int(f.ToInt()), os.FileMode(int(p.ToInt())) fl, err := os.OpenFile(path, flags, perm) if err != nil { panic(err) } return newStream(fl) }), ts.MSlot("write", func(o, f *ts.Object) *ts.Object { fl, err := os.Create(File.Get(o, 0).ToString()) if err != nil { panic(err) } defer fl.Close() return f.Call(nil, newStream(fl)) }), ts.MSlot("append", func(o, f *ts.Object) *ts.Object { path := File.Get(o, 0).ToString() flags := os.O_WRONLY | os.O_APPEND | os.O_CREATE fl, err := os.OpenFile(path, flags, 0666) if err != nil { panic(err) } defer fl.Close() return f.Call(nil, newStream(fl)) }), }) sFlags := ts.UserData | ts.Final Stream = ts.ObjectClass.Extend(itpr, "Stream", sFlags, []ts.Slot{ ts.MSlot("readBuffer", func(o, b *ts.Object) *ts.Object { buf := b.ToBuffer() r := o.UserData().(io.Reader) n, err := r.Read(buf) if err == io.EOF { if n == 0 { return ts.False } return ts.Wrap(n) } if err != nil { panic(err) } return ts.Wrap(n) }), ts.MSlot("writeBuffer", func(o, b *ts.Object) *ts.Object { buf := b.ToBuffer() w := o.UserData().(io.Writer) n, err := w.Write(buf) if err != nil { panic(err) } return ts.Wrap(n) }), ts.MSlot("close", func(o *ts.Object) *ts.Object { c := o.UserData().(io.Closer) err := c.Close() if err != nil { panic(err) } return ts.Nil }), }) env := map[*ts.Object]*ts.Object{} for _, x := range os.Environ() { ss := strings.Split(x, "=") env[ts.Wrap(ss[0])] = ts.Wrap(ss[1]) } return map[string]*ts.Object{ "input": newStream(os.Stdin), "output": newStream(os.Stdout), "File": File.Object(), "args": ts.Wrap(os.Args), "env": ts.Wrap(env), } }
func pkg(it *ts.Interpreter) map[string]*ts.Object { toFloat := it.Accessor("toFloat") flt := func(x *ts.Object) float64 { return x.Call(toFloat).ToFloat() } wrap1 := func(f func(a float64) float64) *ts.Object { return ts.Wrap(func(o, a *ts.Object) *ts.Object { return ts.Wrap(f(flt(a))) }) } wrap2 := func(f func(a, b float64) float64) *ts.Object { return ts.Wrap(func(o, a, b *ts.Object) *ts.Object { return ts.Wrap(f(flt(a), flt(b))) }) } return map[string]*ts.Object{ "E": ts.Wrap(math.E), "PI": ts.Wrap(math.Pi), "PHI": ts.Wrap(math.Phi), "SQRT2": ts.Wrap(math.Sqrt2), "SQRTE": ts.Wrap(math.SqrtE), "SQRTPI": ts.Wrap(math.SqrtPi), "SQRTPHI": ts.Wrap(math.SqrtPhi), "LN2": ts.Wrap(math.Ln2), "LOG2E": ts.Wrap(math.Log2E), "LN10": ts.Wrap(math.Ln10), "LOG10E": ts.Wrap(math.Log10E), "abs": wrap1(math.Abs), "acos": wrap1(math.Acos), "acosh": wrap1(math.Acosh), "asin": wrap1(math.Asin), "asinh": wrap1(math.Asinh), "atan": wrap1(math.Atan), "atanh": wrap1(math.Atanh), "cbrt": wrap1(math.Cbrt), "ceil": wrap1(math.Ceil), "cos": wrap1(math.Cos), "cosh": wrap1(math.Cosh), "erf": wrap1(math.Erf), "erfc": wrap1(math.Erfc), "exp": wrap1(math.Exp), "exp2": wrap1(math.Exp2), "expm1": wrap1(math.Expm1), "floor": wrap1(math.Floor), "gamma": wrap1(math.Gamma), "j0": wrap1(math.J0), "j1": wrap1(math.J1), "log": wrap1(math.Log), "log10": wrap1(math.Log10), "log1p": wrap1(math.Log1p), "log2": wrap1(math.Log2), "logb": wrap1(math.Logb), "sin": wrap1(math.Sin), "sinh": wrap1(math.Sinh), "sqrt": wrap1(math.Sqrt), "tan": wrap1(math.Tan), "tanh": wrap1(math.Tanh), "trunc": wrap1(math.Trunc), "y0": wrap1(math.Y0), "y1": wrap1(math.Y1), "atan2": wrap2(math.Atan2), "copysign": wrap2(math.Copysign), "dim": wrap2(math.Dim), "hypot": wrap2(math.Hypot), "max": wrap2(math.Max), "min": wrap2(math.Min), "mod": wrap2(math.Mod), "nextafter": wrap2(math.Nextafter), "pow": wrap2(math.Pow), "remainder": wrap2(math.Remainder), "ilogb": ts.Wrap(func(o, x *ts.Object) *ts.Object { return ts.Wrap(math.Ilogb(flt(x))) }), "inf": ts.Wrap(func(o, sign *ts.Object) *ts.Object { return ts.Wrap(math.Inf(int(sign.ToInt()))) }), "isInf": ts.Wrap(func(o, x, sign *ts.Object) *ts.Object { return ts.Wrap(math.IsInf(flt(x), int(sign.ToInt()))) }), "isNaN": ts.Wrap(func(o, x *ts.Object) *ts.Object { return ts.Wrap(math.IsNaN(flt(x))) }), "NaN": ts.Wrap(math.NaN()), "pow10": ts.Wrap(func(o, e *ts.Object) *ts.Object { return ts.Wrap(math.Pow10(int(e.ToInt()))) }), "jn": ts.Wrap(func(o, n, x *ts.Object) *ts.Object { return ts.Wrap(math.Jn(int(n.ToInt()), flt(x))) }), "yn": ts.Wrap(func(o, n, x *ts.Object) *ts.Object { return ts.Wrap(math.Yn(int(n.ToInt()), flt(x))) }), "seedRand": ts.Wrap(func(o, s *ts.Object) *ts.Object { rand.Seed(s.ToInt()) return ts.Nil }), "rand": ts.Wrap(func(o *ts.Object) *ts.Object { return ts.Wrap(rand.Float64()) }), } }
func pkg(itpr *ts.Interpreter) map[string]*ts.Object { var Request, Response *ts.Class Request = ts.ObjectClass.Extend(itpr, "Request", ts.UserData, []ts.Slot{ ts.PSlot("headMap", ts.Nil), ts.PSlot("formMap", ts.Nil), ts.PropSlot("method", func(o *ts.Object) *ts.Object { return ts.Wrap(o.UserData().(*http.Request).Method) }, ts.Nil), ts.PropSlot("proto", func(o *ts.Object) *ts.Object { return ts.Wrap(o.UserData().(*http.Request).Proto) }, ts.Nil), ts.PropSlot("path", func(o *ts.Object) *ts.Object { return ts.Wrap(o.UserData().(*http.Request).URL.Path) }, ts.Nil), ts.PropSlot("header", func(o *ts.Object) *ts.Object { return Request.Get(o, 0) }, ts.Nil), ts.PropSlot("form", func(o *ts.Object) *ts.Object { rv := o.UserData().(*http.Request) if err := rv.ParseMultipartForm(32 << 20); err != nil { panic(err) } fm := make(map[*ts.Object]*ts.Object) for k, v := range rv.Form { fm[ts.Wrap(k)] = ts.Wrap(v) } fmw := ts.Wrap(fm) Request.Set(o, 1, fmw) return fmw }, ts.Nil), }) wrapReq := func(r *http.Request) *ts.Object { o := Request.New() o.SetUserData(r) hm := make(map[*ts.Object]*ts.Object) for k, v := range r.Header { hm[ts.Wrap(k)] = ts.Wrap(v) } Request.Set(o, 0, ts.Wrap(hm)) if err := r.ParseForm(); err != nil { panic(err) } return o } Response = ts.ObjectClass.Extend(itpr, "Response", ts.UserData, []ts.Slot{ ts.MSlot("writeBuffer", func(o, b *ts.Object) *ts.Object { bv := b.ToBuffer() rw := o.UserData().(http.ResponseWriter) if _, err := rw.Write(bv); err != nil { panic(err) } return ts.Nil }), ts.MSlot("writeHeader", func(o, c, h *ts.Object) *ts.Object { /*cv := int(c.ToInt()) hv := h.ToHash() rw := o.UserData().(http.ResponseWriter) rwh := rw.Header() for k, v := range hv { rwh[k.(string)] = []string{v.ToString()} } rw.WriteHeader(cv)*/ return ts.Nil }), }) wrapResp := func(w http.ResponseWriter) *ts.Object { o := Response.New() o.SetUserData(w) return o } return map[string]*ts.Object{ "serve": ts.Wrap(func(o, p, f *ts.Object) *ts.Object { port := ":" + strconv.Itoa(int(p.ToInt())) hnd := func(w http.ResponseWriter, r *http.Request) { defer func() { if e := recover(); e != nil { fmt.Println("web.serve:", e) } }() f.Call(nil, wrapResp(w), wrapReq(r)) } http.ListenAndServe(port, http.HandlerFunc(hnd)) return ts.Nil }), "get": ts.Wrap(func(o, u *ts.Object) *ts.Object { resp, err := http.Get(u.ToString()) if err != nil { panic(err) } if resp.StatusCode != 200 { panic(fmt.Errorf("web.get: status %d", resp.StatusCode)) } return ts.Wrap(resp.Body) }), "post": ts.Wrap(func(o, u, form *ts.Object) *ts.Object { /*vals := url.Values{} for k, v := range form.ToHash() { vals.Add(k.(string), v.ToString()) } resp, err := http.PostForm(u.ToString(), vals) if err != nil { panic(err) } if resp.StatusCode != 200 { panic(fmt.Errorf("web.get: status %d", resp.StatusCode)) } return ts.Wrap(resp.Body)*/ return ts.Nil }), } }