コード例 #1
0
ファイル: ast.go プロジェクト: luoxing91/goLisp
func (self *Name) Eval(env *scope.Scope) value.Value {
	if val := env.Lookup(self.Identifier); val != nil {
		return val.(value.Value)
	} else {
		panic(fmt.Sprintf("%s: undefined identifier", self.Identifier))
	}
}
コード例 #2
0
ファイル: ast.go プロジェクト: luoxing91/goLisp
func BindArguments(env *scope.Scope, params Node, args value.Value) {
	if name, ok := params.(*Name); ok && args == value.NilPairValue {
		// ((lambda x <body>) '())
		env.Put(name.Identifier, args)
		return
	}
	for {
		if params == NilPair && args == value.NilPairValue {
			return
		} else if params == NilPair && args != value.NilPairValue {
			panic(fmt.Sprint("too many arguments"))
		} else if params != NilPair && args == value.NilPairValue {
			panic(fmt.Sprint("missing arguments"))
		}
		switch params.(type) {
		case *Pair:
			// R5RS declare first element must be a *Name*
			name, _ := params.(*Pair).First.(*Name)
			pair, ok := args.(*value.PairValue)
			if !ok {
				panic(fmt.Sprint("arguments does not match given number"))
			}
			env.Put(name.Identifier, pair.First)
			params = params.(*Pair).Second
			args = pair.Second
		case *Name:
			env.Put(params.(*Name).Identifier, args)
			return
		}
	}
}