diff --git a/AUTHORS b/AUTHORS index bcb412d..975c7f7 100644 --- a/AUTHORS +++ b/AUTHORS @@ -1,6 +1,7 @@ Code contributors: - Paul R. Tagliamonte + - Gergely Nagy I'd also like to thank the following people: diff --git a/eg/flask/shim.py b/eg/flask/shim.py index 4472877..8aa3517 100644 --- a/eg/flask/shim.py +++ b/eg/flask/shim.py @@ -1,4 +1,4 @@ -import hy.lang.importer +import hy.lang.importer # NOQA from app import app if __name__ == '__main__': diff --git a/hy/compiler/ast27.py b/hy/compiler/ast27.py index 20999b5..37f5d41 100644 --- a/hy/compiler/ast27.py +++ b/hy/compiler/ast27.py @@ -10,9 +10,6 @@ from hy.lang.list import HYList from hy.lang.bool import HYBool from hy.lang.map import HYMap -from hy.lang.builtins import builtins -from hy.lang.natives import natives - def _ast_print(node, children, obj): """ Handle `print' statements """ @@ -30,7 +27,7 @@ def _ast_binop(node, children, obj): # XXX: Add these folks in inv = node.get_invocation() - ops = { "+": ast.Add, "/": ast.Div, "*": ast.Mult, "-": ast.Sub } + ops = {"+": ast.Add, "/": ast.Div, "*": ast.Mult, "-": ast.Sub} op = ops[inv['function']] left = children.pop(0) calc = None @@ -164,6 +161,10 @@ class AST27Converter(object): "for": self._ast_for, "kwapply": self._ast_kwapply, } + self.special_types = { + HYMap: self._ast_fn_index, + HYList: self._ast_fn_index, + } self.in_fn = False def _ast_set_index(self, node): @@ -194,6 +195,13 @@ class AST27Converter(object): ast.Index(value=self.render(tar), ctx=ast.Load()), ast.Load()) + def _ast_fn_index(self, node): + i = node.get_invocation() + cmd = ["index"] + cmd.append(i['function']) + cmd.extend(i['args']) + return self.render_expression(HYExpression(cmd)) + def _ast_dot(self, node): inv = node.get_invocation() args = inv['args'] @@ -268,7 +276,6 @@ class AST27Converter(object): orelse=orel, ) - def _ast_for(self, node): i = node.get_invocation() args = i['args'] @@ -388,6 +395,9 @@ class AST27Converter(object): inv = node.get_invocation() + if type(inv['function']) in self.special_types: + return self.special_types[type(inv['function'])](node) + if inv['function'] in self.native_cases: return self.native_cases[inv['function']](node) @@ -402,12 +412,12 @@ class AST27Converter(object): if inv['function'] in special_cases: return special_cases[inv['function']](node, c, self) - ret = value=ast.Call( - func=self.render_symbol(inv['function']), - args=c, - keywords=[], - starargs=None, - kwargs=None + ret = ast.Call( + func=self.render_symbol(inv['function']), + args=c, + keywords=[], + starargs=None, + kwargs=None ) return ret @@ -422,7 +432,6 @@ class AST27Converter(object): node.lineno = tree.line node.col_offset = tree.column - if isinstance(ret, list): for r in ret: _correct_tree(r, tree) diff --git a/hy/lang/bool.py b/hy/lang/bool.py index 78a37ee..32bc3d6 100644 --- a/hy/lang/bool.py +++ b/hy/lang/bool.py @@ -6,4 +6,4 @@ class HYBool(HYObject): self._val = val def eval(self, lns, *args, **kwargs): - return self._val == True + return self._val is True diff --git a/hy/lang/builtins.py b/hy/lang/builtins.py index f46a0a4..fe58045 100644 --- a/hy/lang/builtins.py +++ b/hy/lang/builtins.py @@ -1,6 +1,5 @@ # import sys -from hy.lang.internals import HYNamespaceCOW from hy.lang.string import HYString diff --git a/hy/lang/importer.py b/hy/lang/importer.py index 2316e26..9457f3f 100644 --- a/hy/lang/importer.py +++ b/hy/lang/importer.py @@ -3,7 +3,6 @@ from hy.compiler.ast27 import forge_module from hy.lex.tokenize import tokenize import sys -import imp import os diff --git a/hy/lang/natives.py b/hy/lang/natives.py index 67fb9bb..07df64e 100644 --- a/hy/lang/natives.py +++ b/hy/lang/natives.py @@ -1,4 +1,3 @@ -from hy.lang.bool import HYBool from hy.lex.tokenize import tokenize as _hy_tok import sys @@ -24,6 +23,7 @@ def _foreach(*args): for arg in a: args[1](arg) + def _get(*args): m = args[0] k = args[1] @@ -85,7 +85,6 @@ def _ne(*args): def _gt(*args): - arg = args[0] for i in range(1, len(args)): if not (args[i - 1] > args[i]): return False @@ -93,7 +92,6 @@ def _gt(*args): def _ge(*args): - arg = args[0] for i in range(1, len(args)): if not (args[i - 1] >= args[i]): return False @@ -101,7 +99,6 @@ def _ge(*args): def _le(*args): - arg = args[0] for i in range(1, len(args)): if not (args[i - 1] <= args[i]): return False @@ -109,7 +106,6 @@ def _le(*args): def _lt(*args): - arg = args[0] for i in range(1, len(args)): if not (args[i - 1] < args[i]): return False diff --git a/hy/lex/states.py b/hy/lex/states.py index 6e203fc..cdc34f6 100644 --- a/hy/lex/states.py +++ b/hy/lex/states.py @@ -74,17 +74,22 @@ class Comment(State): class Idle(State): def p(self, x): - if x == "#": return HashExpression - if x == ";": return Comment - if x == "(": return Expression - if x in WHITESPACE: return + if x == "#": + return HashExpression + if x == ";": + return Comment + if x == "(": + return Expression + if x in WHITESPACE: + return raise LexException("Unknown char: %s" % (x)) class HashExpression(State): def p(self, x): - if x == "!": return Comment + if x == "!": + return Comment raise LexException("Unknwon Hash modifier - %s" % (x)) @@ -106,13 +111,26 @@ class Expression(State): 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(Expression); return - if x == "[": self.sub(List); return - if x == "{": self.sub(Map); return - if x == ";": self.sub(Comment); return + if x == ")": + return Idle + if x in WHITESPACE: + self.commit() + return + 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 @@ -132,13 +150,26 @@ class List(State): 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(Expression); return - if x == "{": self.sub(Map); return - if x == ";": self.sub(Comment); return + 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(Expression) + return + if x == "{": + self.sub(Map) + return + if x == ";": + self.sub(Comment) + return self.bulk += x @@ -167,18 +198,31 @@ class Map(State): 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 == "}": + 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 class String(State): - magic = { "n": "\n", "t": "\t", "\\": "\\", "\"": "\"" } + magic = {"n": "\n", "t": "\t", "\\": "\\", "\"": "\""} def enter(self): self.buf = "" diff --git a/hy/utils.py b/hy/utils.py deleted file mode 100644 index 4aeebb0..0000000 --- a/hy/utils.py +++ /dev/null @@ -1,67 +0,0 @@ -import os -import imp -import marshall -import struct -import time - - -MAGIC = imp.get_magic() - -def _write_long(fp, int_): - """Internal; write a 32-bit int to a file in little-endian order.""" - fp.write(chr( int_ & 0xff)) - fp.write(chr((int_ >> 8) & 0xff)) - fp.write(chr((int_ >> 16) & 0xff)) - fp.write(chr((int_ >> 24) & 0xff)) - - -def get_mtime(fp): - '''Get the last modified date from the 4-byte timestamp in the pyc file. - ''' - with open(filename, 'rb') as f: - f.seed(4) - moddate = f.read(4) - modtime = time.asctime(time.localtime(struct.unpack('L', moddate)[0])) - return modtime - - -def write_pyc(filename, codeobject, cfile=None, dfile='source'): - """Byte-compile one Python source file to Python bytecode. - - Arguments: - filename: filename associated with the bytecode (i.e., foo.py) - - cfile: target filename; defaults to source with 'c' or 'o' appended - ('c' normally, 'o' in optimizing mode, giving .pyc or .pyo) - dfile: purported filename; defaults to source (this is the filename - that will show up in error messages) - See http://hg.python.org/cpython/file/2.7/Lib/py_compile.py - """ - # 'U' opens the file in universal line-ending mode. - with open(filename, 'U') as f: - try: - timestamp = long(os.fstat(f.fileno()).st_mtime) - except AttributeError: - timestamp = long(os.stat(filename).st_mtime) - codestring = f.read() - - # Add on the .pyc (or .pyo) filename extension. - if cfile is None: - cfile = filename + (__debug__ and 'c' or 'o') - - # Write out the compiled code. - with open(cfile, 'wb') as f: - - # Write a placeholder for the magic number. - f.write('\0\0\0\0') - - # Write the timestamp. - _write_long(f, timestamp) - - # Dump the bytecode. - marshal.dump(codeobject, f) - - # Write the magic number of the placeholder. - f.flush() - f.seek(0, 0) - f.write(MAGIC) diff --git a/tests/lang/colls.hy b/tests/lang/colls.hy new file mode 100644 index 0000000..3369b0e --- /dev/null +++ b/tests/lang/colls.hy @@ -0,0 +1,5 @@ +(defn test-map-index [] + ({"foo" "bar"} "foo")) + +(defn test-list-index [] + (["first" "second"] 1)) diff --git a/tests/lang/test_types_as_fn.py b/tests/lang/test_types_as_fn.py new file mode 100644 index 0000000..d942d5a --- /dev/null +++ b/tests/lang/test_types_as_fn.py @@ -0,0 +1,7 @@ +import tests.lang.colls + +def test_map_index(): + assert tests.lang.colls.test_map_index() == "bar" + +def test_list_index(): + assert tests.lang.colls.test_list_index() == "second"