aboutsummaryrefslogtreecommitdiffstats
path: root/jlox/src/com/craftinginterpreters/lox/Environment.java
diff options
context:
space:
mode:
Diffstat (limited to 'jlox/src/com/craftinginterpreters/lox/Environment.java')
-rw-r--r--jlox/src/com/craftinginterpreters/lox/Environment.java63
1 files changed, 63 insertions, 0 deletions
diff --git a/jlox/src/com/craftinginterpreters/lox/Environment.java b/jlox/src/com/craftinginterpreters/lox/Environment.java
new file mode 100644
index 0000000..407b9b3
--- /dev/null
+++ b/jlox/src/com/craftinginterpreters/lox/Environment.java
@@ -0,0 +1,63 @@
+package com.craftinginterpreters.lox;
+
+import java.util.HashMap;
+import java.util.Map;
+
+class Environment {
+ final Environment enclosing;
+ private final Map<String, Object> values = new HashMap<>();
+
+ Environment() {
+ enclosing = null;
+ }
+
+ Environment(Environment enclosing) {
+ this.enclosing = enclosing;
+ }
+
+ Object get(Token name) {
+ if (values.containsKey(name.lexeme)) {
+ return values.get(name.lexeme);
+ }
+
+ if (enclosing != null)
+ return enclosing.get(name);
+
+ throw new RuntimeError(name, "Undefined variable '" + name.lexeme + "'.");
+ }
+
+ void assign(Token name, Object value) {
+ if (values.containsKey(name.lexeme)) {
+ values.put(name.lexeme, value);
+ return;
+ }
+
+ if (enclosing != null) {
+ enclosing.assign(name, value);
+ return;
+ }
+
+ throw new RuntimeError(name, "Undefined variable '" + name.lexeme + "'.");
+ }
+
+ void define(String name, Object value) {
+ values.put(name, value);
+ }
+
+ Environment ancestor(int distance) {
+ Environment environment = this;
+ for (int i = 0; i < distance; i++) {
+ environment = environment.enclosing;
+ }
+
+ return environment;
+ }
+
+ Object getAt(int distance, String name) {
+ return ancestor(distance).values.get(name);
+ }
+
+ void assignAt(int distance, Token name, Object value) {
+ ancestor(distance).values.put(name.lexeme, value);
+ }
+}