コード例 #1
0
ファイル: math.go プロジェクト: kooksee/gisp2
// divx 实现一个左折叠的 parsec 连除解析器,精度向上适配。
func divx(st p.State) (interface{}, error) {
	data, err := p.Try(p.Many(IntValue).Over(p.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 = p.Many(NumberValue).Over(p.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
ファイル: lambda.go プロジェクト: kooksee/gisp2
func (lambda *Lambda) prepareArgs(args List) {
	l := len(args)
	formals := make(List, len(args))
	if l == 0 {
		lambda.Meta["parameters parsex"] = []Var{}
		return
	}
	lidx := l - 1
	last := args[lidx].(Atom)
	// variadic function args formal as (last[::Type] ... )
	isVariadic := false
	if last.Name == "..." && len(args) > 1 {
		isVariadic = true
	}
	lambda.Meta["is variadic"] = isVariadic
	ps := make([]p.P, l+1)
	for idx, arg := range args[:lidx] {
		ps[idx] = argParser(arg.(Atom))
		formals[idx] = arg
	}
	if isVariadic {
		varArg := args[l-2].(Atom)
		ps[lidx] = p.Many(argParser(last))
		larg := Atom{varArg.Name, varArg.Type}
		formals[lidx] = larg
	} else {
		ps[lidx] = argParser(last)
		formals[lidx] = last
	}
	ps[l] = p.EOF
	lambda.Meta["formal parameters"] = formals
	lambda.Meta["parameter parsexs"] = ps
}
コード例 #3
0
ファイル: parsec.go プロジェクト: MarchLiu/pjson
// ObjectParser 实现数组解析器
func ObjectParser() p.P {
	return func(st p.State) (interface{}, error) {
		left := p.Chr('{').Then(Skip)
		right := Skip.Then(p.Chr('}'))
		empty := p.Between(left, right, Skip)

		object, err := p.Between(left, right, p.Many(p.Choice(objectBodyParser, p.NChr('}'))))(st)
		if err != nil {
			_, e := empty(st)
			if e != nil {
				return nil, err
			}
			return Object{}, nil
		}

		switch o := object.(type) {
		case Object:
			return O(o), nil
		case map[string]interface{}:
			return object.(map[string]interface{}), nil
		default:
			return nil, fmt.Errorf("Object Parser Error: %v type is unexpected: %v", object, reflect.TypeOf(object))
		}

	}
}
コード例 #4
0
ファイル: parsec.go プロジェクト: MarchLiu/pjson
// ListParser 实现数组解析器
func ListParser() p.P {
	return func(st p.State) (interface{}, error) {
		left := p.Chr('[').Then(Skip)
		right := Skip.Then(p.Chr(']'))
		empty := p.Between(left, right, Skip)

		list, err := p.Between(left, right, p.Many(p.Choice(p.NChr(']'), listBodyParser)))(st)
		fmt.Printf("list type :%v, value :%v, err: %v\n", reflect.TypeOf(list), list, err)
		if err != nil {
			_, e := empty(st)
			if e != nil {
				return nil, err
			}
			return List{}, nil
		}

		switch l := list.(type) {
		case List:
			return L(l), nil
		case []interface{}:
			return list.([]interface{}), nil
		default:
			return nil, fmt.Errorf("List Parser Error: %v type is unexpected: %v", list, reflect.TypeOf(list))
		}
	}
}
コード例 #5
0
ファイル: math.go プロジェクト: kooksee/gisp2
// addx 实现一个parsex累加解析器,精度向上适配。我一直觉得应该有一个简单的高效版本,不需要回溯的
// 但是目前还没有找到。
func addx(st p.State) (interface{}, error) {
	ints, err := p.Try(p.Many(IntValue).Over(p.EOF))(st)
	if err == nil {
		root := Int(0)
		for _, x := range ints.([]interface{}) {
			root += x.(Int)
		}
		return root, nil
	}
	numbers, err := p.Many(NumberValue).Over(p.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
}
コード例 #6
0
ファイル: args.go プロジェクト: kooksee/gisp2
// argParser 构造一个 parsec 解析器,判断输入数据是否与给定类型一致,如果判断成功,构造对应的
// Var。
func argParser(atom Atom) p.P {
	one := func(st p.State) (interface{}, error) {
		var err error
		if data, err := st.Next(); err == nil {
			if _, err := typeis(atom)(st.Pos(), data); err == nil {
				slot := VarSlot(atom.Type)
				slot.Set(data)
				return slot, nil
			}
		}
		return nil, err
	}
	if atom.Name == "..." {
		return p.Many(one)
	}
	return one
}
コード例 #7
0
ファイル: parses.go プロジェクト: kooksee/gisp2
func bodyParserExt(env Env) p.P {
	return p.Many(ValueParserExt(env).Over(Skip))
}
コード例 #8
0
ファイル: parses.go プロジェクト: kooksee/gisp2
	default:
		panic(st.Trap("Unknown escape sequence \\%c", r))
	}
})

// RuneParser 实现 rune 的解析
var RuneParser = p.Do(func(state p.State) interface{} {
	p.Chr('\'').Exec(state)
	c := p.Choice(p.Try(EscapeCharr), p.NChr('\'')).Exec(state)
	p.Chr('\'').Exec(state)
	return Rune(c.(rune))
})

// StringParser 实现字符串解析
var StringParser = p.Between(p.Chr('"'), p.Chr('"'),
	p.Many(p.Choice(p.Try(EscapeChars), p.NChr('"')))).Bind(p.ReturnString)

func bodyParser(st p.State) (interface{}, error) {
	value, err := p.SepBy(ValueParser(), Skip)(st)
	return value, err
}

func bodyParserExt(env Env) p.P {
	return p.Many(ValueParserExt(env).Over(Skip))
}

// ListParser 实现列表解析器
func ListParser() p.P {
	return func(st p.State) (interface{}, error) {
		left := p.Chr('(').Then(Skip)
		right := Skip.Then(p.Chr(')'))
コード例 #9
0
ファイル: parsec.go プロジェクト: kooksee/gisp2
					"Try Arg Error:expect 1 parser arg but %v.",
					reflect.TypeOf(param))
			}

		},
		"either": func(env Env, args ...interface{}) (Lisp, error) {
			ptype := reflect.TypeOf((p.P)(nil))
			params, err := GetArgs(env, p.UnionAll(TypeAs(ptype), TypeAs(ptype), p.EOF), args)
			if err != nil {
				return nil, err
			}
			return ParsecBox(p.Choice(params[0].(Parsecer).Parser, params[1].(Parsecer).Parser)), nil
		},
		"choice": func(env Env, args ...interface{}) (Lisp, error) {
			ptype := reflect.TypeOf((p.P)(nil))
			params, err := GetArgs(env, p.Many(TypeAs(ptype)).Over(p.EOF), args)
			if err != nil {
				return nil, err
			}
			parsers := make([]p.P, len(params))
			for idx, prs := range params {
				if parser, ok := prs.(Parsecer); ok {
					parsers[idx] = parser.Parser
				}
				return nil, fmt.Errorf("Choice Args Error:expect 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 {