예제 #1
0
파일: re.go 프로젝트: bobappleyard/ts
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(),
	}
}
예제 #2
0
파일: sync.go 프로젝트: bobappleyard/ts
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(),
	}
}
예제 #3
0
파일: system.go 프로젝트: bobappleyard/ts
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),
	}
}
예제 #4
0
파일: web.go 프로젝트: bobappleyard/ts
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
		}),
	}
}