Esempio n. 1
0
File: math.go Progetto: 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
}
Esempio n. 2
0
File: math.go Progetto: 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
}
Esempio n. 3
0
					"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 ParsecBox(p.Either(params[0].(Parsecer).Parser, params[1].(Parsecer).Parser)), nil
		},
		"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([]p.Parser, len(params))
			for idx, prs := range params {
				if parser, ok := prs.(Parsecer); ok {
					parsers[idx] = parser.Parser
				}
				return nil, ParsexSignErrorf("Choice Args Error:except parsec parsers but %v is %v",
					prs, reflect.TypeOf(prs))
			}
			return ParsecBox(p.Choice(parsers...)), nil
		},
		"return": func(env Env, args ...interface{}) (Lisp, error) {
			if len(args) != 1 {
Esempio n. 4
0
					"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
		},
		"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 {