[bug] Fixed the reader to handle dotted lists.

This support is ugly and probably incorrect, but it passes all the current
tests and handles test cases in the original documentation.
This commit is contained in:
Elf M. Sternberg 2015-07-07 19:56:11 -07:00
parent 8572d84817
commit 560bcd4dda
3 changed files with 18 additions and 5 deletions

View File

@ -1,8 +1,9 @@
{car, cdr} = require 'cons-lists/lists' {car, cdr, listp} = require 'cons-lists/lists'
symbol = (form) -> (car form) symbol = (form) -> (car form)
module.exports = module.exports =
astObject: (form) -> typeof (car form) == "string"
aSymbol: symbol aSymbol: symbol
aValue: (form) -> (car cdr form) aValue: (form) -> (car cdr form)
isAList: (form) -> (symbol form) == 'list' isAList: (form) -> (symbol form) == 'list'

View File

@ -1,7 +1,8 @@
{car, cdr, cons, listp, nilp, nil, list, listToString} = require 'cons-lists/lists' {car, cdr, cons, listp, nilp, nil, list, pairp, listToString} = require 'cons-lists/lists'
{aSymbol, aValue} = require './astAccessors' {aSymbol, aValue, astObject} = require './astAccessors'
# RICH_AST -> LISP_AST # RICH_AST -> LISP_AST
normalizeForm = (form) -> normalizeForm = (form) ->
listToRecord1 = (l) -> listToRecord1 = (l) ->
@ -41,6 +42,10 @@ normalizeForms = (forms) ->
# Yes, this reifies the expectation than an empty list and 'nil' are # Yes, this reifies the expectation than an empty list and 'nil' are
# the same. # the same.
return nil if nilp forms return nil if nilp forms
# Handle dotted list.
if (astObject forms)
return normalizeForm(forms)
cons(normalizeForm(car forms), normalizeForms(cdr forms)) cons(normalizeForm(car forms), normalizeForms(cdr forms))
module.exports = module.exports =

View File

@ -102,13 +102,20 @@ makeReadPair = (delim, type) ->
return makeObj(type, nil, line, column) return makeObj(type, nil, line, column)
# IO -> (IO, Node) | Error # IO -> (IO, Node) | Error
dotted = false
readEachPair = (inStream) -> readEachPair = (inStream) ->
[line, column] = inStream.position() [line, column] = inStream.position()
obj = read inStream, true, null, true obj = read inStream, true, null, true
if inStream.peek() == delim then return cons obj, nil if inStream.peek() == delim
if dotted then return obj
return cons obj, nil
if inStream.done() then return handleError("Unexpected end of input")(line, column) if inStream.done() then return handleError("Unexpected end of input")(line, column)
if dotted then return handleError("More than one symbol after dot")
return obj if (car obj) == 'error' return obj if (car obj) == 'error'
cons obj, readEachPair(inStream) if (car obj) == 'symbol' and (car cdr obj) == '.'
dotted = true
return readEachPair inStream
cons obj, readEachPair inStream
ret = makeObj type, readEachPair(inStream), line, column ret = makeObj type, readEachPair(inStream), line, column
inStream.next() inStream.next()