Hash-maps from the ballroom
This commit is contained in:
parent
308b378e02
commit
0ec30fd75b
@ -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
10
hy/lang/map.py
Normal 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()
|
@ -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
15
tests/lang/test_map.py
Normal 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"
|
||||
}
|
||||
}]
|
||||
]
|
Loading…
Reference in New Issue
Block a user