コード例 #1
0
ファイル: math.go プロジェクト: zy02636/gisp
// divx 实现一个左折叠的 parsex 连除解析器,精度向上适配。
func divx(st px.ParsexState) (interface{}, error) {
	data, err := px.Try(px.ManyTil(IntValue, px.Eof))(st)
	if err == nil {
		ints := data.([]interface{})
		root := ints[0].(Int)
		for _, x := range ints[1:] {
			root /= x.(Int)
		}
		return root, nil
	}
	data, err = px.ManyTil(NumberValue, px.Eof)(st)
	if err == nil {
		numbers := data.([]interface{})
		root := numbers[0].(Float)
		for _, x := range numbers[1:] {
			root /= x.(Float)
		}
		return root, nil
	}

	if nerr, ok := err.(NotNumberError); ok {
		return nil, TypeSignError{Type: Type{FLOAT, false}, Value: nerr.Value}
	}
	return nil, err
}
コード例 #2
0
ファイル: compare.go プロジェクト: zy02636/gisp
func less(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.Bind(ListValue, LessThanList(env)),
		), 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)
	}
}
コード例 #3
0
ファイル: math.go プロジェクト: zy02636/gisp
// addx 实现一个parsex累加解析器,精度向上适配。我一直觉得应该有一个简单的高效版本,不需要回溯的
// 但是目前还没有找到。
func addx(st px.ParsexState) (interface{}, error) {
	ints, err := px.Try(px.ManyTil(IntValue, px.Eof))(st)
	if err == nil {
		root := Int(0)
		for _, x := range ints.([]interface{}) {
			root += x.(Int)
		}
		return root, nil
	}
	numbers, err := px.ManyTil(NumberValue, px.Eof)(st)
	if err == nil {
		root := Float(0)
		for _, x := range numbers.([]interface{}) {
			root += x.(Float)
		}
		return root, nil
	}

	if nerr, ok := err.(NotNumberError); ok {
		return nil, TypeSignError{Type: FLOATMUST, Value: nerr.Value}
	}
	return nil, err
}
コード例 #4
0
ファイル: channel.go プロジェクト: gale320/gisp
				}
			}},
		"chan<-": SimpleBox{
			ParsexSignChecker(px.Binds_(
				TypeAs(reflect.TypeOf((*reflect.Type)(nil)).Elem()),
				TypeAs(INT),
				px.Eof)),
			func(args ...interface{}) Tasker {
				return func(env Env) (interface{}, error) {
					return MakeSendChan(args[0].(reflect.Type), args[1].(Int)), nil
				}
			}},
		"send": SimpleBox{
			ParsexSignChecker(px.Binds_(
				TypeAs(reflect.TypeOf((*Chan)(nil))),
				px.Either(px.Try(TypeAs(ANYOPTION)), TypeAs(ANYMUST)),
				px.Eof)),
			func(args ...interface{}) Tasker {
				return func(env Env) (interface{}, error) {
					ch := args[0].(*Chan)
					ch.Send(args[1])
					return nil, nil
				}
			}},
		"send?": SimpleBox{
			ParsexSignChecker(px.Binds_(
				TypeAs(reflect.TypeOf((*Chan)(nil))),
				px.Either(px.Try(TypeAs(ANYOPTION)), TypeAs(ANYMUST)),
				px.Eof)),
			func(args ...interface{}) Tasker {
				return func(env Env) (interface{}, error) {
コード例 #5
0
ファイル: axiom.go プロジェクト: gale320/gisp
// 环境做了妥协
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
		}),
コード例 #6
0
ファイル: parsex.go プロジェクト: gale320/gisp
			}), nil
		},
		"eof":    ParsexBox(px.Eof),
		"nil":    ParsexBox(px.Nil),
		"atimex": ParsexBox(px.TimeVal),
		"try": func(env Env, args ...interface{}) (Lisp, error) {
			if len(args) != 1 {
				return nil, ParsexSignErrorf("Parsex Parser Try Error: only accept one parsex parser as arg but %v", args)
			}
			param, err := Eval(env, args[0])
			if err != nil {
				return nil, err
			}
			switch parser := param.(type) {
			case Parsexer:
				return ParsexBox(px.Try(parser.Parser)), nil
			default:
				return nil, ParsexSignErrorf(
					"Try Arg Error:except 1 parser arg but %v.",
					reflect.TypeOf(param))
			}

		},
		"either": func(env Env, args ...interface{}) (Lisp, error) {
			ptype := reflect.TypeOf((px.Parser)(nil))
			params, err := GetArgs(env, px.UnionAll(TypeAs(ptype), TypeAs(ptype), px.Eof), args)
			if err != nil {
				return nil, err
			}
			return ParsexBox(px.Either(params[0].(Parsexer).Parser, params[1].(Parsexer).Parser)), nil
		},
コード例 #7
0
ファイル: proposition.go プロジェクト: gale320/gisp
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)