Scheme updates:

- Boolean type (no support in lexer yet)
	- Conditionals
	- Defines (only work correctly at top level)
	- More core builtins (apply, cons, car, cdr)
	- Variable-argument functions
	- Incremental garbage collection
	- Garbage collection fixes
	- Other misc bugs fixed
This commit is contained in:
Brian Koropoff 2005-05-06 23:25:06 +00:00
parent 5378a850b4
commit adba6b26dc
31 changed files with 484 additions and 175 deletions

View file

@ -4,5 +4,6 @@
*.src *.src
*.sym *.sym
.vimrc .vimrc
*~
Makefile.in Makefile.in
Makefile Makefile

12
ruamoko/scheme/Boolean.h Normal file
View file

@ -0,0 +1,12 @@
#ifndef __Boolean_h
#define __Boolean_h
#include "SchemeObject.h"
@interface Boolean: SchemeObject
{
}
+ (id) trueConstant;
+ (id) falseConstant;
@end
#endif //__Void_h

32
ruamoko/scheme/Boolean.r Normal file
View file

@ -0,0 +1,32 @@
#include "Boolean.h"
Boolean trueConstant;
Boolean falseConstant;
@implementation Boolean
+ (void) initialize
{
trueConstant = [Boolean new];
[trueConstant makeRootCell];
falseConstant = [Boolean new];
[falseConstant makeRootCell];
}
+ (id) trueConstant
{
return trueConstant;
}
+ (id) falseConstant
{
return falseConstant;
}
- (string) printForm
{
return self == trueConstant ? "#t" : "#f";
}
@end

View file

