aboutsummaryrefslogtreecommitdiff
path: root/object
diff options
context:
space:
mode:
authorDimitri Sokolyuk <demon@dim13.org>2017-05-20 16:27:42 +0200
committerDimitri Sokolyuk <demon@dim13.org>2017-05-20 16:27:42 +0200
commit69fc902f8f5fd8f36db0991f6ba4faeabb3090fa (patch)
tree36b77847cb8548047f3c8bc7a9d40ae017b86658 /object
parentce78935009d931faf2db7e882929a7a4c95ce3e0 (diff)
03
Diffstat (limited to 'object')
-rw-r--r--object/environment.go30
-rw-r--r--object/object.go85
2 files changed, 115 insertions, 0 deletions
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()
+}