quakeforge/ruamoko/scheme/Parser.r
Bill Currie 75ec6bf244 Clean out some unnecessary types from the progs engine and clean up the mess.
This is a nasty commit, sorry, but 99% of the commit is interdependent.
2011-01-10 12:25:31 +09:00

116 lines
2.7 KiB
R

#include "Cons.h"
#include "Parser.h"
#include "Nil.h"
#include "Error.h"
#include "defs.h"
@implementation Parser
+ (id) newFromSource: (string) s file: (string) f
{
return [[self alloc] initWithSource: s file: f];
}
- (id) initWithSource: (string) s file: (string) f
{
self = [super init];
lexer = [Lexer newFromSource: s file: f];
file = f;
return self;
}
- (SchemeObject[]) readList
{
local SchemeObject []token, res;
local integer line;
local Error []err;
line = [lexer lineNumber];
token = [self readAtomic];
if ([token isError])
return token;
if (!token) {
err = [Error type: "parse" message: "Unmatched open parenthesis"];
[err source: file];
[err line: [lexer lineNumber]];
return err;
}
if (token == [Symbol rightParen]) {
return [Nil nil];
} else if (token == [Symbol dot]) {
res = [self readAtomic];
if ([res isError]) return res;
if ([self readAtomic] != [Symbol rightParen]) {
err = [Error type: "parse" message: "Improper use of dot"];
[err source: file];
[err line: [lexer lineNumber]];
return err;
}
return res;
} else {
res = [self readList];
if ([res isError]) return res;
res = cons(token, res);
[res source: file];
[res line: line];
return res;
}
}
- (SchemeObject[]) readAtomic
{
local SchemeObject []token, list, res;
local integer line;
line = [lexer lineNumber];
token = [lexer nextToken];
if ([token isError]) {
return token;
}
if (!token) {
return NIL;
}
if (token == [Symbol leftParen]) {
list = [self readList];
return list;
} else if (token == [Symbol quote]) {
res = [self read];
if ([res isError]) return res;
res = cons(res, [Nil nil]);
[res source: file];
[res line: line];
res = cons([Symbol forString: "quote"], res);
[res source: file];
[res line: line];
return res;
} else return token;
}
- (SchemeObject[]) read
{
local SchemeObject []token;
local Error []err;
token = [self readAtomic];
if (token == [Symbol rightParen]) {
err = [Error type: "parse" message: "mismatched close parentheis"];
[err source: file];
[err line: [lexer lineNumber]];
return err;
}
return token;
}
- (void) markReachable
{
[lexer mark];
}
@end