working to adapt the primitives

This commit is contained in:
Danny Yoo 2011-06-15 17:54:39 -04:00
parent 6b8a3f30ea
commit da95994360
3 changed files with 685 additions and 553 deletions

View File

@ -0,0 +1,47 @@
#lang racket/base
(require racket/runtime-path
racket/file
racket/contract
racket/list)
;; Get the list of primitives implemented in js-vm-primitives.js
(define-runtime-path js-vm-primitives.js "runtime-src/js-vm-primitives.js")
(define-runtime-path whalesong-primitives.js "runtime-src/primitives.js")
;; sort&unique: (listof string) -> (listof string)
(define (sort&unique names)
(let ([ht (make-hash)])
(for ([name names])
(hash-set! ht name #t))
(sort (for/list ([name (in-hash-keys ht)])
name)
string<?)))
;; primitive-names: (listof symbol)
(define js-vm-primitive-names
(map string->symbol
(sort&unique
(map (lambda (a-str)
(substring a-str
(string-length "PRIMITIVES['")
(- (string-length a-str) (string-length "']"))))
(let ([contents (file->string js-vm-primitives.js)])
(regexp-match* #px"PRIMITIVES\\[('|\")[^\\]]*('|\")\\]" contents))))))
(define whalesong-primitive-names
(map string->symbol
(sort&unique
(map (lambda (a-str)
(let ([match (regexp-match
#px"installPrimitiveProcedure\\(\\s+('|\")([^\\]]*)('|\")" a-str)])
(third match)))
(let ([contents (file->string whalesong-primitives.js)])
(regexp-match* #px"installPrimitiveProcedure\\(\\s+('|\")[^\\']*('|\")" contents))))))
(provide/contract [js-vm-primitive-names (listof symbol?)]
[whalesong-primitive-names (listof symbol?)])

View File

@ -1,9 +1,7 @@
if(this['plt'] === undefined) { this['plt'] = {}; } if(this['plt'] === undefined) { this['plt'] = {}; }
// All of the values here are namespaced under "plt.runtime". // All of the values here are namespaced under "plt.runtime".
(function(scope) { (function(scope) {
var runtime = {}; var runtime = {};
scope['runtime'] = runtime; scope['runtime'] = runtime;
@ -19,10 +17,6 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
}; };
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// We try to isolate the effect of external modules: all the identifiers we // We try to isolate the effect of external modules: all the identifiers we
@ -33,6 +27,9 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
var isPair = types.isPair; var isPair = types.isPair;
var isList = types.isList; var isList = types.isList;
var isVector = types.isVector; var isVector = types.isVector;
var isEqual = types.isEqual;
var NULL = types.EMPTY; var NULL = types.EMPTY;
var VOID = types.VOID; var VOID = types.VOID;
@ -542,8 +539,11 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
}; };
installPrimitiveConstant('pi', jsnums.pi); installPrimitiveConstant('pi', jsnums.pi);
installPrimitiveConstant('e', jsnums.e); installPrimitiveConstant('e', jsnums.e);
installPrimitiveConstant('null', NULL);
installPrimitiveProcedure( installPrimitiveProcedure(
'display', makeList(1, 2), 'display', makeList(1, 2),
@ -638,7 +638,10 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
// TODO: use installPrimitiveProcedure for the rest... // TODO: use installPrimitiveProcedure for the rest...
Primitives['<'] = function(MACHINE) { installPrimitiveProcedure(
'<',
new ArityAtLeast(2),
function(MACHINE) {
var firstArg = MACHINE.env[MACHINE.env.length-1]; var firstArg = MACHINE.env[MACHINE.env.length-1];
testArgument(MACHINE, testArgument(MACHINE,
'number', isNumber, firstArg, 0, '<'); 'number', isNumber, firstArg, 0, '<');
@ -655,11 +658,13 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
} }
} }
return true; return true;
}; });
Primitives['<'].arity = new ArityAtLeast(2);
Primitives['<'].displayName = '<';
Primitives['>'] = function(MACHINE) {
installPrimitiveProcedure(
'>',
new ArityAtLeast(2),
function(MACHINE) {
var firstArg = MACHINE.env[MACHINE.env.length-1]; var firstArg = MACHINE.env[MACHINE.env.length-1];
testArgument(MACHINE, testArgument(MACHINE,
'number', isNumber, firstArg, 0, '>'); 'number', isNumber, firstArg, 0, '>');
@ -676,11 +681,12 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
} }
} }
return true; return true;
}; });
Primitives['>'].arity = new ArityAtLeast(2);
Primitives['>'].displayName = '>';
Primitives['<='] = function(MACHINE) { installPrimitiveProcedure(
'<=',
new ArityAtLeast(2),
function(MACHINE) {
var firstArg = MACHINE.env[MACHINE.env.length-1]; var firstArg = MACHINE.env[MACHINE.env.length-1];
testArgument(MACHINE, testArgument(MACHINE,
'number', isNumber, firstArg, 0, '<='); 'number', isNumber, firstArg, 0, '<=');
@ -697,12 +703,13 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
} }
} }
return true; return true;
}; });
Primitives['<='].arity = new ArityAtLeast(2);
Primitives['<='].displayName = '<=';
Primitives['>='] = function(MACHINE) { installPrimitiveProcedure(
'>=',
new ArityAtLeast(2),
function(MACHINE) {
var firstArg = MACHINE.env[MACHINE.env.length-1]; var firstArg = MACHINE.env[MACHINE.env.length-1];
testArgument(MACHINE, testArgument(MACHINE,
'number', isNumber, firstArg, 0, '>='); 'number', isNumber, firstArg, 0, '>=');
@ -719,12 +726,13 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
} }
} }
return true; return true;
}; });
Primitives['>='].arity = new ArityAtLeast(2);
Primitives['>='].displayName = '>=';
Primitives['+'] = function(MACHINE) { installPrimitiveProcedure(
'+',
new ArityAtLeast(0),
function(MACHINE) {
var result = 0; var result = 0;
var i = 0; var i = 0;
for (i=0; i < MACHINE.argcount; i++) { for (i=0; i < MACHINE.argcount; i++) {
@ -737,12 +745,13 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
result = jsnums.add(result, MACHINE.env[MACHINE.env.length - 1 - i]); result = jsnums.add(result, MACHINE.env[MACHINE.env.length - 1 - i]);
}; };
return result; return result;
}; });
Primitives['+'].arity = new ArityAtLeast(0);
Primitives['+'].displayName = '+';
Primitives['*'] = function(MACHINE) { installPrimitiveProcedure(
'*',
new ArityAtLeast(0),
function(MACHINE) {
var result = 1; var result = 1;
var i = 0; var i = 0;
for (i=0; i < MACHINE.argcount; i++) { for (i=0; i < MACHINE.argcount; i++) {
@ -755,11 +764,12 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
result = jsnums.multiply(result, MACHINE.env[MACHINE.env.length - 1 - i]); result = jsnums.multiply(result, MACHINE.env[MACHINE.env.length - 1 - i]);
} }
return result; return result;
}; });
Primitives['*'].arity = new ArityAtLeast(0);
Primitives['*'].displayName = '*';
Primitives['-'] = function(MACHINE) { installPrimitiveProcedure(
'-',
new ArityAtLeast(1),
function(MACHINE) {
if (MACHINE.argcount === 1) { if (MACHINE.argcount === 1) {
testArgument(MACHINE, testArgument(MACHINE,
'number', 'number',
@ -780,11 +790,12 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
result = jsnums.subtract(result, MACHINE.env[MACHINE.env.length - 1 - i]); result = jsnums.subtract(result, MACHINE.env[MACHINE.env.length - 1 - i]);
} }
return result; return result;
}; });
Primitives['-'].arity = new ArityAtLeast(1);
Primitives['-'].displayName = '-';
Primitives['/'] = function(MACHINE) { installPrimitiveProcedure(
'/',
new ArityAtLeast(1),
function(MACHINE) {
testArgument(MACHINE, testArgument(MACHINE,
'number', 'number',
isNumber, isNumber,
@ -802,13 +813,13 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
result = jsnums.divide(result, MACHINE.env[MACHINE.env.length - 1 - i]); result = jsnums.divide(result, MACHINE.env[MACHINE.env.length - 1 - i]);
} }
return result; return result;
}; });
Primitives['/'].arity = new ArityAtLeast(1);
Primitives['/'].displayName = '/';
installPrimitiveProcedure(
Primitives['add1'] = function(MACHINE) { 'add1',
1,
function(MACHINE) {
testArgument(MACHINE, testArgument(MACHINE,
'number', 'number',
isNumber, isNumber,
@ -817,11 +828,13 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
'add1'); 'add1');
var firstArg = MACHINE.env[MACHINE.env.length-1]; var firstArg = MACHINE.env[MACHINE.env.length-1];
return jsnums.add(firstArg, 1); return jsnums.add(firstArg, 1);
}; });
Primitives['add1'].arity = 1;
Primitives['add1'].displayName = 'add1';
Primitives['sub1'] = function(MACHINE) {
installPrimitiveProcedure(
'sub1',
1,
function(MACHINE) {
testArgument(MACHINE, testArgument(MACHINE,
'number', 'number',
isNumber, isNumber,
@ -830,45 +843,44 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
'sub1'); 'sub1');
var firstArg = MACHINE.env[MACHINE.env.length-1]; var firstArg = MACHINE.env[MACHINE.env.length-1];
return jsnums.subtract(firstArg, 1); return jsnums.subtract(firstArg, 1);
}; });
Primitives['sub1'].arity = 1;
Primitives['sub1'].displayName = 'sub1';
Primitives['zero?'] = function(MACHINE) {
installPrimitiveProcedure(
'zero?',
1,
function(MACHINE) {
var firstArg = MACHINE.env[MACHINE.env.length-1]; var firstArg = MACHINE.env[MACHINE.env.length-1];
return jsnums.equals(firstArg, 0); return jsnums.equals(firstArg, 0);
}; });
Primitives['zero?'].arity = 1;
Primitives['zero?'].displayName = 'zero?';
installPrimitiveProcedure(
'cons',
2,
function(MACHINE) {
Primitives['cons'] = function(MACHINE) {
var firstArg = MACHINE.env[MACHINE.env.length-1]; var firstArg = MACHINE.env[MACHINE.env.length-1];
var secondArg = MACHINE.env[MACHINE.env.length-2]; var secondArg = MACHINE.env[MACHINE.env.length-2];
return makePair(firstArg, secondArg); return makePair(firstArg, secondArg);
}; });
Primitives['cons'].arity = 2;
Primitives['cons'].displayName = 'cons';
Primitives['list'] = function(MACHINE) { installPrimitiveProcedure(
'list',
new ArityAtLeast(0),
function(MACHINE) {
var result = NULL; var result = NULL;
for (var i = 0; i < MACHINE.argcount; i++) { for (var i = 0; i < MACHINE.argcount; i++) {
result = makePair(MACHINE.env[MACHINE.env.length - (MACHINE.argcount - i)], result = makePair(MACHINE.env[MACHINE.env.length - (MACHINE.argcount - i)],
result); result);
} }
return result; return result;
}; });
Primitives['list'].arity = new ArityAtLeast(0);
Primitives['list'].displayName = 'list';
Primitives['car'] = function(MACHINE) { installPrimitiveProcedure(
'car',
1,
function(MACHINE) {
testArgument(MACHINE, testArgument(MACHINE,
'pair', 'pair',
isPair, isPair,
@ -877,11 +889,12 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
'car'); 'car');
var firstArg = MACHINE.env[MACHINE.env.length-1]; var firstArg = MACHINE.env[MACHINE.env.length-1];
return firstArg.first; return firstArg.first;
}; });
Primitives['car'].arity = 1;
Primitives['car'].displayName = 'car';
Primitives['cdr'] = function(MACHINE) { installPrimitiveProcedure(
'cdr',
1,
function(MACHINE) {
testArgument(MACHINE, testArgument(MACHINE,
'pair', 'pair',
isPair, isPair,
@ -890,18 +903,20 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
'cdr'); 'cdr');
var firstArg = MACHINE.env[MACHINE.env.length-1]; var firstArg = MACHINE.env[MACHINE.env.length-1];
return firstArg.rest; return firstArg.rest;
}; });
Primitives['cdr'].arity = 1;
Primitives['cdr'].displayName = 'cdr';
Primitives['pair?'] = function(MACHINE) { installPrimitiveProcedure(
'pair?',
1,
function(MACHINE) {
var firstArg = MACHINE.env[MACHINE.env.length-1]; var firstArg = MACHINE.env[MACHINE.env.length-1];
return isPair(firstArg); return isPair(firstArg);
}; });
Primitives['pair?'].arity = 1;
Primitives['pair?'].displayName = 'pair?';
Primitives['set-car!'] = function(MACHINE) { installPrimitiveProcedure(
'set-car!',
2,
function(MACHINE) {
testArgument(MACHINE, testArgument(MACHINE,
'pair', 'pair',
isPair, isPair,
@ -912,11 +927,13 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
var secondArg = MACHINE.env[MACHINE.env.length-2]; var secondArg = MACHINE.env[MACHINE.env.length-2];
firstArg.first = secondArg; firstArg.first = secondArg;
return VOID; return VOID;
}; });
Primitives['set-car!'].arity = 2;
Primitives['set-car!'].displayName = 'set-car!';
Primitives['set-cdr!'] = function(MACHINE) {
installPrimitiveProcedure(
'set-cdr!',
2,
function(MACHINE) {
testArgument(MACHINE, testArgument(MACHINE,
'pair', 'pair',
isPair, isPair,
@ -927,27 +944,31 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
var secondArg = MACHINE.env[MACHINE.env.length-2]; var secondArg = MACHINE.env[MACHINE.env.length-2];
firstArg.rest = secondArg; firstArg.rest = secondArg;
return VOID; return VOID;
}; });
Primitives['set-cdr!'].arity = 2;
Primitives['set-cdr!'].displayName = 'set-cdr!';
Primitives['not'] = function(MACHINE) {
installPrimitiveProcedure(
'not',
1,
function(MACHINE) {
var firstArg = MACHINE.env[MACHINE.env.length-1]; var firstArg = MACHINE.env[MACHINE.env.length-1];
return (firstArg === false); return (firstArg === false);
}; });
Primitives['not'].arity = 1;
Primitives['not'].displayName = 'not';
Primitives['null'] = NULL;
Primitives['null?'] = function(MACHINE) { installPrimitiveProcedure(
'null?',
1,
function(MACHINE) {
var firstArg = MACHINE.env[MACHINE.env.length-1]; var firstArg = MACHINE.env[MACHINE.env.length-1];
return firstArg === NULL; return firstArg === NULL;
}; });
Primitives['null?'].arity = 1;
Primitives['null?'].displayName = 'null?';
Primitives['vector'] = function(MACHINE) {
installPrimitiveProcedure(
'vector',
new ArityAtLeast(0),
function(MACHINE) {
var i; var i;
var result = []; var result = [];
for (i = 0; i < MACHINE.argcount; i++) { for (i = 0; i < MACHINE.argcount; i++) {
@ -955,11 +976,13 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
} }
var newVector = makeVector.apply(null, result); var newVector = makeVector.apply(null, result);
return newVector; return newVector;
}; });
Primitives['vector'].arity = new ArityAtLeast(0);
Primitives['vector'].displayName = 'vector';
Primitives['vector->list'] = function(MACHINE) {
installPrimitiveProcedure(
'vector->list',
1,
function(MACHINE) {
testArgument(MACHINE, testArgument(MACHINE,
'vector', 'vector',
isVector, isVector,
@ -973,11 +996,13 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
result = makePair(elts[elts.length - 1 - i], result); result = makePair(elts[elts.length - 1 - i], result);
} }
return result; return result;
}; });
Primitives['vector->list'].arity = 1;
Primitives['vector->list'].displayName = 'vector->list';
Primitives['list->vector'] = function(MACHINE) {
installPrimitiveProcedure(
'list->vector',
1,
function(MACHINE) {
var firstArg = MACHINE.env[MACHINE.env.length-1]; var firstArg = MACHINE.env[MACHINE.env.length-1];
var result = []; var result = [];
while (firstArg !== NULL) { while (firstArg !== NULL) {
@ -985,11 +1010,13 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
firstArg = firstArg.rest; firstArg = firstArg.rest;
} }
return makeVector.apply(null, result); return makeVector.apply(null, result);
}; });
Primitives['list->vector'].arity = 1;
Primitives['list->vector'].displayName = 'list->vector';
Primitives['vector-ref'] = function(MACHINE) {
installPrimitiveProcedure(
'vector-ref',
2,
function(MACHINE) {
testArgument(MACHINE, testArgument(MACHINE,
'vector', 'vector',
isVector, isVector,
@ -999,11 +1026,13 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
var elts = MACHINE.env[MACHINE.env.length-1].elts; var elts = MACHINE.env[MACHINE.env.length-1].elts;
var index = MACHINE.env[MACHINE.env.length-2]; var index = MACHINE.env[MACHINE.env.length-2];
return elts[index]; return elts[index];
}; });
Primitives['vector-ref'].arity = 2;
Primitives['vector-ref'].displayName = 'vector-ref';
Primitives['vector-set!'] = function(MACHINE) {
installPrimitiveProcedure(
'vector-set!',
3,
function(MACHINE) {
testArgument(MACHINE, testArgument(MACHINE,
'vector', 'vector',
isVector, isVector,
@ -1021,12 +1050,12 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
var val = MACHINE.env[MACHINE.env.length-3]; var val = MACHINE.env[MACHINE.env.length-3];
elts[index] = val; elts[index] = val;
return VOID; return VOID;
}; });
Primitives['vector-set!'].arity = 3;
Primitives['vector-set!'].displayName = 'vector-set!';
installPrimitiveProcedure(
Primitives['vector-length'] = function(MACHINE) { 'vector-length',
1,
function(MACHINE) {
testArgument(MACHINE, testArgument(MACHINE,
'vector', 'vector',
isVector, isVector,
@ -1035,12 +1064,13 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
'vector-length'); 'vector-length');
var firstArg = MACHINE.env[MACHINE.env.length-1].elts; var firstArg = MACHINE.env[MACHINE.env.length-1].elts;
return firstArg.length; return firstArg.length;
}; });
Primitives['vector-length'].arity = 1;
Primitives['vector-length'].displayName = 'vector-length';
Primitives['make-vector'] = function(MACHINE) { installPrimitiveProcedure(
'make-vector',
makeList(1, 2),
function(MACHINE) {
var value = 0; var value = 0;
testArgument(MACHINE, testArgument(MACHINE,
'natural', 'natural',
@ -1057,97 +1087,104 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
arr[i] = value; arr[i] = value;
} }
return makeVector.apply(null, arr); return makeVector.apply(null, arr);
}; });
Primitives['make-vector'].arity = makeList(1, 2);
Primitives['make-vector'].displayName = 'make-vector';
installPrimitiveProcedure(
'symbol?',
Primitives['symbol?'] = function(MACHINE) { 1,
function(MACHINE) {
var firstArg = MACHINE.env[MACHINE.env.length-1]; var firstArg = MACHINE.env[MACHINE.env.length-1];
return typeof(firstArg) === 'string'; return typeof(firstArg) === 'string';
}; });
Primitives['symbol?'].arity = 1;
Primitives['symbol?'].displayName = 'symbol?';
Primitives['symbol->string'] = function(MACHINE) { installPrimitiveProcedure(
'symbol->string',
1,
function(MACHINE) {
var firstArg = MACHINE.env[MACHINE.env.length-1]; var firstArg = MACHINE.env[MACHINE.env.length-1];
return firstArg; return firstArg;
}; });
Primitives['symbol->string'].arity = 1;
Primitives['symbol->string'].displayName = 'symbol->string';
Primitives['string-append'] = function(MACHINE) { installPrimitiveProcedure(
'string-append',
new ArityAtLeast(0),
function(MACHINE) {
var buffer = []; var buffer = [];
var i; var i;
for (i = 0; i < MACHINE.argcount; i++) { for (i = 0; i < MACHINE.argcount; i++) {
buffer.push(MACHINE.env[MACHINE.env.length - 1 - i]); buffer.push(MACHINE.env[MACHINE.env.length - 1 - i]);
} }
return buffer.join(''); return buffer.join('');
}; });
Primitives['string-append'].arity = new ArityAtLeast(0);
Primitives['string-append'].displayName = 'string-append';
Primitives['string-length'] = function(MACHINE) { installPrimitiveProcedure(
'string-length',
1,
function(MACHINE) {
var firstArg = MACHINE.env[MACHINE.env.length-1]; var firstArg = MACHINE.env[MACHINE.env.length-1];
return firstArg.length; return firstArg.length;
}; });
Primitives['string-length'].arity = 1;
Primitives['string-length'].displayName = 'string-length';
Primitives['box'] = function(MACHINE) { installPrimitiveProcedure(
'box',
1,
function(MACHINE) {
var firstArg = MACHINE.env[MACHINE.env.length-1]; var firstArg = MACHINE.env[MACHINE.env.length-1];
var result = [firstArg]; var result = [firstArg];
return result; return result;
}; });
Primitives['box'].arity = 1;
Primitives['box'].displayName = 'box';
Primitives['unbox'] = function(MACHINE) { installPrimitiveProcedure(
'unbox',
1,
function(MACHINE) {
var firstArg = MACHINE.env[MACHINE.env.length-1]; var firstArg = MACHINE.env[MACHINE.env.length-1];
return firstArg[0]; return firstArg[0];
}; });
Primitives['unbox'].arity = 1;
Primitives['unbox'].displayName = 'unbox';
Primitives['set-box!'] = function(MACHINE) { installPrimitiveProcedure(
'set-box!',
2,
function(MACHINE) {
var firstArg = MACHINE.env[MACHINE.env.length-1]; var firstArg = MACHINE.env[MACHINE.env.length-1];
var secondArg = MACHINE.env[MACHINE.env.length-2]; var secondArg = MACHINE.env[MACHINE.env.length-2];
firstArg[0] = secondArg; firstArg[0] = secondArg;
return VOID; return VOID;
}; });
Primitives['set-box!'].arity = 2;
Primitives['set-box!'].displayName = 'set-box!';
Primitives['void'] = function(MACHINE) { installPrimitiveProcedure(
'void',
new ArityAtLeast(0),
function(MACHINE) {
return VOID; return VOID;
}; });
Primitives['void'].arity = new ArityAtLeast(0);
Primitives['void'].displayName = 'void';
Primitives['eq?'] = function(MACHINE) { installPrimitiveProcedure(
'eq?',
2,
function(MACHINE) {
var firstArg = MACHINE.env[MACHINE.env.length-1]; var firstArg = MACHINE.env[MACHINE.env.length-1];
var secondArg = MACHINE.env[MACHINE.env.length-2]; var secondArg = MACHINE.env[MACHINE.env.length-2];
return firstArg === secondArg; return firstArg === secondArg;
}; });
Primitives['eq?'].arity = 2;
Primitives['eq?'].displayName = 'eq?';
Primitives['equal?'] = function(MACHINE) { installPrimitiveProcedure(
'equal?',
2,
function(MACHINE) {
var firstArg = MACHINE.env[MACHINE.env.length-1]; var firstArg = MACHINE.env[MACHINE.env.length-1];
var secondArg = MACHINE.env[MACHINE.env.length-2]; var secondArg = MACHINE.env[MACHINE.env.length-2];
return isEqual(firstArg, secondArg); return isEqual(firstArg, secondArg);
}; });
Primitives['equal?'].arity = 2;
Primitives['equal?'].displayName = 'equal?';
var isEqual = types.isEqual;
installPrimitiveProcedure(
Primitives['member'] = function(MACHINE) { 'member',
2,
function(MACHINE) {
var x = MACHINE.env[MACHINE.env.length-1]; var x = MACHINE.env[MACHINE.env.length-1];
var lst = MACHINE.env[MACHINE.env.length-2]; var lst = MACHINE.env[MACHINE.env.length-2];
var originalLst = lst; var originalLst = lst;
@ -1165,13 +1202,14 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
} }
lst = lst.rest; lst = lst.rest;
} }
}; });
Primitives['member'].arity = 2;
Primitives['member'].displayName = 'member';
Primitives['reverse'] = function(MACHINE) { installPrimitiveProcedure(
'reverse',
1,
function(MACHINE) {
var rev = NULL; var rev = NULL;
var lst = MACHINE.env[MACHINE.env.length-1]; var lst = MACHINE.env[MACHINE.env.length-1];
while(lst !== NULL) { while(lst !== NULL) {
@ -1181,9 +1219,7 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
lst = lst.rest; lst = lst.rest;
} }
return rev; return rev;
}; });
Primitives['reverse'].arity = 1;
Primitives['reverse'].displayName = 'reverse';
@ -1474,7 +1510,5 @@ if(this['plt'] === undefined) { this['plt'] = {}; }
exports['HaltError'] = HaltError; exports['HaltError'] = HaltError;
scope.link.announceReady('runtime'); scope.link.announceReady('runtime');
})(this['plt']); })(this['plt']);

View File

@ -4,8 +4,12 @@
planet/resolver planet/resolver
scribble/eval scribble/eval
racket/sandbox racket/sandbox
(for-label racket/base)) (for-label racket/base)
racket/runtime-path
"../js-assembler/get-js-vm-implemented-primitives.rkt")
@(define-runtime-path whalesong-path "..")
@;; I may need an evaluator for some small examples. @;; I may need an evaluator for some small examples.
@ -228,12 +232,15 @@ commands to do something interesting...)
@section{Internals} @section{Internals}
@;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
Skip this section if you're a regular user: this is really notes internal Please skip this section if you're a regular user: this is really
to Whalesong development. notes internal to Whalesong development, and is not relevant to most
people.
(This section should describe the internal details of the runtime,
including the type map from Racket values to JavaScript values. It These are notes that describe the internal details of the
should also describe how to write FFI bindings.) implementation, including the type map from Racket values to
JavaScript values. It should also describe how to write FFI
bindings, eventually.
@subsection{Architecture} @subsection{Architecture}
@ -246,15 +253,15 @@ compile that to an
intermediate language, and finally assemble JavaScript. intermediate language, and finally assemble JavaScript.
@verbatim|{ @verbatim|{
AST IL JS AST IL
parse-bytecode.rkt ----------> compiler.rkt --------> assembler.rkt -------> parse-bytecode.rkt -----> compiler.rkt ----> assembler.rkt
(todo)
}| }|
The IL is intended to be translated straightforwardly. We currently The IL is intended to be translated straightforwardly. We currently
have an assembler to JavaScript, as well as a simulator have an assembler to JavaScript @filepath{js-assembler/assemble.rkt},
in @filepath{simulator.rkt}. The simulator allows us to test the compiler in a as well as a simulator in @filepath{simulator/simulator.rkt}. The
controlled environment. simulator allows us to test the compiler in a controlled environment.
@subsection{parser/parse-bytecode.rkt} @subsection{parser/parse-bytecode.rkt}
@ -275,7 +282,7 @@ we don't need any of the register-saving infrastructure in the
original compiler. We also need to support slightly different linkage original compiler. We also need to support slightly different linkage
structures, since we want to support multiple value contexts. We're structures, since we want to support multiple value contexts. We're
trying to generate code that works effectively on a machine like the trying to generate code that works effectively on a machine like the
one described in \url{http://plt.eecs.northwestern.edu/racket-machine/}. one described in @url{http://plt.eecs.northwestern.edu/racket-machine/}.
The intermediate language is defined in @filepath{il-structs.rkt}, and a The intermediate language is defined in @filepath{il-structs.rkt}, and a
@ -313,7 +320,7 @@ calls work:
@item{ The head of each basic-blocked function checks to see if we @item{ The head of each basic-blocked function checks to see if we
should trampoline should trampoline
(http://en.wikipedia.org/wiki/Trampoline_(computers))} (@url{http://en.wikipedia.org/wiki/Trampoline_(computers)})}
@item{We support a limited form of computed jump by assigning an @item{We support a limited form of computed jump by assigning an
attribute to the function corresponding to a return point. See attribute to the function corresponding to a return point. See
@ -350,11 +357,55 @@ browser for testing output.
@;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
@section{Incomplete features} @subsection{Incomplete features}
@;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; @;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
(This section should describe what needs to get done next.) (This section should describe what needs to get done next.)
The only types that are mapped so far are
@itemlist[
@item{immutable strings}
@item{numbers}
@item{pairs}
@item{null}
@item{void}
@item{vectors}
]
We need to bring around the following types previously defined in @tt{js-vm}:
(This list will shrink as I get to the work!)
@itemlist[
@item{immutable vectors}
@item{regexp}
@item{byteRegexp}
@item{character}
@item{box}
@item{placeholder}
@item{path}
@item{bytes}
@item{immutable bytes}
@item{keywords}
@item{hash}
@item{hasheq}
@item{color}
@item{structs}
@item{struct types}
@item{exceptions}
@item{thread cells}
@item{big bang info}
@item{worldConfig}
@item{effectType}
@item{renderEffectType}
@item{readerGraph}
]
What are the list of primitives in @filepath{js-vm-primitives.js}? They are:
@(apply itemlist (map (lambda (name)
(item (symbol->string name)))
js-vm-primitive-names))
(I should catalog the bug list in GitHub, as well as the feature list, (I should catalog the bug list in GitHub, as well as the feature list,
so I have a better idea of what's needed to complete the project.) so I have a better idea of what's needed to complete the project.)