Hash-maps from the ballroom

This commit is contained in:
Paul Tagliamonte 2012-12-16 21:09:11 -05:00
parent 308b378e02
commit 0ec30fd75b
4 changed files with 65 additions and 0 deletions

View File

@ -42,6 +42,8 @@ def _add_native_methods(mod):
"-": _subtract, "-": _subtract,
"*": _mult, "*": _mult,
"/": _divide, "/": _divide,
"true": True,
"false": False
} }
for native in natives: for native in natives:

10
hy/lang/map.py Normal file
View File

@ -0,0 +1,10 @@
from hy.lang.hyobj import HYObject
class HYMap(dict, HYObject):
def __init__(self, nodes):
for node in nodes:
self[node] = nodes[node]
def get_children(self):
return self.keys()

View File

@ -4,6 +4,7 @@ from hy.lang.string import HYString
from hy.lang.symbol import HYSymbol from hy.lang.symbol import HYSymbol
from hy.lex.machine import Machine from hy.lex.machine import Machine
from hy.lang.list import HYList from hy.lang.list import HYList
from hy.lang.map import HYMap
WHITESPACE = [" ", "\t", "\n", "\r"] WHITESPACE = [" ", "\t", "\n", "\r"]
@ -72,6 +73,7 @@ class Expression(State):
if x == "\"": self.sub(String); return if x == "\"": self.sub(String); return
if x == "(": self.sub(Expression); return if x == "(": self.sub(Expression); return
if x == "[": self.sub(List); return if x == "[": self.sub(List); return
if x == "{": self.sub(Map); return
if x == ";": self.sub(Comment); return if x == ";": self.sub(Comment); return
self.bulk += x self.bulk += x
@ -97,6 +99,42 @@ class List(State):
if x == "\"": self.sub(String); return if x == "\"": self.sub(String); return
if x == "[": self.sub(List); return if x == "[": self.sub(List); return
if x == "(": self.sub(Expression); return if x == "(": self.sub(Expression); return
if x == "{": self.sub(Map); return
if x == ";": self.sub(Comment); return
self.bulk += x
class Map(State):
def enter(self):
self.nodes = []
self.bulk = ""
def exit(self):
if self.bulk:
self.nodes.append(HYSymbol(self.bulk))
if (len(self.nodes) % 2) != 0:
raise Exception("Hash map is fucked")
ret = HYMap({})
i = iter(self.nodes)
hmap = zip(i, i)
for key, val in hmap:
ret[key] = val
self.machine.nodes.append(ret)
def commit(self):
if self.bulk.strip() != "":
self.nodes.append(HYSymbol(self.bulk))
self.bulk = ""
def p(self, x):
if x == "}": return Idle
if x in WHITESPACE: self.commit(); return
if x == "\"": self.sub(String); return
if x == "[": self.sub(List); return
if x == "{": self.sub(Map); return
if x == "(": self.sub(Expression); return
if x == ";": self.sub(Comment); return if x == ";": self.sub(Comment); return
self.bulk += x self.bulk += x

15
tests/lang/test_map.py Normal file
View File

@ -0,0 +1,15 @@
from hy.lex.tokenize import tokenize
def test_map_lex():
assert tokenize('(def {"foo" "bar"})') == [['def', {'foo': 'bar'}]]
def test_map_lex():
assert tokenize('(def {"foo" "bar" "baz" {"one" "two"}})') == [
['def', {
'foo': 'bar',
'baz': {
"one": "two"
}
}]
]