func compare(st px.ParsexState) (interface{}, error) { l, err := px.Bind(px.Choice( px.Bind(IntValue, LessThanNumber), px.Bind(NumberValue, LessThanFloat), px.Bind(px.StringVal, LessThanString), px.Bind(TimeValue, LessThanTime), ), func(l interface{}) px.Parser { return func(st px.ParsexState) (interface{}, error) { _, err := px.Eof(st) if err != nil { return nil, ParsexSignErrorf("less args sign error: except eof") } return l, nil } })(st) if err == nil { return l, nil } return nil, ParsexSignErrorf("Except two lessable values compare but error %v", err) }
// return false, true or nil func lessOption(env Env) px.Parser { return func(st px.ParsexState) (interface{}, error) { l, err := px.Bind(px.Choice( px.Try(px.Bind(IntValue, LessThanNumber)), px.Try(px.Bind(NumberValue, LessThanFloat)), px.Try(px.Bind(px.StringVal, LessThanString)), px.Try(px.Bind(TimeValue, LessThanTime)), px.Try(px.Bind(ListValue, LessThanListOption(env))), px.Bind(px.AnyOne, LessThanNil), ), func(l interface{}) px.Parser { return func(st px.ParsexState) (interface{}, error) { _, err := px.Eof(st) if err != nil { return nil, ParsexSignErrorf("less args sign error: except eof") } return l, nil } })(st) if err == nil { return l, nil } return nil, ParsexSignErrorf("Except two lessable values or nil compare but error: %v", err) } }
}, "choice": func(env Env, args ...interface{}) (Lisp, error) { ptype := reflect.TypeOf((px.Parser)(nil)) params, err := GetArgs(env, px.ManyTil(TypeAs(ptype), px.Eof), args) if err != nil { return nil, err } parsers := make([]px.Parser, len(params)) for idx, prs := range params { if parser, ok := prs.(Parsexer); ok { parsers[idx] = parser.Parser } return nil, ParsexSignErrorf("Choice Args Error:except parsec parsers but %v is %v", prs, reflect.TypeOf(prs)) } return ParsexBox(px.Choice(parsers...)), nil }, "return": func(env Env, args ...interface{}) (Lisp, error) { if len(args) != 1 { return nil, ParsexSignErrorf("Parsex Parser Return Error: only accept one parsex parser as arg but %v", args) } param, err := Eval(env, args[0]) if err != nil { return nil, err } return ParsexBox(px.Return(param)), nil }, "option": func(env Env, args ...interface{}) (Lisp, error) { if len(args) != 2 { return nil, ParsexSignErrorf("Parsex Parser Option Error: only accept two parsex parser as arg but %v", args) }
func ExtReverseExpr(expr func(Env) px.Parser) LispExpr { return func(env Env, args ...interface{}) (Lisp, error) { return ParsexReverseExpr(expr(env))(env, args...) } } var addExpr = ParsexExpr(addx) var subExpr = ParsexExpr(subx) var mulExpr = ParsexExpr(mulx) var divExpr = ParsexExpr(divx) var lessExpr = ExtExpr(less) var lsoExpr = ExtExpr(lessOption) var leExpr = OrExtRExpr(equals, less) var leoExpr = OrExtRExpr(equalsOption, lessOption) var cmpExpr = ParsexExpr(compare) var greatExpr = ExtReverseExpr(less) var gtoExpr = ExtReverseExpr(lessOption) var geExpr = OrExtRExpr(equals, less) var geoExpr = func(env Env, args ...interface{}) (Lisp, error) { st := px.NewStateInMemory(args) ret, err := px.Choice(px.Try(NotParsex(less(env))), FalseIfHasNil)(st) if err != nil { return nil, err } return Q(ret), nil } var eqsExpr = ParsexExpr(equals) var eqsoExpr = ParsexExpr(equalsOption) var neqsExpr = NotExpr(eqsExpr) var neqsoExpr = ParsexExpr(neqsOption)