func ParsexSignChecker(parser px.Parser) ArgsSignChecker { return func(args ...interface{}) error { st := px.NewStateInMemory(args) _, err := parser(st) return err } }
// NewStringState 构造一个新的基于字符串的 state func NewStringState(data string) *px.StateInMemory { buf := make([]interface{}, len(data)) for idx, r := range data { buf[idx] = r } return px.NewStateInMemory(buf) }
func LetFunc(env Env, args ...interface{}) (Lisp, error) { st := px.NewStateInMemory(args) _, err := TypeAs(LIST)(st) if err != nil { return nil, ParsexSignErrorf("Let Args Error: except args list but error: %v", err) } local := map[string]Var{} vars := args[0].(List) for _, v := range vars { declares := v.(List) varb := declares[0].(Atom) slot := VarSlot(varb.Type) value, err := Eval(env, (declares[1])) if err != nil { return nil, err } slot.Set(value) local[varb.Name] = slot } meta := map[string]interface{}{ "local": local, } let := Let{meta, args} return let, nil }
// OrExpr 是 or 表达式 func OrExpr(x, y px.Parser) LispExpr { return func(env Env, args ...interface{}) (Lisp, error) { data, err := Evals(env, args...) if err != nil { return nil, err } st := px.NewStateInMemory(data) rex, err := x(st) if err != nil { return nil, err } if b, ok := rex.(bool); ok { if b { return Q(true), nil } st.SeekTo(0) rex, err = y(st) if err != nil { return nil, err } return Q(rex), nil } return nil, ParsexSignErrorf("Unknow howto combine %v or %v for %v", x, y, data) } }
func TestAddx0(t *testing.T) { var data = []interface{}{0, 1, 2, 3, 4, 5, 6} st := px.NewStateInMemory(data) s, err := addx(st) if err != nil { t.Fatalf("except error is nil but %v", err) } if s.(Int) != 21 { t.Fatalf("except sum 0~6 is 21 but got %v", s) } }
// GetArgs 方法为将传入的 args 的 gisp 值从指定环境中解析出来,然后传入 parser 。 func GetArgs(env Env, parser px.Parser, args []interface{}) ([]interface{}, error) { ret, err := Evals(env, args...) if err != nil { return nil, err } st := px.NewStateInMemory(ret) _, err = parser(st) if err != nil { return nil, fmt.Errorf("Args Type Sign Check got error:%v", err) } return ret, nil }
// LambdaExpr 生成一个封装后的 Lambda 表达式 func LambdaExpr(env Env, args ...interface{}) (Tasker, error) { st := px.NewStateInMemory(args) _, err := TypeAs(LIST)(st) if err != nil { return nil, ParsexSignErrorf("Lambda Args Error: except args list but error: %v", err) } lptr, err := DeclareLambda(env, args[0].(List), args[1:]...) if err != nil { return nil, fmt.Errorf("Lambda Args Error: except lambda tasker but error: %v", err) } return Q(lptr).Eval, nil }
// MatchArgsSign 校验参数是否匹配 func (lambda Lambda) MatchArgsSign(env Env, args ...interface{}) (interface{}, error) { params := make([]interface{}, len(args)) for idx, arg := range args { param, err := Eval(env, arg) if err != nil { return nil, err } params[idx] = param } pxs := lambda.Meta["parameter parsexs"].([]px.Parser) st := px.NewStateInMemory(params) return px.UnionAll(pxs...)(st) }
// ExtExpr 带扩展环境 func ExtExpr(extExpr func(env Env) px.Parser) LispExpr { return func(env Env, args ...interface{}) (Lisp, error) { data, err := Evals(env, args...) if err != nil { return nil, err } st := px.NewStateInMemory(data) ret, err := extExpr(env)(st) if err != nil { return nil, err } return Q(ret), nil } }
func (mrm mrMul) Task(env Env, args ...interface{}) (Lisp, error) { params, err := Evals(env, args...) if err != nil { return nil, err } st := px.NewStateInMemory(params) data, err := mrm.argsParser(st) if err != nil { return nil, err } return TaskBox{func(env Env) (interface{}, error) { vals := data.([]interface{}) m := vals[0].(money) for _, r := range vals[1].([]interface{}) { m = m.Mul(r.(Float)) } return m, nil }}, nil }
// ParsexReverseExpr 是倒排运算 func ParsexReverseExpr(pxExpr px.Parser) LispExpr { return func(env Env, args ...interface{}) (Lisp, error) { data, err := Evals(env, args...) if err != nil { return nil, err } l := len(data) last := l - 1 datax := make([]interface{}, l) for idx, item := range data { datax[last-idx] = item } st := px.NewStateInMemory(data) x, err := pxExpr(st) if err != nil { return nil, err } return Q(x), nil } }
// Axiom 是基本的 LISP 公理实现,尽可能贴近原始的 LISP 公理描述,但是部分实现对实际的 golang // 环境做了妥协 var Axiom = Toolkit{ Meta: map[string]interface{}{ "name": "axiom", "category": "package", }, Content: map[string]interface{}{ "quote": LispExpr(func(env Env, args ...interface{}) (Lisp, error) { if len(args) != 1 { return nil, fmt.Errorf("Quote Args Error: except only one arg but %v", args) } return Q(Q(args[0])), nil }), "var": LispExpr(func(env Env, args ...interface{}) (Lisp, error) { st := px.NewStateInMemory(args) _, err := px.Binds_(TypeAs(ATOM), px.Either(px.Try(px.Eof), px.Bind_(px.AnyOne, px.Eof)))(st) if err != nil { return nil, err } first := args[0].(Atom) slot := VarSlot(first.Type) if len(args) == 1 { err := env.Defvar(first.Name, slot) return Q(nil), err } val, err := Eval(env, args[1]) slot.Set(val) err = env.Defvar(first.Name, slot) return Q(val), err
"category": "package", }, Content: map[string]interface{}{ "state": func(env Env, args ...interface{}) (Lisp, error) { if len(args) != 1 { return nil, ParsexSignErrorf("Parsex Arg Error:except args has 1 arg.") } param, err := Eval(env, args[0]) if err != nil { return nil, err } switch data := param.(type) { case string: return Q(NewStringState(data)), nil case List: return Q(px.NewStateInMemory(data)), nil default: return nil, fmt.Errorf("Parsex Error: Except create a state from a string or List but %v", data) } }, "s2str": func(env Env, args ...interface{}) (Lisp, error) { if len(args) != 1 { return nil, ParsexSignErrorf("Slice to string Arg Error:except args has 1 arg.") } param, err := Eval(env, args[0]) if err != nil { return nil, err } var ( slice []interface{} ok bool