Пример #1
0
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([]px.Parser, 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] = px.Many(argParser(last))
		larg := Atom{varArg.Name, varArg.Type}
		formals[lidx] = larg
	} else {
		ps[lidx] = argParser(last)
		formals[lidx] = last
	}
	ps[l] = px.Eof
	lambda.Meta["formal parameters"] = formals
	lambda.Meta["parameter parsexs"] = ps
}
Пример #2
0
// argParser 构造一个 parsex 解析器,判断输入数据是否与给定类型一致,如果判断成功,构造对应的
// Var。
func argParser(atom Atom) px.Parser {
	one := func(st px.ParsexState) (interface{}, error) {
		var err error
		if data, err := st.Next(typeis(atom)); err == nil {
			slot := VarSlot(atom.Type)
			slot.Set(data)
			return slot, nil
		}
		return nil, err
	}
	if atom.Name == "..." {
		return px.Many(one)
	}
	return one
}
Пример #3
0
				return nil, ParsexSignErrorf(
					"Many1 Arg Error:except 1 parser arg but %v.",
					reflect.TypeOf(param))
			}
		},
		"many": func(env Env, args ...interface{}) (Lisp, error) {
			if len(args) != 1 {
				return nil, ParsexSignErrorf("Parsex Parser Many 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.Many(parser.Parser)), nil
			default:
				return nil, ParsexSignErrorf(
					"Many Arg Error:except 1 parser arg but %v.",
					reflect.TypeOf(param))
			}
		},
		"failed": func(env Env, args ...interface{}) (Lisp, error) {
			if len(args) != 1 {
				return nil, ParsexSignErrorf("Parsex Parser Failed Error: only accept one string as arg but %v", args)
			}
			param, err := Eval(env, args[0])
			if err != nil {
				return nil, err
			}
			var str string