diff --git a/hy/compiler/modfaker.py b/hy/compiler/modfaker.py index eee05a3..6b40c98 100644 --- a/hy/compiler/modfaker.py +++ b/hy/compiler/modfaker.py @@ -42,6 +42,8 @@ def _add_native_methods(mod): "-": _subtract, "*": _mult, "/": _divide, + "true": True, + "false": False } for native in natives: diff --git a/hy/lang/map.py b/hy/lang/map.py new file mode 100644 index 0000000..37902ec --- /dev/null +++ b/hy/lang/map.py @@ -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() diff --git a/hy/lex/states.py b/hy/lex/states.py index 29ee309..e01289e 100644 --- a/hy/lex/states.py +++ b/hy/lex/states.py @@ -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 diff --git a/tests/lang/test_map.py b/tests/lang/test_map.py new file mode 100644 index 0000000..b94604a --- /dev/null +++ b/tests/lang/test_map.py @@ -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" + } + }] + ]