From e6877c3e194418648fa834098eed0101744015ba Mon Sep 17 00:00:00 2001 From: Danny Yoo Date: Fri, 27 Jan 2012 14:47:48 -0500 Subject: [PATCH] grabbing an old version of the read library from beyond the grave of the moby probject --- js-assembler/runtime-src/read.js | 161 +++++++++++++++++++++++++++++++ 1 file changed, 161 insertions(+) create mode 100644 js-assembler/runtime-src/read.js diff --git a/js-assembler/runtime-src/read.js b/js-assembler/runtime-src/read.js new file mode 100644 index 0000000..56f65a3 --- /dev/null +++ b/js-assembler/runtime-src/read.js @@ -0,0 +1,161 @@ +var readSchemeExpressions; + + +function tokenize(s) { + + function replaceEscapes(s) { + return s.replace(/\\./g, function(match, submatch, index) { + // FIXME: add more escape sequences. + if (match == '\\n') { + return "\n"; + } + else { + return match.substring(1); + } + }); + } + + + + var tokens = []; + + var PATTERNS = [['whitespace' , /^(\s+)/], + ['comment' , /(^;[^\n]*)/], + ['(' , /^(\(|\[)/], + [')' , /^(\)|\])/], + ['\'' , /^(\')/], + ['`' , /^(`)/], + [',' , /^(,)/], + ['char', /^\#\\(newline)/], + ['char', /^\#\\(.)/], + ['number' , /^([+\-]?(?:\d+\.\d+|\d+\.|\.\d+|\d+))/], + ['string' , /^"((?:([^\\"]|(\\.)))*)"/], // comment (emacs getting confused with quote): " + ['symbol' ,/^([a-zA-Z\:\+\=\~\_\?\!\@\#\$\%\^\&\*\-\/\.\>\<][\w\:\+\=\~\_\?\!\@\#\$\%\^\&\*\-\/\.\>\<]*)/] + ]; + + while (true) { + var shouldContinue = false; + for (var i = 0; i < PATTERNS.length; i++) { + var patternName = PATTERNS[i][0]; + var pattern = PATTERNS[i][1] + var result = s.match(pattern); + if (result != null) { + if (patternName == 'string') { + result[1] = replaceEscapes(result[1]); + } + if (patternName != 'whitespace' && patternName != 'comment') { + tokens.push([patternName, result[1]]); + } + s = s.substring(result[0].length); + shouldContinue = true; + } + } + if (! shouldContinue) { + break; + } + } + return [tokens, s]; +} + + + + +(function(){ + + + readSchemeExpressions = function(s) { + var tokensAndError = tokenize(s); + var tokens = tokensAndError[0]; + if (tokensAndError[1].length > 0) { + throw new Error("Error while tokenizing: the rest of the stream is: " + tokensAndError[1]); + } + + var quoteSymbol = plt.types.Symbol.makeInstance("quote"); + var quasiquoteSymbol = plt.types.Symbol.makeInstance("quasiquote"); + var unquoteSymbol = plt.types.Symbol.makeInstance("unquote"); + var empty = plt.types.Empty.EMPTY; + + function isType(type) { + return (tokens.length > 0 && tokens[0][0] == type); + } + + function eat(expectedType) { + if (tokens.length == 0) + throw new Error("token stream exhausted while trying to eat " + + expectedType); + var t = tokens.shift(); + if (t[0] == expectedType) { + return t; + } else { + throw new Error("Unexpected token " + t); + } + } + + + + function readExpr() { + var t; + if (isType('(')) { + eat('('); + var result = readExprs(); + eat(')'); + return result; + } else if (isType("'")) { + eat("'"); + var quoted = readExpr(); + return plt.Kernel.cons(quoteSymbol, + plt.Kernel.cons(quoted, empty)); + } else if (isType('`')) { + eat("`"); + return plt.Kernel.cons(quasiquoteSymbol, + plt.kernel.cons(quoted, empty)); + } else if (isType(',')) { + eat(","); + return plt.Kernel.cons(unquoteSymbol, + plt.kernel.cons(quoted, empty)); + } else if (isType('number')) { + t = eat('number'); + if (t[1].match(/\./)) { + return plt.types.FloatPoint.makeInstance(parseFloat(t[1])); + } else { + return plt.types.Rational.makeInstance(parseInt(t[1]), 1); + } + } else if (isType('string')) { + t = eat('string'); + return plt.types.String.makeInstance(t[1]); + } else if (isType('char')) { + t = eat('char'); + if (t[1] == 'newline') { + return plt.types.Char.makeInstance('\n'); + } + else { + return plt.types.Char.makeInstance(t[1]); + } + } else if (isType('symbol')) { + t = eat('symbol'); + return plt.types.Symbol.makeInstance(t[1]); + } else { + throw new Error("Parse broke with token stream " + tokens); + } + } + + + function readExprs() { + var result = plt.types.Empty.EMPTY; + while (true) { + if (tokens.length == 0 || isType(')')) { + break; + } else { + var nextElt = readExpr(); + result = plt.types.Cons.makeInstance(nextElt, result); + } + } + return plt.Kernel.reverse(result); + } + + + + return readExprs(); + } + +}());