01: package gnu.mapping;
02:
03: /** This is a constraint used to catch unbound variables. */
04:
05: public class UnboundConstraint extends Constraint {
06: Environment environment;
07:
08: static UnboundConstraint instance;
09:
10: public static UnboundConstraint getInstance(Environment environment) {
11: UnboundConstraint result;
12: if (environment != null) {
13: result = environment.unboundConstraint;
14: if (result == null) {
15: result = new UnboundConstraint(environment);
16: environment.unboundConstraint = result;
17: }
18: } else {
19: result = instance;
20: if (result == null) {
21: result = new UnboundConstraint(null);
22: instance = result;
23: }
24: }
25: return result;
26: }
27:
28: public static UnboundConstraint getInstance(Binding binding) {
29: Constraint constraint = binding.constraint;
30: if (constraint instanceof UnboundConstraint)
31: return (UnboundConstraint) binding.constraint;
32: return getInstance(constraint.getEnvironment(binding));
33: }
34:
35: public UnboundConstraint(Environment environment) {
36: this .environment = environment;
37: }
38:
39: public Object get(Binding binding, Object defaultValue) {
40: // Before reporting an error, check parent environment.
41: Object value = binding.value;
42: if (value == null && environment != null
43: && environment.previous != null)
44: binding.value = value = environment.previous.lookup(binding
45: .getName());
46: if (value != null)
47: return ((Binding) value).get();
48: return defaultValue;
49: }
50:
51: public boolean isBound(Binding binding) {
52: return false;
53: }
54:
55: public void set(Binding binding, Object value) {
56: Environment env = getEnvironment(binding);
57: if (env != null && env.locked)
58: throw new IllegalStateException(
59: "attempt to modify variable: " + binding.getName()
60: + " locked environment");
61: synchronized (binding) {
62: if (binding.constraint == this )
63: binding.setConstraint(TrivialConstraint
64: .getInstance(env));
65: binding.constraint.set(binding, value);
66: }
67: }
68:
69: public Environment getEnvironment(Binding binding) {
70: return environment;
71: }
72: }
|