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:
Ken Elf Mathieu Sternberg 2015-07-03 15:47:04 -07:00
parent 254c1c0f60
commit 1c4975067d
3 changed files with 95 additions and 0 deletions

View File

@ -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'

51
chapter1/astToList.coffee Normal file
View File

@ -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

34
test/test_reader.coffee Normal file
View File

@ -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)