[chore] Lint-picked versions that pass all unit tests.
This commit is contained in:
parent
111ad5d8dc
commit
abf6c4ec50
|
@ -1,7 +1,11 @@
|
||||||
{listToString, listToVector, pairp, cons, car, cdr, caar, cddr, cdar, cadr, caadr, cadar, caddr, nilp, nil, setcdr, metacadr} = require "cons-lists/lists"
|
{listToString, listToVector, pairp, cons, car, cdr, caar, cddr, cdar,
|
||||||
|
cadr, caadr, cadar, caddr, nilp, nil, setcdr, metacadr} = require "cons-lists/lists"
|
||||||
readline = require "readline"
|
readline = require "readline"
|
||||||
{inspect} = require "util"
|
{inspect} = require "util"
|
||||||
print = require "../chapter1/print"
|
|
||||||
|
class LispInterpreterError extends Error
|
||||||
|
name: 'LispInterpreterError'
|
||||||
|
constructor: (@message) ->
|
||||||
|
|
||||||
env_init = nil
|
env_init = nil
|
||||||
env_global = env_init
|
env_global = env_init
|
||||||
|
@ -19,7 +23,7 @@ defprimitive = (name, nativ, arity) ->
|
||||||
if (vmargs.length == arity)
|
if (vmargs.length == arity)
|
||||||
callback nativ.apply null, vmargs
|
callback nativ.apply null, vmargs
|
||||||
else
|
else
|
||||||
throw "Incorrect arity")
|
throw new LispInterpreterError "Incorrect arity")
|
||||||
|
|
||||||
the_false_value = (cons "false", "boolean")
|
the_false_value = (cons "false", "boolean")
|
||||||
|
|
||||||
|
@ -50,9 +54,9 @@ extend = (env, variables, values) ->
|
||||||
(cons (cons (car variables), (car values)),
|
(cons (cons (car variables), (car values)),
|
||||||
(extend env, (cdr variables), (cdr values)))
|
(extend env, (cdr variables), (cdr values)))
|
||||||
else
|
else
|
||||||
throw "Too few values"
|
throw new LispInterpreterError "Too few values"
|
||||||
else if (nilp variables)
|
else if (nilp variables)
|
||||||
if (nilp values) then env else throw "Too many values"
|
if (nilp values) then env else throw new LispInterpreterError "Too many values"
|
||||||
else
|
else
|
||||||
if (symbolp variables)
|
if (symbolp variables)
|
||||||
(cons (cons variables, values), env)
|
(cons (cons variables, values), env)
|
||||||
|
@ -113,7 +117,7 @@ update = (id, env, value, callback) ->
|
||||||
|
|
||||||
astSymbolsToLispSymbols = (node) ->
|
astSymbolsToLispSymbols = (node) ->
|
||||||
return nil if nilp node
|
return nil if nilp node
|
||||||
throw "Not a list of variable names" if not (ntype(node) is 'list')
|
throw (new LispInterpreterError "Not a list of variable names") if not (ntype(node) is 'list')
|
||||||
handler = (node) ->
|
handler = (node) ->
|
||||||
return nil if nilp node
|
return nil if nilp node
|
||||||
cons (nvalu car node), (handler cdr node)
|
cons (nvalu car node), (handler cdr node)
|
||||||
|
@ -157,6 +161,6 @@ evaluate = (e, env, callback) ->
|
||||||
evlis (cdr exp), env, (args) ->
|
evlis (cdr exp), env, (args) ->
|
||||||
invoke fn, args, callback
|
invoke fn, args, callback
|
||||||
else
|
else
|
||||||
throw new Error("Can't handle a #{type}")
|
throw new LispInterpreterError ("Can't handle a #{type}")
|
||||||
|
|
||||||
module.exports = (c, cb) -> evaluate c, env_global, cb
|
module.exports = (c, cb) -> evaluate c, env_global, cb
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
{car, cdr, cons, listp, nilp, nil, list, pairp, listToString} = require 'cons-lists/lists'
|
{car, cdr, cons, listp, nilp, nil,
|
||||||
|
list, pairp, listToString} = require 'cons-lists/lists'
|
||||||
{aSymbol, aValue, astObject} = require './astAccessors'
|
{aSymbol, aValue, astObject} = require './astAccessors'
|
||||||
|
|
||||||
# RICH_AST -> LISP_AST
|
# RICH_AST -> LISP_AST
|
||||||
|
@ -52,5 +53,3 @@ module.exports =
|
||||||
normalizeForm: normalizeForm
|
normalizeForm: normalizeForm
|
||||||
normalizeForms: normalizeForms
|
normalizeForms: normalizeForms
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,11 @@
|
||||||
{listToString, listToVector, pairp, cons, car, cdr, caar, cddr, cdar, cadr, caadr, cadar, caddr, nilp, nil, setcdr, metacadr} = require "cons-lists/lists"
|
{listToString, listToVector, pairp, cons, car, cdr, caar, cddr,
|
||||||
|
cdar, cadr, caadr, cadar, caddr, nilp, nil, setcdr, metacadr} = require "cons-lists/lists"
|
||||||
readline = require "readline"
|
readline = require "readline"
|
||||||
{inspect} = require "util"
|
{inspect} = require "util"
|
||||||
print = require "./print"
|
|
||||||
|
|
||||||
|
class LispInterpreterError extends Error
|
||||||
|
name: 'LispInterpreterError'
|
||||||
|
constructor: (@message) ->
|
||||||
|
|
||||||
env_init = nil
|
env_init = nil
|
||||||
env_global = env_init
|
env_global = env_init
|
||||||
|
@ -20,7 +23,7 @@ defprimitive = (name, nativ, arity) ->
|
||||||
if (vmargs.length == arity)
|
if (vmargs.length == arity)
|
||||||
nativ.apply null, vmargs
|
nativ.apply null, vmargs
|
||||||
else
|
else
|
||||||
throw "Incorrect arity")
|
throw (new LispInterpreterError "Incorrect arity"))
|
||||||
|
|
||||||
the_false_value = (cons "false", "boolean")
|
the_false_value = (cons "false", "boolean")
|
||||||
|
|
||||||
|
@ -51,9 +54,9 @@ extend = (env, variables, values) ->
|
||||||
(cons (cons (car variables), (car values)),
|
(cons (cons (car variables), (car values)),
|
||||||
(extend env, (cdr variables), (cdr values)))
|
(extend env, (cdr variables), (cdr values)))
|
||||||
else
|
else
|
||||||
throw "Too few values"
|
throw new LispInterpreterError "Too few values"
|
||||||
else if (nilp variables)
|
else if (nilp variables)
|
||||||
if (nilp values) then env else throw "Too many values"
|
if (nilp values) then env else throw new LispInterpreterError "Too many values"
|
||||||
else
|
else
|
||||||
if (symbolp variables)
|
if (symbolp variables)
|
||||||
(cons (cons variables, values), env)
|
(cons (cons variables, values), env)
|
||||||
|
@ -112,7 +115,7 @@ update = (id, env, value) ->
|
||||||
|
|
||||||
astSymbolsToLispSymbols = (node) ->
|
astSymbolsToLispSymbols = (node) ->
|
||||||
return nil if nilp node
|
return nil if nilp node
|
||||||
throw "Not a list of variable names" if not (ntype(node) is 'list')
|
throw (new LispInterpreterError "Not a list of variable names") if not (ntype(node) is 'list')
|
||||||
handler = (node) ->
|
handler = (node) ->
|
||||||
return nil if nilp node
|
return nil if nilp node
|
||||||
cons (nvalu car node), (handler cdr node)
|
cons (nvalu car node), (handler cdr node)
|
||||||
|
@ -147,6 +150,6 @@ evaluate = (e, env) ->
|
||||||
else
|
else
|
||||||
invoke (evaluate (car exp), env), (evlis (cdr exp), env)
|
invoke (evaluate (car exp), env), (evlis (cdr exp), env)
|
||||||
else
|
else
|
||||||
throw new Error("Can't handle a #{type}")
|
throw new LispInterpreterError "Can't handle a #{type}"
|
||||||
|
|
||||||
module.exports = (c) -> evaluate c, env_global
|
module.exports = (c) -> evaluate c, env_global
|
||||||
|
|
|
@ -5,8 +5,8 @@
|
||||||
NEWLINES = ["\n", "\r", "\x0B", "\x0C"]
|
NEWLINES = ["\n", "\r", "\x0B", "\x0C"]
|
||||||
WHITESPACE = [" ", "\t"].concat(NEWLINES)
|
WHITESPACE = [" ", "\t"].concat(NEWLINES)
|
||||||
|
|
||||||
EOF = new (class)
|
EOF = new (class Eof)()
|
||||||
EOO = new (class)
|
EOO = new (class Eoo)()
|
||||||
|
|
||||||
class Source
|
class Source
|
||||||
constructor: (@inStream) ->
|
constructor: (@inStream) ->
|
||||||
|
@ -143,7 +143,7 @@ readMacros =
|
||||||
'[': makeReadPair ']', 'vector'
|
'[': makeReadPair ']', 'vector'
|
||||||
']': handleError "Closing bracket encountered"
|
']': handleError "Closing bracket encountered"
|
||||||
'{': makeReadPair('}', 'record', (res) ->
|
'{': makeReadPair('}', 'record', (res) ->
|
||||||
res.length % 2 == 0 and true or mkerr "record key without value")
|
res.length % 2 == 0 and true or mkerr "record key without value")
|
||||||
'}': handleError "Closing curly without corresponding opening."
|
'}': handleError "Closing curly without corresponding opening."
|
||||||
"`": prefixReader 'back-quote'
|
"`": prefixReader 'back-quote'
|
||||||
"'": prefixReader 'quote'
|
"'": prefixReader 'quote'
|
||||||
|
@ -188,19 +188,19 @@ read = (inStream, eofErrorP = false, eofError = EOF, recursiveP = false, inReadM
|
||||||
|
|
||||||
# IO -> (Form* | Error)
|
# IO -> (Form* | Error)
|
||||||
readForms = (inStream) ->
|
readForms = (inStream) ->
|
||||||
inStream = if inStream instanceof Source then inStream else new Source inStream
|
inStream = if inStream instanceof Source then inStream else new Source inStream
|
||||||
return nil if inStream.done()
|
return nil if inStream.done()
|
||||||
|
|
||||||
# IO -> (FORM*, IO) | Error
|
# IO -> (FORM*, IO) | Error
|
||||||
[line, column] = inStream.position()
|
[line, column] = inStream.position()
|
||||||
readEach = (inStream) ->
|
readEach = (inStream) ->
|
||||||
obj = read inStream, true, null, false
|
obj = read inStream, true, null, false
|
||||||
return nil if (nilp obj)
|
return nil if (nilp obj)
|
||||||
return obj if (car obj) == 'error'
|
return obj if (car obj) == 'error'
|
||||||
cons obj, readEach inStream
|
cons obj, readEach inStream
|
||||||
|
|
||||||
obj = readEach inStream
|
obj = readEach inStream
|
||||||
if (car obj) == 'error' then obj else makeObj "list", obj, line, column
|
if (car obj) == 'error' then obj else makeObj "list", obj, line, column
|
||||||
|
|
||||||
exports.read = read
|
exports.read = read
|
||||||
exports.readForms = readForms
|
exports.readForms = readForms
|
||||||
|
|
|
@ -1,7 +1,13 @@
|
||||||
{listToString, listToVector, pairp, cons, car, cdr, caar, cddr, cdar, cadr, caadr, cadar, caddr, nilp, nil, setcdr, metacadr, setcar} = require "cons-lists/lists"
|
{listToString, listToVector, pairp, cons, car, cdr, caar, cddr, cdar,
|
||||||
|
cadr, caadr, cadar, caddr, nilp, nil, setcdr,
|
||||||
|
metacadr, setcar} = require "cons-lists/lists"
|
||||||
readline = require "readline"
|
readline = require "readline"
|
||||||
{inspect} = require "util"
|
{inspect} = require "util"
|
||||||
|
|
||||||
|
class LispInterpreterError extends Error
|
||||||
|
name: 'LispInterpreterError'
|
||||||
|
constructor: (@message) ->
|
||||||
|
|
||||||
ntype = (node) -> car node
|
ntype = (node) -> car node
|
||||||
nvalu = (node) -> cadr node
|
nvalu = (node) -> cadr node
|
||||||
|
|
||||||
|
@ -19,21 +25,21 @@ class Continuation
|
||||||
if nilp cdr v
|
if nilp cdr v
|
||||||
@k.resume (car v)
|
@k.resume (car v)
|
||||||
else
|
else
|
||||||
throw "Continuations expect one argument"
|
throw new LispInterpreterError "Continuations expect one argument"
|
||||||
|
|
||||||
# Abstract class representing the environment
|
# Abstract class representing the environment
|
||||||
|
|
||||||
class Environment
|
class Environment
|
||||||
lookup: -> throw "Nonspecific invocation"
|
lookup: -> throw new LispInterpreterError "Nonspecific invocation"
|
||||||
update: -> throw "Nonspecific invocation"
|
update: -> throw new LispInterpreterError "Nonspecific invocation"
|
||||||
|
|
||||||
# Base of the environment stack. If you hit this, your variable was
|
# Base of the environment stack. If you hit this, your variable was
|
||||||
# never found for lookup/update. Note that at this time in the
|
# never found for lookup/update. Note that at this time in the
|
||||||
# class, you have not
|
# class, you have not
|
||||||
|
|
||||||
class NullEnv extends Environment
|
class NullEnv extends Environment
|
||||||
lookup: (e) -> throw "Unknown variable #{e}"
|
lookup: (e) -> throw new LispInterpreterError "Unknown variable #{e}"
|
||||||
update: (e) -> throw "Unknown variable #{e}"
|
update: (e) -> throw new LispInterpreterError "Unknown variable #{e}"
|
||||||
|
|
||||||
# This appears to be an easy and vaguely abstract handle to the
|
# This appears to be an easy and vaguely abstract handle to the
|
||||||
# environment. The book is not clear on the distinction between the
|
# environment. The book is not clear on the distinction between the
|
||||||
|
@ -149,7 +155,7 @@ extend = (env, names, values) ->
|
||||||
if (pairp names) and (pairp values)
|
if (pairp names) and (pairp values)
|
||||||
new VariableEnv (extend env, (cdr names), (cdr values)), (car names), (car values)
|
new VariableEnv (extend env, (cdr names), (cdr values)), (car names), (car values)
|
||||||
else if (nilp names)
|
else if (nilp names)
|
||||||
if (nilp values) then env else throw "Arity mismatch"
|
if (nilp values) then env else throw new LispInterpreterError "Arity mismatch"
|
||||||
else
|
else
|
||||||
new VariableEnv env, names, values
|
new VariableEnv env, names, values
|
||||||
|
|
||||||
|
@ -220,7 +226,7 @@ class Primitive extends Value
|
||||||
|
|
||||||
astSymbolsToLispSymbols = (node) ->
|
astSymbolsToLispSymbols = (node) ->
|
||||||
return nil if nilp node
|
return nil if nilp node
|
||||||
throw "Not a list of variable names" if not (ntype(node) is 'list')
|
throw (new LispInterpreterError "Not a list of variable names") if not (ntype(node) is 'list')
|
||||||
handler = (node) ->
|
handler = (node) ->
|
||||||
return nil if nilp node
|
return nil if nilp node
|
||||||
cons (nvalu car node), (handler cdr node)
|
cons (nvalu car node), (handler cdr node)
|
||||||
|
@ -245,7 +251,7 @@ evaluate = (e, env, kont) ->
|
||||||
else
|
else
|
||||||
evaluateApplication (car exp), (cdr exp), env, kont
|
evaluateApplication (car exp), (cdr exp), env, kont
|
||||||
else
|
else
|
||||||
throw new Error("Can't handle a '#{type}'")
|
throw new LispInterpreterError("Can't handle a '#{type}'")
|
||||||
|
|
||||||
env_init = new NullEnv()
|
env_init = new NullEnv()
|
||||||
|
|
||||||
|
@ -259,7 +265,7 @@ defprimitive = (name, nativ, arity) ->
|
||||||
if (vmargs.length == arity)
|
if (vmargs.length == arity)
|
||||||
kont.resume (nativ.apply null, vmargs)
|
kont.resume (nativ.apply null, vmargs)
|
||||||
else
|
else
|
||||||
throw "Incorrect arity"
|
throw new LispInterpreterError "Incorrect arity"
|
||||||
|
|
||||||
defpredicate = (name, nativ, arity) ->
|
defpredicate = (name, nativ, arity) ->
|
||||||
defprimitive name, ((a, b) -> if nativ.call(null, a, b) then true else the_false_value), arity
|
defprimitive name, ((a, b) -> if nativ.call(null, a, b) then true else the_false_value), arity
|
||||||
|
@ -294,7 +300,7 @@ definitial "call/cc", new Primitive "call/cc", (values, env, kont) ->
|
||||||
if nilp cdr values
|
if nilp cdr values
|
||||||
(car values).invoke (cons kont), env, kont
|
(car values).invoke (cons kont), env, kont
|
||||||
else
|
else
|
||||||
throw ["Incorrect arity for call/cc", [r, k]]
|
throw new LispInterpreterError "Incorrect arity for call/cc"
|
||||||
|
|
||||||
definitial "apply", new Primitive "apply", (values, env, kont) ->
|
definitial "apply", new Primitive "apply", (values, env, kont) ->
|
||||||
if pairp cdr values
|
if pairp cdr values
|
||||||
|
|
Loading…
Reference in New Issue