예제 #1
0
파일: pair.go 프로젝트: kedebug/LispEx
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.(*UnquoteSplicing); 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)
}
예제 #2
0
func (self *Cons) Apply(args []value.Value) value.Value {
	if len(args) != 2 {
		panic(fmt.Sprintf("cons: arguments mismatch, expected: 2, given: ", args))
	}
	return value.NewPairValue(args[0], args[1])
}