@ -13,8 +13,10 @@
- (void) markReachable - (void) markReachable
{ {
[literals mark]; [literals mark];
[constants makeObjectsPerformSelector: @selector(mark)]; if (constants)
[instructions makeObjectsPerformSelector: @selector(mark)]; [constants makeObjectsPerformSelector: @selector(mark)];
if (instructions)
[instructions makeObjectsPerformSelector: @selector(mark)];
} }
- (void) addInstruction: (Instruction) inst - (void) addInstruction: (Instruction) inst
@ -30,7 +32,7 @@
local integer number = [constants count]; local integer number = [constants count];
[constants addItem: c]; [constants addItem: c];
return number; return number;
} }
- (void) compile - (void) compile
{ {
@ -62,10 +64,23 @@
- (void) dealloc - (void) dealloc
{ {
[instructions release]; local Array temp;
[constants release];
if (code) if (instructions) {
temp = instructions;
instructions = NIL;
[temp release];
}
if (constants) {
temp = constants;
constants = NIL;
[temp release];
}
if (code) {
obj_free (code); obj_free (code);
}
[super dealloc];
} }
@end @end

View file

@ -10,7 +10,6 @@
{ {
CompiledCode code; CompiledCode code;
SchemeObject sexpr; SchemeObject sexpr;
Symbol lambdaSym, quoteSym;
Scope scope; Scope scope;
Error err; Error err;
} }

View file

@ -1,10 +1,29 @@
#include "Compiler.h" #include "Compiler.h"
#include "Instruction.h" #include "Instruction.h"
#include "Nil.h" #include "Nil.h"
#include "Void.h"
#include "Boolean.h"
#include "Cons.h" #include "Cons.h"
#include "defs.h" #include "defs.h"
Symbol lambdaSym;
Symbol quoteSym;
Symbol defineSym;
Symbol ifSym;
@implementation Compiler @implementation Compiler
+ (void) initialize
{
lambdaSym = [Symbol forString: "lambda"];
[lambdaSym makeRootCell];
quoteSym = [Symbol forString: "quote"];
[quoteSym makeRootCell];
defineSym = [Symbol forString: "define"];
[defineSym makeRootCell];
ifSym = [Symbol forString: "if"];
[ifSym makeRootCell];
}
+ (id) newWithLambda: (SchemeObject) xp scope: (Scope) sc + (id) newWithLambda: (SchemeObject) xp scope: (Scope) sc
{ {
return [[self alloc] initWithLambda: xp scope: sc]; return [[self alloc] initWithLambda: xp scope: sc];
@ -15,14 +34,11 @@
self = [super init]; self = [super init];
sexpr = xp; sexpr = xp;
scope = sc; scope = sc;
lambdaSym = [Symbol forString: "lambda"];
quoteSym = [Symbol forString: "quote"];
code = [CompiledCode new]; code = [CompiledCode new];
err = NIL; err = NIL;
return self; return self;
} }
// FIXME: handle variable argument lists
- (void) emitBuildEnvironment: (SchemeObject) arguments - (void) emitBuildEnvironment: (SchemeObject) arguments
{ {
local integer count, index; local integer count, index;
@ -30,15 +46,30 @@
scope = [Scope newWithOuter: scope]; scope = [Scope newWithOuter: scope];
count = 0; count = 0;
for (cur = arguments; cur != [Nil nil]; cur = [cur cdr]) { for (cur = arguments; [cur isKindOfClass: [Cons class]]; cur = [cur cdr]) {
count++;
}
if (cur != [Nil nil]) {
count++; count++;
} }
[code addInstruction: [Instruction opcode: MAKEENV operand: count]]; [code addInstruction: [Instruction opcode: MAKEENV operand: count]];
[code addInstruction: [Instruction opcode: LOADENV]]; [code addInstruction: [Instruction opcode: LOADENV]];
cur = arguments; cur = arguments;
for (index = 0; index < count; cur = [cur cdr]) { for (index = 0; index < count; cur = [cur cdr]) {
[scope addName: (Symbol) [cur car]]; if ([cur isKindOfClass: [Cons class]]) {
[code addInstruction: [Instruction opcode: SET operand: index]]; [scope addName: (Symbol) [cur car]];
[code addInstruction: [Instruction opcode: SET operand: index]];
} else if ([cur isKindOfClass: [Symbol class]]) {
[scope addName: (Symbol) cur];
[code addInstruction:
[Instruction opcode: SETREST operand: index]];
break;
} else {
err = [Error type: "syntax"
message: "Invalid entry in argument list"
by: arguments];
return;
}
index++; index++;
} }
} }
@ -72,17 +103,89 @@
} }
} }
- (void) emitDefine: (SchemeObject) expression
{
local integer index = 0;
if (![expression isKindOfClass: [Cons class]] ||
![[expression cdr] isKindOfClass: [Cons class]]) {
err = [Error type: "syntax"
message: "Malformed define statement"
by: expression];
return;
}
if ([[expression car] isKindOfClass: [Cons class]]) {
index = [code addConstant: [[expression car] car]];
[self emitLambda: cons(lambdaSym,
cons([[expression car] cdr],
[expression cdr]))];
if (err) return;
} else if ([[expression car] isKindOfClass: [Symbol class]]) {
index = [code addConstant: [expression car]];
[self emitExpression: [[expression cdr] car]];
if (err) return;
} else {
err = [Error type: "syntax"
message: "Malformed define statement"
by: expression];
return;
}
[code addInstruction: [Instruction opcode: PUSH]];
[code addInstruction: [Instruction opcode: LOADLITS]];
[code addInstruction: [Instruction opcode: GET operand: index]];
[code addInstruction: [Instruction opcode: SETGLOBAL]];
}
- (void) emitIf: (SchemeObject) expression
{
local Instruction falseLabel, endLabel;
local integer index;
if (![expression isKindOfClass: [Cons class]] ||
![[expression cdr] isKindOfClass: [Cons class]]) {
err = [Error type: "syntax"
message: "Malformed if expression"
by: expression];
}
falseLabel = [Instruction opcode: LABEL];
endLabel = [Instruction opcode: LABEL];
[self emitExpression: [expression car]];
if (err) return;
[code addInstruction: [Instruction opcode: IFFALSE label: falseLabel]];
[self emitExpression: [[expression cdr] car]];
if (err) return;
[code addInstruction: [Instruction opcode: GOTO label: endLabel]];
[code addInstruction: falseLabel];
if ([[expression cdr] cdr] == [Nil nil]) {
index = [code addConstant: [Void voidConstant]];
[code addInstruction: [Instruction opcode: LOADLITS]];
[code addInstruction: [Instruction opcode: GET operand: index]];
} else {
[self emitExpression: [[[expression cdr] cdr] car]];
if (err) return;
}
[code addInstruction: endLabel];
}
- (void) emitExpression: (SchemeObject) expression - (void) emitExpression: (SchemeObject) expression
{ {
if ([expression isKindOfClass: [Cons class]]) { if ([expression isKindOfClass: [Cons class]]) {
if ([expression car] == lambdaSym) { if ([expression car] == lambdaSym) {
[self emitLambda: expression]; [self emitLambda: expression];
if (err) return;
} else if ([expression car] == quoteSym) { } else if ([expression car] == quoteSym) {
[self emitConstant: [[expression cdr] car]]; [self emitConstant: [[expression cdr] car]];
} else if ([expression car] == defineSym) {
[self emitDefine: [expression cdr]];
} else if ([expression car] == ifSym) {
[self emitIf: [expression cdr]];
} else { } else {
[self emitApply: expression]; [self emitApply: expression];
if (err) return;
} }
} else if ([expression isKindOfClass: [Symbol class]]) { } else if ([expression isKindOfClass: [Symbol class]]) {
[self emitVariable: (Symbol) expression]; [self emitVariable: (Symbol) expression];
@ -122,7 +225,7 @@
scope: scope]; scope: scope];
local SchemeObject res; local SchemeObject res;
local integer index; local integer index;
res = [compiler compile]; res = [compiler compile];
if ([res isError]) { if ([res isError]) {
err = (Error) res; err = (Error) res;
@ -177,9 +280,7 @@
{ {
[code mark]; [code mark];
[sexpr mark]; [sexpr mark];
[lambdaSym mark]; [scope mark];
[quoteSym mark];
[Scope mark];
} }
@end @end

View file

@ -7,11 +7,9 @@
@interface Continuation: Procedure @interface Continuation: Procedure
{ {
state_t state; state_t state;
SchemeObject cont;
Frame env;
} }
+ (id) newWithState: (state_t []) st environment: (Frame) e continuation: (Continuation) c pc: (integer) p; + (id) newWithState: (state_t []) st pc: (integer) p;
- (id) initWithState: (state_t []) st environment: (Frame) e continuation: (Continuation) c pc: (integer) p; - (id) initWithState: (state_t []) st pc: (integer) p;
@end @end

View file

@ -2,27 +2,25 @@
#include "defs.h" #include "defs.h"
@implementation Continuation @implementation Continuation
+ (id) newWithState: (state_t []) st environment: (Frame) e continuation: (Continuation) c pc: (integer) p + (id) newWithState: (state_t []) st pc: (integer) p
{ {
return [[self alloc] initWithState: st environment: e continuation: c pc: p]; return [[self alloc] initWithState: st pc: p];
} }
- (id) initWithState: (state_t []) st environment: (Frame) e continuation: (Continuation) c pc: (integer) p - (id) initWithState: (state_t []) st pc: (integer) p
{ {
self = [self init]; self = [self init];
state.program = st.program; state.program = st.program;
state.pc = p; state.pc = p;
state.literals = st.literals; state.literals = st.literals;
state.stack = st.stack; state.stack = st.stack;
cont = c; state.cont = st.cont;
env = e; state.env = st.env;
return self; return self;
} }
- (void) invokeOnMachine: (Machine) m - (void) invokeOnMachine: (Machine) m
{ {
[m state: &state]; [m state: &state];
[m environment: env];
[m continuation: cont];
return; return;
} }
@ -30,8 +28,9 @@
{ {
[state.literals mark]; [state.literals mark];
[state.stack mark]; [state.stack mark];
[cont mark]; [state.cont mark];
[env mark]; [state.env mark];
[state.proc mark];
} }
- (string) printForm - (string) printForm

View file

@ -13,10 +13,15 @@ typedef enum {
MAKEENV, MAKEENV,
GET, GET,
SET, SET,
SETREST,
SETSTACK,
GETLINK, GETLINK,
GETGLOBAL, GETGLOBAL,
SETGLOBAL,
CALL, CALL,
RETURN RETURN,
IFFALSE,
GOTO
} opcode_e; } opcode_e;
struct instruction_s { struct instruction_s {

View file

@ -20,6 +20,7 @@
- (void) invokeOnMachine: (Machine) m - (void) invokeOnMachine: (Machine) m
{ {
[super invokeOnMachine: m];
[m loadCode: code]; [m loadCode: code];
[m environment: env]; [m environment: env];
} }

View file

@ -3,7 +3,7 @@
#include "SchemeObject.h" #include "SchemeObject.h"
#include "Symbol.h" #include "Symbol.h"
@interface Lexer: Object @interface Lexer: SchemeObject
{ {
string source; string source;
string filename; string filename;

View file

@ -30,7 +30,8 @@ BOOL issymbol (string x)
- (id) initWithSource: (string) s file: (string) f - (id) initWithSource: (string) s file: (string) f
{ {
self = [super init]; self = [super init];
source = s; source = str_new();
str_copy(source, s);
filename = f; filename = f;
linenum = 1; linenum = 1;
return self; return self;
@ -49,14 +50,14 @@ BOOL issymbol (string x)
} }
} }
source = str_mid(source, len); str_copy (source, str_mid(source, len));
switch (str_mid (source, 0, 1)) { switch (str_mid (source, 0, 1)) {
case "(": case "(":
source = str_mid (source, 1); str_copy (source, str_mid (source, 1));
return [Symbol leftParen]; return [Symbol leftParen];
case ")": case ")":
source = str_mid (source, 1); str_copy (source, str_mid (source, 1));
return [Symbol rightParen]; return [Symbol rightParen];
case "0": case "1": case "2": case "0": case "1": case "2":
case "3": case "4": case "5": case "3": case "4": case "5":
@ -66,24 +67,27 @@ BOOL issymbol (string x)
num = [Number newFromInt: stoi (str_mid(source, 0, len))]; num = [Number newFromInt: stoi (str_mid(source, 0, len))];
[num source: filename]; [num source: filename];
[num line: linenum]; [num line: linenum];
source = str_mid(source, len); str_copy (source, str_mid(source, len));
return num; return num;
case "\"": case "\"":
for (len = 1; str_mid(source, len, len+1) != "\""; len++); for (len = 1; str_mid(source, len, len+1) != "\""; len++);
str = [String newFromString: str_mid(source, 1, len)]; str = [String newFromString: str_mid(source, 1, len)];
[str source: filename]; [str source: filename];
[str line: linenum]; [str line: linenum];
source = str_mid(source, len+1); str_copy (source, str_mid(source, len+1));
return str; return str;
case "'": case "'":
source = str_mid (source, 1); str_copy (source, str_mid (source, 1));
return [Symbol quote]; return [Symbol quote];
case ".":
str_copy (source, str_mid (source, 1));
return [Symbol dot];
case "": case "":
return NIL; return NIL;
default: default:
for (len = 1; issymbol(str_mid(source, len, len+1)); len++); for (len = 1; issymbol(str_mid(source, len, len+1)); len++);
sym = [Symbol forString: str_mid (source, 0, len)]; sym = [Symbol forString: str_mid (source, 0, len)];
source = str_mid(source, len); str_copy (source, str_mid(source, len));
return sym; return sym;
} }
} }

View file

@ -11,9 +11,8 @@
{ {
state_t state; state_t state;
SchemeObject value; SchemeObject value;
Continuation cont;
Frame env;
hashtab_t globals; hashtab_t globals;
SchemeObject all_globals;
} }
- (void) loadCode: (CompiledCode) code; - (void) loadCode: (CompiledCode) code;
- (SchemeObject) run; - (SchemeObject) run;

View file

@ -1,8 +1,10 @@
#include "Machine.h" #include "Machine.h"
#include "Cons.h" #include "Cons.h"
#include "Lambda.h" #include "Lambda.h"
#include "Boolean.h"
#include "Nil.h" #include "Nil.h"
#include "defs.h" #include "defs.h"
//#include "debug.h"
string GlobalGetKey (void []ele, void []data) string GlobalGetKey (void []ele, void []data)
{ {
@ -22,19 +24,20 @@ void GlobalFree (void []ele, void []data)
state.program = NIL; state.program = NIL;
state.pc = 0; state.pc = 0;
value = NIL; value = NIL;
cont = NIL; state.cont = NIL;
env = NIL; state.env = NIL;
state.literals = NIL; state.literals = NIL;
state.stack = [Nil nil]; state.stack = [Nil nil];
globals = Hash_NewTable(1024, GlobalGetKey, GlobalFree, NIL); globals = Hash_NewTable(1024, GlobalGetKey, GlobalFree, NIL);
all_globals = [Nil nil];
return self; return self;
} }
- (void) addGlobal: (Symbol) sym value: (SchemeObject) val - (void) addGlobal: (Symbol) sym value: (SchemeObject) val
{ {
local Cons c = cons(sym, val); local Cons c = cons(sym, val);
[c makeRootCell];
Hash_Add(globals, c); Hash_Add(globals, c);
all_globals = cons(c, all_globals);
} }
- (void) loadCode: (CompiledCode) code - (void) loadCode: (CompiledCode) code
@ -46,12 +49,12 @@ void GlobalFree (void []ele, void []data)
- (void) environment: (Frame) e - (void) environment: (Frame) e
{ {
env = e; state.env = e;
} }
- (void) continuation: (Continuation) c - (void) continuation: (Continuation) c
{ {
cont = c; state.cont = c;
} }
- (void) value: (SchemeObject) v - (void) value: (SchemeObject) v
@ -59,9 +62,14 @@ void GlobalFree (void []ele, void []data)
value = v; value = v;
} }
- (SchemeObject) value
{
return value;
}
- (Continuation) continuation - (Continuation) continuation
{ {
return cont; return state.cont;
} }
- (SchemeObject) stack - (SchemeObject) stack
@ -85,6 +93,14 @@ void GlobalFree (void []ele, void []data)
state.pc = st[0].pc; state.pc = st[0].pc;
state.literals = st[0].literals; state.literals = st[0].literals;
state.stack = st[0].stack; state.stack = st[0].stack;
state.cont = st[0].cont;
state.env = st[0].env;
state.proc = st[0].proc;
}
- (void) procedure: (Procedure) pr
{
state.proc = pr;
} }
- (SchemeObject) run - (SchemeObject) run
@ -118,18 +134,17 @@ void GlobalFree (void []ele, void []data)
case MAKECLOSURE: case MAKECLOSURE:
dprintf("Makeclosure\n"); dprintf("Makeclosure\n");
value = [Lambda newWithCode: (CompiledCode) value value = [Lambda newWithCode: (CompiledCode) value
environment: env]; environment: state.env];
break; break;
case MAKECONT: case MAKECONT:
dprintf("Makecont\n"); dprintf("Makecont\n");
cont = [Continuation newWithState: &state state.cont = [Continuation newWithState: &state
environment: env pc: operand];
continuation: cont state.stack = [Nil nil];
pc: operand];
break; break;
case LOADENV: case LOADENV:
dprintf("Loadenv\n"); dprintf("Loadenv\n");
value = env; value = state.env;
break; break;
case LOADLITS: case LOADLITS:
dprintf("Loadlits\n"); dprintf("Loadlits\n");
@ -137,7 +152,7 @@ void GlobalFree (void []ele, void []data)
break; break;
case MAKEENV: case MAKEENV:
dprintf("Makeenv\n"); dprintf("Makeenv\n");
env = [Frame newWithSize: operand link: env]; state.env = [Frame newWithSize: operand link: state.env];
break; break;
case GET: case GET:
value = [value get: operand]; value = [value get: operand];
@ -145,29 +160,55 @@ void GlobalFree (void []ele, void []data)
break; break;
case SET: case SET:
[value set: operand to: [state.stack car]]; [value set: operand to: [state.stack car]];
dprintf("Set: %i --> %s\n", operand, [value printForm]); dprintf("Set: %i --> %s\n", operand, [[state.stack car] printForm]);
state.stack = [state.stack cdr]; state.stack = [state.stack cdr];
break; break;
case SETREST:
[value set: operand to: state.stack];
dprintf("Setrest: %i --> %s\n", operand, [state.stack printForm]);
state.stack = [Nil nil];
break;
case SETSTACK:
dprintf("Setstack: %s\n", [value printForm]);
state.stack = value;
break;
case GETLINK: case GETLINK:
dprintf("Getlink"); dprintf("Getlink\n");
value = [value getLink]; value = [value getLink];
break; break;
case GETGLOBAL: case GETGLOBAL:
dprintf("Getglobal: %s\n", [value printForm]); dprintf("Getglobal: %s\n", [value printForm]);
value = [((Cons) Hash_Find(globals, [value printForm])) cdr]; value = [((Cons) Hash_Find(globals, [value printForm])) cdr];
dprintf(" --> %s\n", [value printForm]);
break;
case SETGLOBAL:
dprintf("Setglobal: %s\n", [value printForm]);
[self addGlobal: (Symbol) value value: [state.stack car]];
state.stack = [state.stack cdr];
break; break;
case CALL: case CALL:
dprintf("Call\n"); dprintf("Call\n");
[SchemeObject collectCheckPoint];
[value invokeOnMachine: self]; [value invokeOnMachine: self];
break; break;
case RETURN: case RETURN:
dprintf("Return: %s\n", [value printForm]); dprintf("Return: %s\n", [value printForm]);
if (!cont) { if (!state.cont) {
return value; return value;
} else { } else {
[cont invokeOnMachine: self]; [state.cont invokeOnMachine: self];
} }
break; break;
case IFFALSE:
dprintf("Iffalse: %s\n", [value printForm]);
if (value == [Boolean falseConstant]) {
state.pc = operand;
}
break;
case GOTO:
dprintf("Goto: %i\n", operand);
state.pc = operand;
break;
} }
} }
} }
@ -176,9 +217,11 @@ void GlobalFree (void []ele, void []data)
{ {
[state.literals mark]; [state.literals mark];
[state.stack mark]; [state.stack mark];
[cont mark]; [state.cont mark];
[env mark]; [state.env mark];
[state.proc mark];
[value mark]; [value mark];
// FIXME: need to mark globals [all_globals mark];
} }
@end @end

