mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-26 14:20:59 +00:00
98 lines
1.7 KiB
R
98 lines
1.7 KiB
R
#include "string.h"
|
|
#include "Cons.h"
|
|
#include "Nil.h"
|
|
#include "defs.h"
|
|
#include "SchemeString.h"
|
|
|
|
Cons *cons (SchemeObject *car, SchemeObject *cdr)
|
|
{
|
|
return [Cons newWithCar: car cdr: cdr];
|
|
}
|
|
|
|
int length (SchemeObject *foo)
|
|
{
|
|
local int len;
|
|
|
|
for (len = 0; [foo isKindOfClass: [Cons class]]; foo = [(Cons *) foo cdr]) {
|
|
len++;
|
|
}
|
|
|
|
return len;
|
|
}
|
|
|
|
BOOL isList (SchemeObject *ls)
|
|
{
|
|
return ls == [Nil nil] ||
|
|
([ls isKindOfClass: [Cons class]] &&
|
|
isList([(Cons*) ls cdr]));
|
|
}
|
|
|
|
@implementation Cons
|
|
|
|
+ (id) newWithCar: (SchemeObject *) a cdr: (SchemeObject *) d
|
|
{
|
|
return [[self alloc] initWithCar: a cdr: d];
|
|
}
|
|
|
|
- (id) initWithCar: (SchemeObject *) a cdr: (SchemeObject *) d
|
|
{
|
|
car = a;
|
|
cdr = d;
|
|
|
|
if (!car) {
|
|
print("Cons: WARNING: nil car\n");
|
|
} else if (!cdr) {
|
|
print("cons: WARNING: nil cdr\n");
|
|
}
|
|
|
|
return [super init];
|
|
}
|
|
|
|
- (SchemeObject *) car
|
|
{
|
|
return car;
|
|
}
|
|
|
|
- (void) car: (SchemeObject *) a
|
|
{
|
|
car = a;
|
|
}
|
|
|
|
- (SchemeObject *) cdr
|
|
{
|
|
return cdr;
|
|
}
|
|
|
|
- (void) cdr: (SchemeObject *) d
|
|
{
|
|
cdr = d;
|
|
}
|
|
|
|
- (void) markReachable
|
|
{
|
|
[car mark];
|
|
[cdr mark];
|
|
}
|
|
|
|
- (string) printForm
|
|
{
|
|
local string acc = "";
|
|
local id cur, next = nil;
|
|
|
|
for (cur = self; cur; cur = next) {
|
|
next = [cur cdr];
|
|
acc = acc + [[cur car] printForm];
|
|
if (next == [Nil nil]) {
|
|
next = nil;
|
|
} else if (next && ![next isKindOfClass: [Cons class]]) {
|
|
acc = acc + " . " + [next printForm];
|
|
next = nil;
|
|
} else if (next) {
|
|
acc = acc + " ";
|
|
}
|
|
}
|
|
|
|
return [[String newFromString: sprintf("(%s)", acc)] stringValue];
|
|
}
|
|
|
|
@end
|