[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)
|
||||||
|
@ -87,7 +91,7 @@ evlis = (exps, env, callback) ->
|
||||||
callback cons calc, rest
|
callback cons calc, rest
|
||||||
else
|
else
|
||||||
callback nil
|
callback nil
|
||||||
|
|
||||||
lookup = (id, env) ->
|
lookup = (id, env) ->
|
||||||
if (pairp env)
|
if (pairp env)
|
||||||
if (caar env) == id
|
if (caar env) == id
|
||||||
|
@ -113,12 +117,12 @@ 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)
|
||||||
handler(nvalu node)
|
handler(nvalu node)
|
||||||
|
|
||||||
|
|
||||||
# Takes an AST node and evaluates it and its contents. A node may be
|
# Takes an AST node and evaluates it and its contents. A node may be
|
||||||
# ("list" (... contents ...)) or ("number" 42) or ("symbol" x), etc.
|
# ("list" (... contents ...)) or ("number" 42) or ("symbol" x), etc.
|
||||||
|
@ -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
|
||||||
|
@ -12,13 +13,13 @@ normalizeForm = (form) ->
|
||||||
l = cdr cdr l
|
l = cdr cdr l
|
||||||
null
|
null
|
||||||
o
|
o
|
||||||
|
|
||||||
listToVector1 = (l) ->
|
listToVector1 = (l) ->
|
||||||
while(l != nil) then p = normalizeForm(car l); l = cdr l; p
|
while(l != nil) then p = normalizeForm(car l); l = cdr l; p
|
||||||
|
|
||||||
id = (a) -> a
|
id = (a) -> a
|
||||||
|
|
||||||
methods =
|
methods =
|
||||||
'list': normalizeForms
|
'list': normalizeForms
|
||||||
'vector': (atom) -> listToVector1(atom)
|
'vector': (atom) -> listToVector1(atom)
|
||||||
'record': (atom) -> listToRecord1(atom)
|
'record': (atom) -> listToRecord1(atom)
|
||||||
|
@ -28,7 +29,7 @@ normalizeForm = (form) ->
|
||||||
'number': id
|
'number': id
|
||||||
'string': (atom) -> atom
|
'string': (atom) -> atom
|
||||||
'nil': (atom) -> nil
|
'nil': (atom) -> nil
|
||||||
|
|
||||||
# Values inherited from the VM.
|
# Values inherited from the VM.
|
||||||
'true': (atom) -> true
|
'true': (atom) -> true
|
||||||
'false': (atom) -> false
|
'false': (atom) -> false
|
||||||
|
@ -47,10 +48,8 @@ normalizeForms = (forms) ->
|
||||||
if (astObject forms)
|
if (astObject forms)
|
||||||
return normalizeForm(forms)
|
return normalizeForm(forms)
|
||||||
cons(normalizeForm(car forms), normalizeForms(cdr forms))
|
cons(normalizeForm(car forms), normalizeForms(cdr forms))
|
||||||
|
|
||||||
module.exports =
|
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) ->
|
||||||
|
@ -29,7 +29,7 @@ class Source
|
||||||
done: -> @index > @max
|
done: -> @index > @max
|
||||||
|
|
||||||
# IO -> IO
|
# IO -> IO
|
||||||
skipWS = (inStream) ->
|
skipWS = (inStream) ->
|
||||||
while inStream.peek() in WHITESPACE then inStream.next()
|
while inStream.peek() in WHITESPACE then inStream.next()
|
||||||
|
|
||||||
# (type, value, line, column) -> (node {type, value, line, column)}
|
# (type, value, line, column) -> (node {type, value, line, column)}
|
||||||
|
@ -88,7 +88,7 @@ readSymbol = (inStream, tableKeys) ->
|
||||||
if number?
|
if number?
|
||||||
return makeObj 'number', number, line, column
|
return makeObj 'number', number, line, column
|
||||||
makeObj 'symbol', symbol, line, column
|
makeObj 'symbol', symbol, line, column
|
||||||
|
|
||||||
|
|
||||||
# (Delim, TypeName) -> IO -> (IO, node) | Error
|
# (Delim, TypeName) -> IO -> (IO, node) | Error
|
||||||
makeReadPair = (delim, type) ->
|
makeReadPair = (delim, type) ->
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -12,33 +18,33 @@ class Value
|
||||||
# Represents the base class of a continuation. Calls to invoke resume
|
# Represents the base class of a continuation. Calls to invoke resume
|
||||||
# the contained continuation, which is typecast to one of the specific
|
# the contained continuation, which is typecast to one of the specific
|
||||||
# continuation needs of conditional, sequence, etc...
|
# continuation needs of conditional, sequence, etc...
|
||||||
|
|
||||||
class Continuation
|
class Continuation
|
||||||
constructor: (@k) ->
|
constructor: (@k) ->
|
||||||
invoke: (v, env, kont) ->
|
invoke: (v, env, kont) ->
|
||||||
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
|
||||||
# FullEnv and the VariableEnv.
|
# FullEnv and the VariableEnv.
|
||||||
|
|
||||||
class FullEnv extends Environment
|
class FullEnv extends Environment
|
||||||
constructor: (@others, @name) ->
|
constructor: (@others, @name) ->
|
||||||
@_type = "FullEnv"
|
@_type = "FullEnv"
|
||||||
|
@ -116,7 +122,7 @@ evaluateVariable = (name, env, kont) ->
|
||||||
# called after an update has been performed.
|
# called after an update has been performed.
|
||||||
|
|
||||||
evaluateSet = (name, exp, env, kont) ->
|
evaluateSet = (name, exp, env, kont) ->
|
||||||
evaluate exp, env, (new SetCont(kont, name, env))
|
evaluate exp, env, (new SetCont(kont, name, env))
|
||||||
|
|
||||||
class SetCont extends Continuation
|
class SetCont extends Continuation
|
||||||
constructor: (@k, @name, @env) ->
|
constructor: (@k, @name, @env) ->
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -195,7 +201,7 @@ class GatherCont extends Continuation
|
||||||
@k.resume (cons @v, v)
|
@k.resume (cons @v, v)
|
||||||
|
|
||||||
# Upon resumption, invoke the function.
|
# Upon resumption, invoke the function.
|
||||||
|
|
||||||
class ApplyCont extends Continuation
|
class ApplyCont extends Continuation
|
||||||
constructor: (@k, @fn, @env) ->
|
constructor: (@k, @fn, @env) ->
|
||||||
@_type = "ApplyCont"
|
@_type = "ApplyCont"
|
||||||
|
@ -205,13 +211,13 @@ class ApplyCont extends Continuation
|
||||||
|
|
||||||
# A special continuation that represents what we want the interpreter
|
# A special continuation that represents what we want the interpreter
|
||||||
# to do when it's done processing.
|
# to do when it's done processing.
|
||||||
|
|
||||||
class BottomCont extends Continuation
|
class BottomCont extends Continuation
|
||||||
constructor: (@k, @f) ->
|
constructor: (@k, @f) ->
|
||||||
@_type = "BottomCont"
|
@_type = "BottomCont"
|
||||||
resume: (v) ->
|
resume: (v) ->
|
||||||
@f(v)
|
@f(v)
|
||||||
|
|
||||||
class Primitive extends Value
|
class Primitive extends Value
|
||||||
constructor: (@name, @nativ) ->
|
constructor: (@name, @nativ) ->
|
||||||
@_type = "Primitive"
|
@_type = "Primitive"
|
||||||
|
@ -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
|
||||||
|
@ -309,5 +315,5 @@ definitial "list", new Primitive "list", (values, env, kont) ->
|
||||||
|
|
||||||
interpreter = (ast, kont) ->
|
interpreter = (ast, kont) ->
|
||||||
evaluate ast, env_init, new BottomCont null, kont
|
evaluate ast, env_init, new BottomCont null, kont
|
||||||
|
|
||||||
module.exports = interpreter
|
module.exports = interpreter
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
chai = require 'chai'
|
chai = require 'chai'
|
||||||
chai.should()
|
chai.should()
|
||||||
expect = chai.expect
|
expect = chai.expect
|
||||||
|
|
||||||
{cons} = require "cons-lists/lists"
|
{cons} = require "cons-lists/lists"
|
||||||
olisp = require '../chapter-lambda-1/interpreter'
|
olisp = require '../chapter-lambda-1/interpreter'
|
||||||
|
@ -27,7 +27,7 @@ describe "Core interpreter #3", ->
|
||||||
expect(lisp read '(begin (if (eq? "y" "y") "y" "n"))').to.equal("y")
|
expect(lisp read '(begin (if (eq? "y" "y") "y" "n"))').to.equal("y")
|
||||||
it "Should handle inequivalent objects that are not intrinsically truthy", ->
|
it "Should handle inequivalent objects that are not intrinsically truthy", ->
|
||||||
expect(lisp read '(begin (if (eq? "y" "x") "y" "n"))').to.equal("n")
|
expect(lisp read '(begin (if (eq? "y" "x") "y" "n"))').to.equal("n")
|
||||||
|
|
||||||
it "Should handle basic arithmetic", ->
|
it "Should handle basic arithmetic", ->
|
||||||
expect(lisp read '(begin (+ 5 5))').to.equal(10)
|
expect(lisp read '(begin (+ 5 5))').to.equal(10)
|
||||||
expect(lisp read '(begin (* 5 5))').to.equal(25)
|
expect(lisp read '(begin (* 5 5))').to.equal(25)
|
||||||
|
@ -51,4 +51,4 @@ describe "Core interpreter #3", ->
|
||||||
|
|
||||||
it "Should handle an IIFE", ->
|
it "Should handle an IIFE", ->
|
||||||
expect(lisp read '(begin ((lambda () (+ 5 5))))').to.equal(10)
|
expect(lisp read '(begin ((lambda () (+ 5 5))))').to.equal(10)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
chai = require 'chai'
|
chai = require 'chai'
|
||||||
chai.should()
|
chai.should()
|
||||||
expect = chai.expect
|
expect = chai.expect
|
||||||
|
|
||||||
{cons} = require "cons-lists/lists"
|
{cons} = require "cons-lists/lists"
|
||||||
lisp = require '../chapter1/interpreter'
|
lisp = require '../chapter1/interpreter'
|
||||||
|
@ -21,7 +21,7 @@ describe "Core interpreter #1", ->
|
||||||
expect(lisp read '(begin (if (eq? "y" "y") "y" "n"))').to.equal("y")
|
expect(lisp read '(begin (if (eq? "y" "y") "y" "n"))').to.equal("y")
|
||||||
it "Should handle inequivalent objects that are not intrinsically truthy", ->
|
it "Should handle inequivalent objects that are not intrinsically truthy", ->
|
||||||
expect(lisp read '(begin (if (eq? "y" "x") "y" "n"))').to.equal("n")
|
expect(lisp read '(begin (if (eq? "y" "x") "y" "n"))').to.equal("n")
|
||||||
|
|
||||||
it "Should handle basic arithmetic", ->
|
it "Should handle basic arithmetic", ->
|
||||||
expect(lisp read '(begin (+ 5 5))').to.equal(10)
|
expect(lisp read '(begin (+ 5 5))').to.equal(10)
|
||||||
expect(lisp read '(begin (* 5 5))').to.equal(25)
|
expect(lisp read '(begin (* 5 5))').to.equal(25)
|
||||||
|
@ -45,4 +45,4 @@ describe "Core interpreter #1", ->
|
||||||
|
|
||||||
it "Should handle an IIFE", ->
|
it "Should handle an IIFE", ->
|
||||||
expect(lisp read '(begin ((lambda () (+ 5 5))))').to.equal(10)
|
expect(lisp read '(begin ((lambda () (+ 5 5))))').to.equal(10)
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
chai = require 'chai'
|
chai = require 'chai'
|
||||||
chai.should()
|
chai.should()
|
||||||
expect = chai.expect
|
expect = chai.expect
|
||||||
|
|
||||||
{cons} = require "cons-lists/lists"
|
{cons} = require "cons-lists/lists"
|
||||||
olisp = require '../chapter3/interpreter'
|
olisp = require '../chapter3/interpreter'
|
||||||
|
@ -27,7 +27,7 @@ describe "Core interpreter #3", ->
|
||||||
expect(lisp read '(begin (if (eq? "y" "y") "y" "n"))').to.equal("y")
|
expect(lisp read '(begin (if (eq? "y" "y") "y" "n"))').to.equal("y")
|
||||||
it "Should handle inequivalent objects that are not intrinsically truthy", ->
|
it "Should handle inequivalent objects that are not intrinsically truthy", ->
|
||||||
expect(lisp read '(begin (if (eq? "y" "x") "y" "n"))').to.equal("n")
|
expect(lisp read '(begin (if (eq? "y" "x") "y" "n"))').to.equal("n")
|
||||||
|
|
||||||
it "Should handle basic arithmetic", ->
|
it "Should handle basic arithmetic", ->
|
||||||
expect(lisp read '(begin (+ 5 5))').to.equal(10)
|
expect(lisp read '(begin (+ 5 5))').to.equal(10)
|
||||||
expect(lisp read '(begin (* 5 5))').to.equal(25)
|
expect(lisp read '(begin (* 5 5))').to.equal(25)
|
||||||
|
@ -51,5 +51,5 @@ describe "Core interpreter #3", ->
|
||||||
|
|
||||||
it "Should handle an IIFE", ->
|
it "Should handle an IIFE", ->
|
||||||
expect(lisp read '(begin ((lambda () (+ 5 5))))').to.equal(10)
|
expect(lisp read '(begin ((lambda () (+ 5 5))))').to.equal(10)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
chai = require 'chai'
|
chai = require 'chai'
|
||||||
chai.should()
|
chai.should()
|
||||||
expect = chai.expect
|
expect = chai.expect
|
||||||
|
|
||||||
{cons, nil, nilp} = require "cons-lists/lists"
|
{cons, nil, nilp} = require "cons-lists/lists"
|
||||||
{read, readForms} = require '../chapter1/reader'
|
{read, readForms} = require '../chapter1/reader'
|
||||||
|
|
Loading…
Reference in New Issue