// (1 2 '(3)) => (1 2 3) func ExpandApplyArgs(args []value.Value) value.Value { prev := value.NewPairValue(nil, nil) curr := value.NewPairValue(nil, nil) front := prev expectlist := false for i, arg := range args { switch arg.(type) { case *value.PairValue: prev.Second = arg.(*value.PairValue) for { if _, ok := arg.(*value.PairValue); ok { arg = arg.(*value.PairValue).Second } else if _, ok := arg.(*value.EmptyPairValue); ok { break } else { panic(fmt.Sprint("apply: expected list, given: ", arg)) } } expectlist = false if i != len(args)-1 { panic(fmt.Sprint("apply: expected list, given: ", arg)) } case *value.EmptyPairValue: expectlist = false if i != len(args)-1 { panic(fmt.Sprint("apply: expected list, given: ", arg)) } default: expectlist = true curr.First = arg prev.Second = curr prev = curr curr = value.NewPairValue(nil, nil) } } if expectlist { panic(fmt.Sprint("apply: expected list, given: ", args[len(args)-1])) } return front.Second }
func (self *Pair) Eval(env *scope.Scope) value.Value { var first value.Value var second value.Value if self.Second == NilPair { second = value.NilPairValue } else { switch self.Second.(type) { case *Name: second = value.NewSymbol(self.Second.(*Name).Identifier) default: second = self.Second.Eval(env) } } if name, ok := self.First.(*Name); ok { // treat Name as Symbol first = value.NewSymbol(name.Identifier) } else if _, ok := self.First.(*UnquoteBase); ok { // our parser garantees unquote-splicing only appears in quasiquote // and unquote-splicing will be evaluated to a list first = self.First.Eval(env) // () empty list must be handled if first == value.NilPairValue { return second } // seek for the last element var last value.Value = first for { switch last.(type) { case *value.PairValue: pair := last.(*value.PairValue) if pair.Second == value.NilPairValue { pair.Second = second return first } last = pair.Second default: if second == value.NilPairValue { return first } else { // `(,@(cdr '(1 . 2) 3)) panic(fmt.Sprintf("unquote-splicing: expected list?, given: %s", first)) } } } } else { first = self.First.Eval(env) } return value.NewPairValue(first, second) }
func (self *Cons) Apply(args []value.Value) value.Value { checkargsnumber(args, 2) return value.NewPairValue(args[0], args[1]) }