예제 #1
0
파일: main.go 프로젝트: bobappleyard/tsi
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
}
예제 #2
0
파일: text.go 프로젝트: bobappleyard/ts
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
		}),
	}
}
예제 #3
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(),
	}
}
예제 #4
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(),
	}
}
예제 #5
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),
	}
}
예제 #6
0
파일: math.go 프로젝트: bobappleyard/ts
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())
		}),
	}

}
예제 #7
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
		}),
	}
}