This repository was archived by the owner on Jul 21, 2026. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathEnvironment.java
More file actions
87 lines (74 loc) · 2.71 KB
/
Copy pathEnvironment.java
File metadata and controls
87 lines (74 loc) · 2.71 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
package aether;
import aether.lexer.Token;
import java.util.HashMap;
import java.util.Map;
/**
* Manages lexical scope, variable storage, and variable resolution
* during the interpretation of Aether source programs.
* Supports nesting environments for local scopes (blocks).
*/
public class Environment {
/**
* The parent/enclosing environment scope, or null if this is the global scope.
*/
public final Environment enclosing;
/** Stores the mapping from variable names (identifiers) to their evaluated runtime values. */
private final Map<String, Object> values = new HashMap<>();
/**
* Constructs a global environment scope with no enclosing scope.
*/
public Environment() {
this.enclosing = null;
}
/**
* Constructs a nested environment scope enclosed by the specified parent scope.
*
* @param enclosing the parent environment scope
*/
public Environment(Environment enclosing) {
this.enclosing = enclosing;
}
/**
* Retrieves the value of a variable defined in this scope or its enclosing parent scopes.
*
* @param name the token representing the variable name
* @return the value associated with the variable
* @throws RuntimeException if the variable is not defined in this scope or enclosing scopes
*/
public Object get(Token name) {
if (values.containsKey(name.lexeme())) {
return values.get(name.lexeme());
}
if (enclosing != null) return enclosing.get(name);
throw new RuntimeException("Undefined variable '" + name.lexeme() + "' at line " + name.line() + ".");
}
/**
* Defines a new variable in the current scope.
* Overwrites any existing definition in the current scope level.
*
* @param name the name of the variable to define
* @param value the initial value of the variable
*/
public void define(String name, Object value) {
values.put(name, value);
}
/**
* Assigns a new value to an existing variable in this scope or its enclosing parent scopes.
* Does not define a new variable.
*
* @param name the token representing the variable name
* @param value the new value to assign
* @throws RuntimeException if the variable is not defined in this scope or enclosing scopes
*/
public 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 RuntimeException("Undefined variable '" + name.lexeme() + "' at line " + name.line() + ".");
}
}