// LetFunc 构造一个 Let 环境 func LetFunc(env Env, args ...interface{}) (Lisp, error) { st := p.NewBasicState(args) _, err := TypeAs(LIST)(&st) if err != nil { return nil, fmt.Errorf("Let Args Error: expect 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 p.P) LispExpr { return func(env Env, args ...interface{}) (Lisp, error) { data, err := Evals(env, args...) if err != nil { return nil, err } st := p.NewBasicState(data) zero := st.Begin() // zero 记录的是 pos 还处于 0 点时申请到的事务号 rex, err := x(&st) if err != nil { fmt.Println("Trace x parsec") return nil, err } if b, ok := rex.(bool); ok { if b { return Q(true), nil } st.Rollback(zero) rex, err = y(&st) if err != nil { fmt.Println("Trace y parsec") return nil, err } return Q(rex), nil } return nil, fmt.Errorf("Unknow howto combine %v or %v for %v", x, y, data) } }
// SignChecker 定义 Parsex 环境下的函数签名验证器 func SignChecker(parser p.P) ArgsSignChecker { return func(args ...interface{}) error { st := p.NewBasicState(args) _, err := parser(&st) return err } }
func TestAddx0(t *testing.T) { var data = []interface{}{0, 1, 2, 3, 4, 5, 6} st := p.NewBasicState(data) s, err := addx(&st) if err != nil { t.Fatalf("expect error is nil but %v", err) } if s.(Int) != 21 { t.Fatalf("expect sum 0~6 is 21 but got %v", s) } }
// LambdaExpr 生成一个封装后的 Lambda 表达式 func LambdaExpr(env Env, args ...interface{}) (Tasker, error) { st := p.NewBasicState(args) _, err := TypeAs(LIST)(&st) if err != nil { return nil, st.Trap("Lambda Args Error: expect 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: expect lambda tasker but error: %v", err) } return Q(lptr).Eval, nil }
// GetArgs 方法为将传入的 args 的 gisp 值从指定环境中解析出来,然后传入 parser 。 func GetArgs(env Env, parser p.P, args []interface{}) ([]interface{}, error) { ret, err := Evals(env, args...) if err != nil { return nil, err } st := p.NewBasicState(ret) _, err = parser(&st) if err != nil { return nil, fmt.Errorf("Args Type Sign Check got error:%v", err) } return ret, 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"].([]p.P) st := p.NewBasicState(params) return p.UnionAll(pxs...)(&st) }
// ExtExpr 带扩展环境 func ExtExpr(extExpr func(env Env) p.P) LispExpr { return func(env Env, args ...interface{}) (Lisp, error) { data, err := Evals(env, args...) if err != nil { return nil, err } st := p.NewBasicState(data) ret, err := extExpr(env)(&st) if err != nil { return nil, err } return Q(ret), nil } }
// ParsecReverseExpr 是倒排运算 func ParsecReverseExpr(pxExpr p.P) 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 := p.NewBasicState(data) x, err := pxExpr(&st) if err != nil { return nil, err } return Q(x), nil } }
"category": "package", }, Content: map[string]interface{}{ "state": func(env Env, args ...interface{}) (Lisp, error) { if len(args) != 1 { return nil, fmt.Errorf("Parsex Arg Error:expect 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(p.NewBasicState(data)), nil default: return nil, fmt.Errorf("Parsex Error: expect 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, fmt.Errorf("Slice to string Arg Error:expect args has 1 arg.") } param, err := Eval(env, args[0]) if err != nil { return nil, err } var ( slice []interface{} ok bool
func ExtReverseExpr(expr func(Env) p.P) LispExpr { return func(env Env, args ...interface{}) (Lisp, error) { return ParsecReverseExpr(expr(env))(env, args...) } } var addExpr = ParsecExpr(addx) var subExpr = ParsecExpr(subx) var mulExpr = ParsecExpr(mulx) var divExpr = ParsecExpr(divx) var lessExpr = ExtExpr(less) var lsoExpr = ExtExpr(lessOption) var leExpr = OrExtRExpr(equals, less) var leoExpr = OrExtRExpr(equalsOption, lessOption) var cmpExpr = ParsecExpr(compare) var greatExpr = ExtReverseExpr(less) var gtoExpr = ExtReverseExpr(lessOption) var geExpr = OrExtRExpr(equals, less) var geoExpr = func(env Env, args ...interface{}) (Lisp, error) { st := p.NewBasicState(args) ret, err := p.Choice(p.Try(NotParsec(less(env))), FalseIfHasNil)(&st) if err != nil { return nil, err } return Q(ret), nil } var eqsExpr = ParsecExpr(equals) var eqsoExpr = ParsecExpr(equalsOption) var neqsExpr = NotExpr(eqsExpr) var neqsoExpr = ParsecExpr(neqsOption)