summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--MLKInterpreter.m32
1 files changed, 32 insertions, 0 deletions
diff --git a/MLKInterpreter.m b/MLKInterpreter.m
index 8237f7b..2fe49a5 100644
--- a/MLKInterpreter.m
+++ b/MLKInterpreter.m
@@ -66,6 +66,7 @@ static MLKSymbol *UNWIND_PROTECT;
static MLKSymbol *VALUES;
static MLKSymbol *_DEFMACRO;
static MLKSymbol *_LAMBDA;
+static MLKSymbol *_LOOP;
@implementation MLKInterpreter
@@ -84,6 +85,7 @@ static MLKSymbol *_LAMBDA;
THROW = [cl intern:@"THROW"];
LAMBDA = [cl intern:@"LAMBDA"];
LET = [cl intern:@"LET"];
+ _LOOP = [sys intern:@"%LOOP"];
APPLY = [cl intern:@"APPLY"];
EVAL = [cl intern:@"EVAL"];
FUNCALL = [cl intern:@"FUNCALL"];
@@ -558,6 +560,36 @@ static MLKSymbol *_LAMBDA;
return result;
}
+ else if (car == _LOOP)
+ {
+ id rest;
+
+ if (expandOnly)
+ {
+ RETURN_VALUE ([MLKCons cons:_LOOP
+ with:[[[self eval:[MLKCons cons:PROGN
+ with:[program cdr]]
+ inLexicalContext:context
+ withEnvironment:lexenv
+ expandOnly:YES]
+ objectAtIndex:0]
+ cdr]]);
+ }
+
+ while (YES)
+ {
+ rest = program;
+ while ((rest = [rest cdr]))
+ {
+ [self eval:[rest car]
+ inLexicalContext:context
+ withEnvironment:lexenv
+ expandOnly:expandOnly];
+ }
+ }
+
+ RETURN_VALUE (nil); // never reached
+ }
else if (car == PROGN)
{
id result = nil;