1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.mal_lang.lib;
18
19 import java.util.HashMap;
20 import java.util.Map;
21
22
23
24
25
26 public class Scope<T> {
27 private Map<String, T> symbols;
28 public final Scope<T> parent;
29
30 public Scope() {
31 this.symbols = new HashMap<>();
32 this.parent = null;
33 }
34
35 public Scope(Scope<T> parent) {
36 this.symbols = new HashMap<>();
37 this.parent = parent;
38 }
39
40
41
42
43
44
45
46
47 public T lookup(String key) {
48 if (symbols.containsKey(key)) {
49 return symbols.get(key);
50 } else if (parent != null) {
51 return parent.lookup(key);
52 } else {
53 return null;
54 }
55 }
56
57
58
59
60
61
62
63
64 public T lookdown(String key) {
65 if (parent != null) {
66 var parentValue = parent.lookdown(key);
67 if (parentValue != null) {
68 return parentValue;
69 }
70 }
71 return symbols.get(key);
72 }
73
74
75
76
77
78
79
80 public T look(String key) {
81 return symbols.get(key);
82 }
83
84 public Scope<T> getScopeFor(String key) {
85 if (symbols.containsKey(key)) {
86 return this;
87 } else if (parent != null) {
88 return parent.getScopeFor(key);
89 } else {
90 return null;
91 }
92 }
93
94
95
96
97
98
99
100 public void add(String key, T value) {
101 symbols.put(key, value);
102 }
103
104 public Map<String, T> getSymbols() {
105 return symbols;
106 }
107
108 @Override
109 public String toString() {
110 if (parent != null) {
111 return String.format("{%s, %s}", parent.toString(), String.join(", ", symbols.keySet()));
112 } else {
113 return String.format("{%s}", String.join(", ", symbols.keySet()));
114 }
115 }
116 }