diff --git a/NEWS b/NEWS index 8d2d046..ca1932d 100644 --- a/NEWS +++ b/NEWS @@ -11,6 +11,9 @@ Changes from Hy 0.9.4 (catch [Exception] BODY) (catch [e Exception] BODY) (catch [e [Exception1 Exception2]] BODY) + * With's syntax was fixed to match the rest of the code. It's now: (PT) + (with [name context-managed-fn] BODY) + (with [context-managed-fn] BODY) [ Language Changes ] diff --git a/hy/compiler.py b/hy/compiler.py index fff1e60..66f10bf 100644 --- a/hy/compiler.py +++ b/hy/compiler.py @@ -476,12 +476,21 @@ class HyASTCompiler(object): fn.decorator_list = [self.compile(x) for x in expr] return fn - @builds("with_as") + @builds("with") @checkargs(min=2) - def compile_with_as_expression(self, expr): - expr.pop(0) # with-as - ctx = self.compile(expr.pop(0)) - thing = self._storeize(self.compile(expr.pop(0))) + def compile_with_expression(self, expr): + expr.pop(0) # with + + args = expr.pop(0) + if len(args) > 2 or len(args) < 1: + raise TypeError("with needs [arg (expr)] or [(expr)]") + + args.reverse() + ctx = self.compile(args.pop(0)) + + thing = None + if args != []: + thing = self._storeize(self.compile(args.pop(0))) ret = ast.With(context_expr=ctx, lineno=expr.start_line, diff --git a/hy/core/__init__.py b/hy/core/__init__.py index a17b72c..65be1af 100644 --- a/hy/core/__init__.py +++ b/hy/core/__init__.py @@ -31,9 +31,12 @@ MACROS = [ def process(tree): load_macros() - tree = mprocess(tree) - for m in hy.mangle.MANGLES: - m().mangle(tree) + old = None + while old != tree: + old = tree + tree = mprocess(tree) + for m in hy.mangle.MANGLES: + m().mangle(tree) return tree diff --git a/tests/compilers/test_ast.py b/tests/compilers/test_ast.py index 3a2d7ca..72f466f 100644 --- a/tests/compilers/test_ast.py +++ b/tests/compilers/test_ast.py @@ -36,8 +36,9 @@ def _ast_spotcheck(arg, root, secondary): def cant_compile(expr): + expr = tokenize(expr) try: - hy_compile(tokenize(expr)) + hy_compile(expr) assert False except HyCompileError: pass @@ -251,6 +252,13 @@ def test_ast_bad_assoc(): cant_compile("(assoc 1 2 3 4)") +def test_ast_bad_with(): + "Make sure AST can't compile invalid with" + cant_compile("(with)") + cant_compile("(with [])") + cant_compile("(with [] (pass))") + + def test_ast_valid_while(): "Make sure AST can't compile invalid while" hy_compile(tokenize("(while foo bar)")) diff --git a/tests/native_tests/language.hy b/tests/native_tests/language.hy index 588e3af..e029480 100644 --- a/tests/native_tests/language.hy +++ b/tests/native_tests/language.hy @@ -302,8 +302,8 @@ (defn test-context [] "NATIVE: test with" - (with-as (open "README.md" "r") fd - (pass))) + (with [fd (open "README.md" "r")] (assert fd)) + (with [(open "README.md" "r")] (pass))) (defn test-for-doodle [] @@ -386,6 +386,11 @@ (assert (= true (if true true true)))) +(defn test-nested-mangles [] + "NATIVE: test that we can use macros in mangled code" + (assert (= ((fn [] (-> 2 (+ 1 1) (* 1 2)))) 8))) + + (defn test-let-scope [] "NATIVE: test let works rightish" (setv y 123)