예제 #1
0
파일: ast.go 프로젝트: luoxing91/goLisp
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)
}
예제 #2
0
파일: typeof.go 프로젝트: luoxing91/goLisp
func (self *TypeOf) Apply(args []value.Value) value.Value {
	if len(args) != 1 {
		panic(fmt.Sprint("argument mismatch for `type-of', expected 1, given: ", len(args)))
	}
	symbol := "unknown"
	switch args[0].(type) {
	case *value.IntValue:
		symbol = "integer"
	case *value.FloatValue:
		symbol = "float"
	case *value.BoolValue:
		symbol = "bool"
	case *value.StringValue:
		symbol = "string"
	case *value.Channel:
		symbol = "channel"
	case *value.EmptyPairValue:
		symbol = "nilpair"
	case *value.PairValue:
		symbol = "pair"
	case *value.Closure:
		symbol = "procedure"
	case value.PrimFunc:
		symbol = "procedure"
	case *value.Symbol:
		symbol = args[0].(*value.Symbol).Value
	}
	return value.NewSymbol(symbol)
}
예제 #3
0
파일: tuple.go 프로젝트: luoxing91/goLisp
func (self *QuoteBase) Eval(env *scope.Scope) value.Value {
	if name, ok := self.Body.(*Name); ok {
		return value.NewSymbol(name.Identifier)
	} else {
		return self.Body.Eval(env)
	}
}