View file

@ -45,7 +45,7 @@ libscheme_a_SOURCES=\
SchemeObject.r Cons.r Number.r String.r Symbol.r Lexer.r Parser.r Nil.r \ SchemeObject.r Cons.r Number.r String.r Symbol.r Lexer.r Parser.r Nil.r \
Procedure.r Primitive.r Lambda.r Scope.r Instruction.r builtins.r \ Procedure.r Primitive.r Lambda.r Scope.r Instruction.r builtins.r \
Frame.r CompiledCode.r Compiler.r Continuation.r Machine.r Void.r \ Frame.r CompiledCode.r Compiler.r Continuation.r Machine.r Void.r \
Error.r Error.r Boolean.r
libscheme_a_AR=$(PAK) -cf libscheme_a_AR=$(PAK) -cf
scheme_data=\ scheme_data=\

View file

@ -2,7 +2,7 @@
#define __Parser_h #define __Parser_h
#include "Lexer.h" #include "Lexer.h"
@interface Parser: Object @interface Parser: SchemeObject
{ {
Lexer lexer; Lexer lexer;
string file; string file;

View file

@ -40,6 +40,16 @@
if (token == [Symbol rightParen]) { if (token == [Symbol rightParen]) {
return [Nil nil]; 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 { } else {
res = [self readList]; res = [self readList];
if ([res isError]) return res; if ([res isError]) return res;
@ -56,7 +66,7 @@
local integer line; local integer line;
line = [lexer lineNumber]; line = [lexer lineNumber];
token = [lexer nextToken]; token = [lexer nextToken];
if ([token isError]) { if ([token isError]) {

View file

@ -15,8 +15,11 @@
- (SchemeObject) invokeOnMachine: (Machine) m - (SchemeObject) invokeOnMachine: (Machine) m
{ {
local SchemeObject value = func ([m stack], m); local SchemeObject value = func ([m stack], m);
[m value: value]; [super invokeOnMachine: m];
[[m continuation] invokeOnMachine: m]; if (value) {
[m value: value];
[[m continuation] invokeOnMachine: m];
}
} }
- (string) printForm - (string) printForm

View file

@ -3,6 +3,7 @@
@implementation Procedure @implementation Procedure
- (void) invokeOnMachine: (Machine) m - (void) invokeOnMachine: (Machine) m
{ {
[m procedure: self];
return; return;
} }

View file

@ -3,13 +3,8 @@
#include "Object.h" #include "Object.h"
#define true YES #define true YES
#define false NO #define false NO
//#define DEBUG
#ifdef DEBUG
#define dprintf printf
#else
#define dprintf(x, ...) #define dprintf(x, ...)
#endif
@interface SchemeObject: Object @interface SchemeObject: Object

View file

@ -1,9 +1,20 @@
#include "SchemeObject.h" #include "SchemeObject.h"
#include "defs.h" #include "defs.h"
//#include "debug.h"
SchemeObject maybe_garbage, not_garbage, roots; SchemeObject maybe_garbage, not_garbage, not_garbage_end, wait_list, roots, queue_pos;
BOOL markstate; BOOL markstate;
typedef enum {
GC_IDLE = 0,
GC_MARK = 1,
GC_SWEEP = 2
} gc_state_e;
gc_state_e gc_state;
integer checkpoint;
BOOL contains (SchemeObject list, SchemeObject what) BOOL contains (SchemeObject list, SchemeObject what)
{ {
local SchemeObject cur; local SchemeObject cur;
@ -22,8 +33,10 @@ BOOL contains (SchemeObject list, SchemeObject what)
+ (void) initialize + (void) initialize
{ {
maybe_garbage = not_garbage = roots = NIL; maybe_garbage = not_garbage = not_garbage_end = wait_list = roots = NIL;
markstate = true; markstate = true;
gc_state = GC_IDLE;
checkpoint = 0;
} }
+ (id) dummyObject + (id) dummyObject
@ -40,40 +53,99 @@ BOOL contains (SchemeObject list, SchemeObject what)
return self; return self;
} }
+ (void) collectCheckPoint
{
if (++checkpoint == 50)
{
[self collect];
checkpoint = 0;
}
}
+ (void) collect + (void) collect
{ {
local SchemeObject cur, next = NIL, dummy; local SchemeObject cur;
local integer amount;
not_garbage = dummy = [SchemeObject dummyObject]; switch (gc_state) {
for (cur = roots; cur; cur = next) { case GC_IDLE:
next = cur.next; dprintf("GC: Starting collection...\n");
[cur markReachable]; gc_state = GC_MARK;
not_garbage = not_garbage_end = [SchemeObject dummyObject];
for (cur = roots; cur; cur = cur.next) {
[cur markReachable];
}
queue_pos = not_garbage_end;
return;
case GC_MARK:
dprintf("GC: Marking...\n");
amount = 0;
while (queue_pos) {
dprintf("GC: marking queue: %s[%s]@%i\n",
[queue_pos description],
[queue_pos printForm],
(integer) queue_pos);
[queue_pos markReachable];
queue_pos = queue_pos.prev;
if (++amount == 50) return;
}
gc_state = GC_SWEEP;
queue_pos = maybe_garbage;
return;
case GC_SWEEP:
dprintf("GC: Sweeping...\n");
amount = 0;
while (queue_pos) {
dprintf("GC: freeing %s[%s]@%i...\n",
[queue_pos description],
[queue_pos printForm],
(integer) queue_pos);
[queue_pos release];
queue_pos = queue_pos.next;
if (++amount == 100) return;
}
maybe_garbage = not_garbage;
not_garbage_end.next = wait_list;
if (wait_list) {
wait_list.prev = not_garbage_end;
}
wait_list = NIL;
not_garbage_end = NIL;
not_garbage = NIL;
markstate = !markstate;
gc_state = GC_IDLE;
} }
for (cur = dummy; cur; cur = cur.prev) { }
dprintf("GC: marking queue: %s[%s]@%i\n", [cur description], [cur printForm],
(integer) cur); + (void) finishCollecting
[cur markReachable]; {
while (gc_state) {
[self collect];
} }
for (cur = maybe_garbage; cur; cur = next) {
next = cur.next;
dprintf("GC: freeing %s[%s]@%i...\n", [cur description], [cur printForm], (integer) cur);
[cur release];
}
maybe_garbage = not_garbage;
not_garbage = NIL;
markstate = !markstate;
} }
- (id) init - (id) init
{ {
self = [super init]; self = [super init];
if (maybe_garbage) { if (gc_state) {
maybe_garbage.prev = self; if (wait_list) {
wait_list.prev = self;
}
next = wait_list;
wait_list = self;
marked = markstate;
dprintf("GC: During collect: %i\n", (integer) self);
} else {
if (maybe_garbage) {
maybe_garbage.prev = self;
}
next = maybe_garbage;
maybe_garbage = self;
marked = !markstate;
dprintf("GC: Not during collect: %i\n", (integer) self);
} }
next = maybe_garbage;
maybe_garbage = self;
prev = NIL; prev = NIL;
marked = !markstate;
root = false; root = false;
return self; return self;
} }
@ -98,11 +170,19 @@ BOOL contains (SchemeObject list, SchemeObject what)
prev = NIL; prev = NIL;
not_garbage = self; not_garbage = self;
//[self markReachable]; //[self markReachable];
if (contains (maybe_garbage, self)) {
dprintf("Shit shit shit!\n");
}
} }
} }
- (void) makeRootCell - (void) makeRootCell
{ {
if (gc_state) {
dprintf("Root cell made during collection!\n");
[SchemeObject finishCollecting];
}
if (prev) { if (prev) {
prev.next = next; prev.next = next;
} else { } else {

View file

@ -71,7 +71,11 @@
- (void) dealloc - (void) dealloc
{ {
[names release]; if (names) {
[names release];
}
names = NIL;
[super dealloc];
} }
- (void) markReachable - (void) markReachable

View file

@ -8,7 +8,10 @@
+ (void) initialize; + (void) initialize;
+ (Symbol) leftParen; + (Symbol) leftParen;
+ (Symbol) rightParen; + (Symbol) rightParen;
+ (Symbol) dot;
+ (Symbol) forString: (string) s; + (Symbol) forString: (string) s;
@end @end
@extern Symbol symbol (string str);
#endif //__Symbol_h #endif //__Symbol_h

View file

@ -20,6 +20,12 @@ hashtab_t symbols;
Symbol lparen; Symbol lparen;
Symbol rparen; Symbol rparen;
Symbol quote; Symbol quote;
Symbol dot;
Symbol symbol (string str)
{
return [Symbol forString: str];
}
@implementation Symbol @implementation Symbol
+ (void) initialize + (void) initialize
@ -28,9 +34,11 @@ Symbol quote;
lparen = [Symbol forString: "("]; lparen = [Symbol forString: "("];
rparen = [Symbol forString: ")"]; rparen = [Symbol forString: ")"];
quote = [Symbol forString: "'"]; quote = [Symbol forString: "'"];
dot = symbol(".");
[lparen makeRootCell]; [lparen makeRootCell];
[rparen makeRootCell]; [rparen makeRootCell];
[quote makeRootCell]; [quote makeRootCell];
[dot makeRootCell];
} }
+ (Symbol) forString: (string) s + (Symbol) forString: (string) s
@ -61,6 +69,11 @@ Symbol quote;
return quote; return quote;
} }
+ (Symbol) dot
{
return dot;
}
- (string) printForm - (string) printForm
{ {
return value; return value;

View file

@ -1,8 +1,3 @@
#include "Primitive.h" #include "Primitive.h"
@extern Primitive print_p; @extern void builtin_addtomachine (Machine m);
@extern Primitive newline_p;
@extern Primitive add_p;
@extern Primitive map_p;
@extern Primitive for_each_p;
@extern void builtin_init (void);

View file

@ -6,14 +6,9 @@
#include "string.h" #include "string.h"
#include "Cons.h" #include "Cons.h"
#include "Continuation.h" #include "Continuation.h"
#include "Boolean.h"
Primitive print_p; SchemeObject bi_display (SchemeObject args, Machine m)
Primitive newline_p;
Primitive add_p;
Primitive map_p;
Primitive for_each_p;
SchemeObject bi_print (SchemeObject args, Machine m)
{ {
print([[args car] printForm]); print([[args car] printForm]);
return [Void voidConstant]; return [Void voidConstant];
@ -37,58 +32,53 @@ SchemeObject bi_add (SchemeObject args, Machine m)
return [Number newFromInt: sum]; return [Number newFromInt: sum];
} }
SchemeObject bi_map (SchemeObject args, Machine m) SchemeObject bi_cons (SchemeObject args, Machine m)
{ {
local SchemeObject func = [args car]; [args cdr: [[args cdr] car]];
local SchemeObject list = [[args cdr] car]; return args;
local SchemeObject output, cur, last, temp;
local Continuation oldcont;
if (list == [Nil nil]) {
return list;
} else {
oldcont = [m continuation];
[m stack: cons([list car], [Nil nil])];
[m continuation: NIL];
[func invokeOnMachine: m];
output = last = cons([m run], [Nil nil]);
for (cur = [list cdr]; cur != [Nil nil]; cur = [cur cdr]) {
[m stack: cons([cur car], [Nil nil])];
[func invokeOnMachine: m];
temp = cons([m run], [Nil nil]);
[last cdr: temp];
last = temp;
}
[m continuation: oldcont];
return output;
}
}
SchemeObject bi_for_each (SchemeObject args, Machine m)
{
local SchemeObject func = [args car];
local SchemeObject list = [[args cdr] car];
local SchemeObject cur;
local Continuation oldcont;
if (list != [Nil nil]) {
oldcont = [m continuation];
[m continuation: NIL];
for (cur = list; cur != [Nil nil]; cur = [cur cdr]) {
[m stack: cons([cur car], [Nil nil])];
[func invokeOnMachine: m];
[m run];
}
[m continuation: oldcont];
}
return [Void voidConstant];
} }
void builtin_init (void) SchemeObject bi_null (SchemeObject args, Machine m)
{ {
print_p = [Primitive newFromFunc: bi_print]; return [args car] == [Nil nil]
newline_p = [Primitive newFromFunc: bi_newline]; ?
add_p = [Primitive newFromFunc: bi_add]; [Boolean trueConstant] :
map_p = [Primitive newFromFunc: bi_map]; [Boolean falseConstant];
for_each_p = [Primitive newFromFunc: bi_for_each]; }
SchemeObject bi_car (SchemeObject args, Machine m)
{
return [[args car] car];
}
SchemeObject bi_cdr (SchemeObject args, Machine m)
{
return [[args car] cdr];
}
SchemeObject bi_apply (SchemeObject args, Machine m)
{
[m stack: [[args cdr] car]];
[[args car] invokeOnMachine: m];
return NIL;
}
void builtin_addtomachine (Machine m)
{
[m addGlobal: symbol("display")
value: [Primitive newFromFunc: bi_display]];
[m addGlobal: symbol("newline")
value: [Primitive newFromFunc: bi_newline]];
[m addGlobal: symbol("+")
value: [Primitive newFromFunc: bi_add]];
[m addGlobal: symbol("cons")
value: [Primitive newFromFunc: bi_cons]];
[m addGlobal: symbol("null?")
value: [Primitive newFromFunc: bi_null]];
[m addGlobal: symbol("car")
value: [Primitive newFromFunc: bi_car]];
[m addGlobal: symbol("cdr")
value: [Primitive newFromFunc: bi_cdr]];
[m addGlobal: symbol("apply")
value: [Primitive newFromFunc: bi_apply]];
} }

4
ruamoko/scheme/debug.h Normal file
View file

@ -0,0 +1,4 @@
#ifdef dprintf
#undef dprintf
#endif
#define dprintf printf

View file

@ -7,7 +7,7 @@
@extern integer (integer handle, string buffer, integer count) write = #0; @extern integer (integer handle, string buffer, integer count) write = #0;
@extern integer (integer handle, integer pos, integer whence) seek = #0; @extern integer (integer handle, integer pos, integer whence) seek = #0;
//@extern void() traceon = #0; // turns statment trace on @extern void() traceon = #0; // turns statment trace on
//@extern void() traceoff = #0; @extern void() traceoff = #0;
@extern void (...) printf = #0; @extern void (...) printf = #0;

View file

@ -7,8 +7,8 @@ string (integer handle, integer count, integer []result) read = #0;
integer (integer handle, string buffer, integer count) write = #0; integer (integer handle, string buffer, integer count) write = #0;
integer (integer handle, integer pos, integer whence) seek = #0; integer (integer handle, integer pos, integer whence) seek = #0;
//void() traceon = #0; // turns statment trace on void() traceon = #0; // turns statment trace on
//void() traceoff = #0; void() traceoff = #0;
void (...) printf = #0; void (...) printf = #0;

View file

@ -36,16 +36,14 @@ integer main (integer argc, string []argv)
if (argc < 1) { if (argc < 1) {
return -1; return -1;
} }
//traceon();
builtin_init();
parser = [Parser newFromSource: readfile(argv[1]) file: argv[1]]; parser = [Parser newFromSource: readfile(argv[1]) file: argv[1]];
vm = [Machine new]; vm = [Machine new];
[vm makeRootCell]; [vm makeRootCell];
[vm addGlobal: [Symbol forString: "display"] value: print_p]; [parser makeRootCell];
[vm addGlobal: [Symbol forString: "newline"] value: newline_p]; builtin_addtomachine (vm);
[vm addGlobal: [Symbol forString: "+"] value: add_p];
[vm addGlobal: [Symbol forString: "map"] value: map_p];
[vm addGlobal: [Symbol forString: "for-each"] value: for_each_p];
while ((stuff = [parser read])) { while ((stuff = [parser read])) {
if ([stuff isError]) { if ([stuff isError]) {
printf(">> %s: %i\n", [stuff source], [stuff line]); printf(">> %s: %i\n", [stuff source], [stuff line]);
@ -65,7 +63,7 @@ integer main (integer argc, string []argv)
lm = [Lambda newWithCode: code environment: NIL]; lm = [Lambda newWithCode: code environment: NIL];
[lm invokeOnMachine: vm]; [lm invokeOnMachine: vm];
[vm run]; [vm run];
[SchemeObject collect];
} }
[SchemeObject finishCollecting];
return 0; return 0;
} }

View file

@ -4,11 +4,15 @@
#include "Instruction.h" #include "Instruction.h"
#include "Frame.h" #include "Frame.h"
@class Continuation;
struct state_s = { struct state_s = {
instruction_t [] program; instruction_t [] program;
integer pc; integer pc;
Frame literals; Frame literals, env;
SchemeObject stack; SchemeObject stack;
Continuation cont;
Procedure proc;
}; };
typedef struct state_s state_t; typedef struct state_s state_t;