func eq(a, b interface{}) interface{} { var res interface{} errors.Catch( func() { res = a == b }, func(_ interface{}) { res = false }, ) return res }
func catch(thk, hnd interface{}) interface{} { t, ok := thk.(Function) if !ok { TypeError("function", t) } h, ok := hnd.(Function) if !ok { TypeError("function", h) } var res interface{} errors.Catch( func() { res = Call(t) }, func(err interface{}) { e := WrapError(err).(*errorStruct) res = Call(h, e.kind, e.msg) }, ) return res }
func (self *Scope) Repl(in io.Reader, out io.Writer) { // set stuff up inp := NewInput(in) outp := NewOutput(out) read := func() interface{} { res := inp.ReadLine() if res == EOF_OBJECT { return nil } s := res.(string) if strings.TrimSpace(s) == "" { return nil } res = ReadString(s) if res == EOF_OBJECT { return nil } return res } self.Bind(WrapPrimitives(map[string]interface{}{ "standard-input": func() interface{} { return inp }, "standard-output": func() interface{} { return outp }, })) // main loop var x interface{} for !inp.Eof() { errors.Catch( func() { Display("> ", outp) outp.Flush() x = self.Eval(read()) }, func(err interface{}) { x = err }, ) if x != nil { Write(x, outp) Display("\n", outp) } } Display("\n", outp) outp.Flush() }
func (self *Scope) Expand(x interface{}) interface{} { done := false for !done { p, ok := x.(*Pair) if !ok { break } if s, ok := p.a.(Symbol); ok { switch string(s) { case "quote": return x case "if": return Cons(p.a, self.expandList(p.d)) case "lambda": { ctx := NewScope(self) return Cons(p.a, Cons(Car(p.d), ctx.expandList(Cdr(p.d)))) } case "set!": return List(p.a, Car(p.d), self.Expand(Car(Cdr(p.d)))) case "define": return Cons(p.a, self.expandDefinition(p.d)) case "define-macro": { expr := self.expandDefinition(p.d) expr = List(Symbol("define"), Car(expr), Cons(Symbol("macro"), Cdr(expr))) self.evalExpr(expr, nil) return expr } case "begin": return Cons(p.a, self.expandList(p.d)) } errors.Catch( func() { x = self.lookupSym(s).(*macro).f.Apply(p.d) }, func(_ interface{}) { x, done = self.expandList(x), true }, ) } else { x, done = self.expandList(x), true } } return x }