[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:
parent
8572d84817
commit
560bcd4dda
|
@ -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'
|
||||||
|
|
|
@ -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 =
|
||||||
|
|
|
@ -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()
|
||||||
|
|
Loading…
Reference in New Issue