TEST: Add tests for the reader (!), which I had forgotten.
This also adds a number of accesory functions necessary for rationalizing the record structure of an object in the lex/parse phase into something more lisp-like. There's a metadata issue here that I'm not quite wrapping my head around.
This commit is contained in:
parent
254c1c0f60
commit
1c4975067d
|
@ -0,0 +1,10 @@
|
|||
{car, cdr} = require 'cons-lists/lists'
|
||||
|
||||
symbol = (form) -> (car form)
|
||||
|
||||
module.exports =
|
||||
aSymbol: symbol
|
||||
aValue: (form) -> (car cdr form)
|
||||
isAList: (form) -> (symbol form) == 'list'
|
||||
isARecord: (form) -> (symbol form) == 'record'
|
||||
isAVector: (form) -> (symbol form) == 'vector'
|
|
@ -0,0 +1,51 @@
|
|||
{car, cdr, cons, listp, nilp, nil, list, listToString} = require 'cons-lists/lists'
|
||||
{aSymbol, aValue} = require './astAccessors'
|
||||
|
||||
# RICH_AST -> LISP_AST
|
||||
normalizeForm = (form) ->
|
||||
|
||||
listToRecord1 = (l) ->
|
||||
o = Object.create(null)
|
||||
while(l != nil)
|
||||
o[normalizeForm(car l)] = normalizeForm(car cdr l)
|
||||
l = cdr cdr l
|
||||
null
|
||||
o
|
||||
|
||||
listToVector1 = (l) ->
|
||||
while(l != nil) then p = normalizeForm(car l); l = cdr l; p
|
||||
|
||||
id = (a) -> a
|
||||
|
||||
methods =
|
||||
'list': normalizeForms
|
||||
'vector': (atom) -> listToVector1(atom)
|
||||
'record': (atom) -> listToRecord1(atom)
|
||||
|
||||
# Basic native types. Meh.
|
||||
'symbol': id
|
||||
'number': id
|
||||
'string': (atom) -> atom
|
||||
'nil': (atom) -> nil
|
||||
|
||||
# Values inherited from the VM.
|
||||
'true': (atom) -> true
|
||||
'false': (atom) -> false
|
||||
'null': (atom) -> null
|
||||
'undefined': (atom) -> undefined
|
||||
|
||||
methods[(car form)](car cdr form)
|
||||
|
||||
|
||||
normalizeForms = (forms) ->
|
||||
# Yes, this reifies the expectation than an empty list and 'nil' are
|
||||
# the same.
|
||||
return nil if nilp forms
|
||||
cons(normalizeForm(car forms), normalizeForms(cdr forms))
|
||||
|
||||
module.exports =
|
||||
normalizeForm: normalizeForm
|
||||
normalizeForms: normalizeForms
|
||||
|
||||
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
chai = require 'chai'
|
||||
chai.should()
|
||||
expect = chai.expect
|
||||
|
||||
{cons, nil, nilp} = require "cons-lists/lists"
|
||||
{read, readForms} = require '../chapter1/reader'
|
||||
{normalizeForm} = require '../chapter1/astToList'
|
||||
|
||||
describe "Core reader functions", ->
|
||||
samples = [
|
||||
['nil', nil]
|
||||
['0', 0]
|
||||
['1', 1]
|
||||
['500', 500]
|
||||
['0xdeadbeef', 3735928559]
|
||||
['"Foo"', 'Foo']
|
||||
['(1)', cons(1)]
|
||||
['(1 2)', cons(1, (cons 2))]
|
||||
['(1 2 )', cons(1, (cons 2))]
|
||||
['( 1 2 )', cons(1, (cons 2))]
|
||||
['( 1 2 )', cons(1, (cons 2))]
|
||||
['("a" "b")', cons("a", (cons "b"))]
|
||||
['("a" . "b")', cons("a", "b")]
|
||||
['[]', []]
|
||||
['{}', {}]
|
||||
['[1 2 3]', [1, 2, 3]]
|
||||
['{foo "bar"}', {foo: "bar"}]
|
||||
]
|
||||
|
||||
for [t, v] in samples
|
||||
do (t, v) ->
|
||||
it "should interpret #{t} as #{v}", ->
|
||||
res = normalizeForm read t
|
||||
expect(res).to.deep.equal(v)
|
Loading…
Reference in New Issue