summaryrefslogtreecommitdiff
path: root/MLKLexicalContext.m
diff options
context:
space:
mode:
authorMatthias Andreas Benkard <matthias@benkard.de>2008-06-30 21:04:34 +0200
committerMatthias Andreas Benkard <matthias@benkard.de>2008-06-30 21:04:34 +0200
commiteb968f738101d87b2d0e170d757ea10a27bbb867 (patch)
tree3841ee113f61a48ce9ba6f08bc42e2ecd1418152 /MLKLexicalContext.m
parentee2d7b7d9bb5ab87dc7986407ee44acd6bcad429 (diff)
Create environments upon binding when needed.
Diffstat (limited to 'MLKLexicalContext.m')
-rw-r--r--MLKLexicalContext.m79
1 files changed, 56 insertions, 23 deletions
diff --git a/MLKLexicalContext.m b/MLKLexicalContext.m
index f41b05c..545c3c1 100644
--- a/MLKLexicalContext.m
+++ b/MLKLexicalContext.m
@@ -138,6 +138,13 @@ static MLKSymbol *LEXICAL;
-(void) addMacro:(id <MLKFuncallable>)value forSymbol:(MLKSymbol *)symbol
{
+ if (_parent && _macros == _parent->_macros)
+ _macros = [[MLKEnvironment alloc] initWithParent:_parent->_macros
+ values:nil];
+ else if (!_macros)
+ _macros = [[MLKEnvironment alloc] initWithParent:nil
+ values:nil];
+
[_knownMacros addObject:symbol];
[_macros addValue:value forSymbol:symbol];
}
@@ -154,6 +161,13 @@ static MLKSymbol *LEXICAL;
-(void) addCompilerMacro:(id <MLKFuncallable>)value forSymbol:(MLKSymbol *)symbol
{
+ if (_parent && _compilerMacros == _parent->_compilerMacros)
+ _compilerMacros = [[MLKEnvironment alloc] initWithParent:_parent->_compilerMacros
+ values:nil];
+ else if (!_compilerMacros)
+ _compilerMacros = [[MLKEnvironment alloc] initWithParent:nil
+ values:nil];
+
[_knownCompilerMacros addObject:symbol];
[_compilerMacros addValue:value forSymbol:symbol];
}
@@ -170,6 +184,13 @@ static MLKSymbol *LEXICAL;
-(void) addSymbolMacro:(id <MLKFuncallable>)value forSymbol:(MLKSymbol *)symbol
{
+ if (_parent && _symbolMacros == _parent->_symbolMacros)
+ _symbolMacros = [[MLKEnvironment alloc] initWithParent:_parent->_symbolMacros
+ values:nil];
+ else if (!_symbolMacros)
+ _symbolMacros = [[MLKEnvironment alloc] initWithParent:nil
+ values:nil];
+
[_knownSymbolMacros addObject:symbol];
[_symbolMacros addValue:value forSymbol:symbol];
}
@@ -221,36 +242,48 @@ static MLKSymbol *LEXICAL;
{
id rest;
- rest = _declarations;
- while (rest)
+ symbol = symbol ? (id)symbol : (id)[NSNull null];
+
+ if ([_variables containsObject:symbol])
{
- id item = [rest car];
- if ([item isKindOfClass:[MLKCons class]] && [[item cdr] car] == symbol)
+ // The variable was introduced in this lexical context.
+ rest = _declarations;
+ while (rest)
{
- if ([item car] == LEXICAL)
- return YES;
- else if ([item car] == SPECIAL)
- return NO;
+ id item = [rest car];
+ if ([item isKindOfClass:[MLKCons class]] && [[item cdr] car] == symbol)
+ {
+ if ([item car] == LEXICAL)
+ return YES;
+ else if ([item car] == SPECIAL)
+ return NO;
+ }
+ rest = [rest cdr];
}
- rest = [rest cdr];
- }
- // Has the variable been globally proclaimed special?
- rest = [MLKLexicalContext globalContext]->_declarations;
- while (rest)
- {
- id item = [rest car];
- if ([[item cdr] car] == symbol)
+ // Has the variable been globally proclaimed special?
+ rest = [MLKLexicalContext globalContext]->_declarations;
+ while (rest)
{
- if ([item car] == LEXICAL)
- return YES;
- else if ([item car] == SPECIAL)
- return NO;
+ id item = [rest car];
+ if ([[item cdr] car] == symbol)
+ {
+ if ([item car] == LEXICAL)
+ return YES;
+ else if ([item car] == SPECIAL)
+ return NO;
+ }
+ rest = [rest cdr];
}
- rest = [rest cdr];
- }
- return YES;
+ // The variable is apparently neither locally nor pervasively
+ // special.
+ return YES;
+ }
+ // We don't know anything about a variable of the given name. Ask the
+ // parent environment. If there is no parent, nobody seems to know
+ // anything about the variable, so we assume it's a special one.
+ else return (_parent && [_parent variableIsLexical:symbol]);
}
-(void) addVariable:(MLKSymbol *)symbol