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(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 }), } }