From 69fc902f8f5fd8f36db0991f6ba4faeabb3090fa Mon Sep 17 00:00:00 2001 From: Dimitri Sokolyuk Date: Sat, 20 May 2017 16:27:42 +0200 Subject: 03 --- object/environment.go | 30 ++++++++++++++++++ object/object.go | 85 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 object/environment.go create mode 100644 object/object.go (limited to 'object') diff --git a/object/environment.go b/object/environment.go new file mode 100644 index 0000000..6f31070 --- /dev/null +++ b/object/environment.go @@ -0,0 +1,30 @@ +package object + +func NewEnclosedEnvironment(outer *Environment) *Environment { + env := NewEnvironment() + env.outer = outer + return env +} + +func NewEnvironment() *Environment { + s := make(map[string]Object) + return &Environment{store: s, outer: nil} +} + +type Environment struct { + store map[string]Object + outer *Environment +} + +func (e *Environment) Get(name string) (Object, bool) { + obj, ok := e.store[name] + if !ok && e.outer != nil { + obj, ok = e.outer.Get(name) + } + return obj, ok +} + +func (e *Environment) Set(name string, val Object) Object { + e.store[name] = val + return val +} diff --git a/object/object.go b/object/object.go new file mode 100644 index 0000000..cdde084 --- /dev/null +++ b/object/object.go @@ -0,0 +1,85 @@ +package object + +import ( + "bytes" + "fmt" + "monkey/ast" + "strings" +) + +type ObjectType string + +const ( + NULL_OBJ = "NULL" + ERROR_OBJ = "ERROR" + + INTEGER_OBJ = "INTEGER" + BOOLEAN_OBJ = "BOOLEAN" + + RETURN_VALUE_OBJ = "RETURN_VALUE" + + FUNCTION_OBJ = "FUNCTION" +) + +type Object interface { + Type() ObjectType + Inspect() string +} + +type Integer struct { + Value int64 +} + +func (i *Integer) Type() ObjectType { return INTEGER_OBJ } +func (i *Integer) Inspect() string { return fmt.Sprintf("%d", i.Value) } + +type Boolean struct { + Value bool +} + +func (b *Boolean) Type() ObjectType { return BOOLEAN_OBJ } +func (b *Boolean) Inspect() string { return fmt.Sprintf("%t", b.Value) } + +type Null struct{} + +func (n *Null) Type() ObjectType { return NULL_OBJ } +func (n *Null) Inspect() string { return "null" } + +type ReturnValue struct { + Value Object +} + +func (rv *ReturnValue) Type() ObjectType { return RETURN_VALUE_OBJ } +func (rv *ReturnValue) Inspect() string { return rv.Value.Inspect() } + +type Error struct { + Message string +} + +func (e *Error) Type() ObjectType { return ERROR_OBJ } +func (e *Error) Inspect() string { return "ERROR: " + e.Message } + +type Function struct { + Parameters []*ast.Identifier + Body *ast.BlockStatement + Env *Environment +} + +func (f *Function) Type() ObjectType { return FUNCTION_OBJ } +func (f *Function) Inspect() string { + var out bytes.Buffer + + params := []string{} + for _, p := range f.Parameters { + params = append(params, p.String()) + } + + out.WriteString("fn") + out.WriteString("(") + out.WriteString(strings.Join(params, ", ")) + out.WriteString(") {\n") + out.WriteString(f.Body.String()) + out.WriteString("\n}") + + return out.String() +} -- cgit v1.2.3