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,
"*": _mult,
"/": _divide,
"true": True,
"false": False
}
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.lex.machine import Machine
from hy.lang.list import HYList
from hy.lang.map import HYMap
WHITESPACE = [" ", "\t", "\n", "\r"]
@ -72,6 +73,7 @@ class Expression(State):
if x == "\"": self.sub(String); return
if x == "(": self.sub(Expression); return
if x == "[": self.sub(List); return
if x == "{": self.sub(Map); return
if x == ";": self.sub(Comment); return
self.bulk += x
@ -97,6 +99,42 @@ class List(State):
if x == "\"": self.sub(String); return
if x == "[": self.sub(List); 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
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"
}
}]
]