func (self *LetStar) Eval(env *scope.Scope) value.Value { // Let* is similar to let, but the bindings are performed sequentially // from left to right, and the region of a binding indicated by // (<variable> <init>) is that part of the let* expression to the right // of the binding. Thus the second binding is done in an environment in // which the first binding is visible, and so on. for i := 0; i < len(self.Patterns); i++ { env = scope.NewScope(env) binder.Define(env, self.Patterns[i].Identifier, self.Exprs[i].Eval(env)) } return self.Body.Eval(env) }
func (self *Let) Eval(s *scope.Scope) value.Value { // The <init>s are evaluated in the current environment // (in some unspecified order), the <variable>s are bound // to fresh locations holding the results, the <body> is // evaluated in the extended environment, and the value(s) // of the last expression of <body> is(are) returned. env := scope.NewScope(s) extended := scope.NewScope(s) for i := 0; i < len(self.Patterns); i++ { binder.Define(extended, self.Patterns[i].Identifier, self.Exprs[i].Eval(env)) } return self.Body.Eval(extended) }
func (self *LetRec) Eval(s *scope.Scope) value.Value { // The <variable>s are bound to fresh locations holding undefined values, // the <init>s are evaluated in the resulting environment // (in some unspecified order), each <variable> is assigned to the result of // the corresponding <init>, the <body> is evaluated in the resulting // environment, and the value(s) of the last expression in <body> is(are) // returned. Each binding of a <variable> has the entire letrec expression // as its region, making it possible to define mutually recursive procedures. env := scope.NewScope(s) extended := make([]*scope.Scope, len(self.Patterns)) for i := 0; i < len(self.Patterns); i++ { extended[i] = scope.NewScope(env) binder.Define(extended[i], self.Patterns[i].Identifier, self.Exprs[i].Eval(env)) } for i := 0; i < len(extended); i++ { env.PutAll(extended[i]) } return self.Body.Eval(env) }
func (self *Define) Eval(env *scope.Scope) value.Value { binder.Define(env, self.Pattern.Identifier, self.Value.Eval(env)) return nil }