From 9a31fc1f81524c746efa60308582dbbb4ef8373d Mon Sep 17 00:00:00 2001 From: "Paul R. Tagliamonte" Date: Mon, 4 Mar 2013 22:35:07 -0500 Subject: [PATCH] Futzin' with some things. --- hy/__init__.py | 3 +++ hy/compiler.py | 46 ++++++++++++++++++++++++++++++++++- hy/importer.py | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 113 insertions(+), 1 deletion(-) diff --git a/hy/__init__.py b/hy/__init__.py index bde886c..bd4d8a9 100644 --- a/hy/__init__.py +++ b/hy/__init__.py @@ -21,3 +21,6 @@ __appname__ = "hy" __version__ = "0.ALPHA.REALLY.1.0~pre0" + + +import hy.importer diff --git a/hy/compiler.py b/hy/compiler.py index 7a041d5..b2c6f93 100644 --- a/hy/compiler.py +++ b/hy/compiler.py @@ -48,6 +48,7 @@ class HyASTCompiler(object): def __init__(self): self.returnable = False + self.anon_fn_count = 0 def compile(self, tree): for _type in _compile_table: @@ -82,7 +83,11 @@ class HyASTCompiler(object): @builds(HyExpression) def compile_expression(self, expression): - return ast.Call(func=self.compile_symbol(expression[0]), + fn = expression[0] + if fn in _compile_table: + return _compile_table[fn](self, expression) + + return ast.Call(func=self.compile_symbol(fn), args=[self.compile(x) for x in expression[1:]], keywords=[], starargs=None, @@ -90,6 +95,45 @@ class HyASTCompiler(object): lineno=expression.start_line, col_offset=expression.start_column) + @builds("fn") + def compile_fn_expression(self, expression): + ret_status = self.returnable + self.returnable = True + + expression.pop(0) # fn + + self.anon_fn_count += 1 + name = "_hy_anon_fn_%d" % (self.anon_fn_count) + sig = expression.pop(0) + + ret = ast.FunctionDef( + name=name, + lineno=expression.start_line, + col_offset=expression.start_column, + args=ast.arguments( + args=[ + ast.Name( + arg=str(x), + id=str(x), + ctx=ast.Param(), + lineno=x.start_line, + col_offset=x.start_column + ) for x in sig + ], + vararg=None, + kwarg=None, + kwonlyargs=[], + kw_defaults=[], + defaults=[] + ), + body=self._mangle_branch([self.compile(x) for x in expression]), + decorator_list=[] + ) + + self.returnable = ret_status + return ret + + @builds(HySymbol) def compile_symbol(self, symbol): return ast.Name(id=str(symbol), ctx=ast.Load(), diff --git a/hy/importer.py b/hy/importer.py index e8de9ab..413d302 100644 --- a/hy/importer.py +++ b/hy/importer.py @@ -2,7 +2,10 @@ from hy.lex import tokenize from hy.compiler import hy_compile + import imp +import sys +import os def import_file_to_module(name, fpath): @@ -11,3 +14,65 @@ def import_file_to_module(name, fpath): mod.__file__ = fpath eval(compile(ast, fpath, "exec"), mod.__dict__) return mod + + +class HyFinder(object): + def is_package(self, fullname): + dirpath = "/".join(fullname.split(".")) + for pth in sys.path: + pth = os.path.abspath(pth) + composed_path = "%s/%s/__init__.hy" % (pth, dirpath) + if os.path.exists(composed_path): + return True + return False + + def find_on_path(self, fullname): + fls = ["%s/__init__.hy", "%s.hy"] + dirpath = "/".join(fullname.split(".")) + + for pth in sys.path: + pth = os.path.abspath(pth) + for fp in fls: + composed_path = fp % ("%s/%s" % (pth, dirpath)) + if os.path.exists(composed_path): + return composed_path + + +class MetaLoader(HyFinder): + def load_module(self, fullname): + if fullname in sys.modules: + return sys.modules[fullname] + + pth = self.find_on_path(fullname) + if pth is None: + return + + sys.modules[fullname] = None + mod = import_file_to_module(fullname, pth) + + ispkg = self.is_package(fullname) + + mod.__file__ = pth + mod.__loader__ = self + mod.__name__ = fullname + + if ispkg: + mod.__path__ = [] + mod.__package__ = fullname + else: + mod.__package__ = fullname.rpartition('.')[0] + + sys.modules[fullname] = mod + return mod + + +class MetaImporter(HyFinder): + def find_module(self, fullname, path=None): + pth = self.find_on_path(fullname) + if pth is None: + return + return MetaLoader() + + +sys.meta_path.append(MetaImporter()) +sys.path.insert(0, "")