-
Notifications
You must be signed in to change notification settings - Fork 0
/
lecture11_symbol_lookup_environments
114 lines (88 loc) · 3.21 KB
/
lecture11_symbol_lookup_environments
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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
//
// environments
//
// represent environments in environment diagrams
// do this using frames
// frames has two lists
// list of names
// list of corresponding values
// make a pair of that
// head gives name, tail gives values
// how do we actually access the environments
``
// environment structure that is outside the control and stash but related to both
function enclosing_environment(env) { return tail(env); }
function first_frame(env) { return head(env); }
const the_empty_environment = null;
// const the_global_environment = the_empty_environment;
// null is our empty environment
// the global environment is initially the empty environment
function make_frame(symbols, values) { return pair(symbols, values); }
function frame_symbols(frame) { return head(frame); }
function frame_values(frame) { return tail(frame); }
// extends the given encironment by taking
// given list of names, list of values and enclosing environment
// makes a new environment that extends the enclosing environement
// by making a new frame
// so environments are just lists of frames
function extend_environment(symbols, vals, base_env) {
return length(symbols) === length(vals)
? pair(make_frame(symbols, vals), base_env)
: length(symbols) < length(vals)
? error("too many arguments supplied: " +
stringify(symbols) + ", " +
stringify(vals))
: error("too few arguments supplied: " +
stringify(symbols) + ", " +
stringify(vals));
}
// access function
// start from innermost frame (current environment)
// and go up until find what we are looking for
function lookup_symbol_value(symbol, env) {
function env_loop(env) {
function scan(symbols, vals) {
return is_null(symbols)
? env_loop(enclosing_environment(env))
: symbol === head(symbols)
? head(vals)
: scan(tail(symbols), tail(vals));
}
if (env === the_empty_environment) {
error(symbol, "unbound name");
} else {
const frame = first_frame(env);
return scan(frame_symbols(frame), frame_values(frame));
}
}
return env_loop(env);
}
// program than assigns a given value to a new value
function assign_symbol_value(symbol, val, env) {
function env_loop(env) {
function scan(symbols, vals) {
return is_null(symbols)
? env_loop(enclosing_environment(env))
: symbol === head(symbols)
? set_head(vals, val)
: scan(tail(symbols), tail(vals));
}
if (env === the_empty_environment) {
error(symbol, "unbound name -- assignment");
} else {
const frame = first_frame(env);
return scan(frame_symbols(frame), frame_values(frame));
}
}
return env_loop(env);
}
const test_env =
list(
make_frame(list("a", "b", "c"),
list(1, 2, 3)),
make_frame(list("v", "w", "x"),
list(4, 5, 42)),
make_frame(list("y", "z"),
list(7, 8)));
draw_data(test_env);
lookup_symbol_value("x", test_env);