From 4db944619774c660e1317580e2004a71973b1adb Mon Sep 17 00:00:00 2001 From: "Paul R. Tagliamonte" Date: Sun, 7 Apr 2013 18:35:36 -0400 Subject: [PATCH 1/4] Fixing (with)'s syntax to be more hyish. --- NEWS | 3 +++ hy/compiler.py | 19 ++++++++++++++----- tests/compilers/test_ast.py | 7 +++++++ tests/native_tests/language.hy | 4 ++-- 4 files changed, 26 insertions(+), 7 deletions(-) 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 cf0de49..898313a 100644 --- a/hy/compiler.py +++ b/hy/compiler.py @@ -456,12 +456,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/tests/compilers/test_ast.py b/tests/compilers/test_ast.py index 31daf14..1fb438d 100644 --- a/tests/compilers/test_ast.py +++ b/tests/compilers/test_ast.py @@ -252,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 9eaf0f5..47dd111 100644 --- a/tests/native_tests/language.hy +++ b/tests/native_tests/language.hy @@ -293,8 +293,8 @@ (defn test-context [] "NATIVE: test with" - (with-as (open "README.md" "r") fd - (pass))) + (with [fd (open "README.md" "r")] (pass)) + (with [(open "README.md" "r")] (pass))) (defn test-for-doodle [] From a81a7164208c5a634dce6af87374cf11165a7e0f Mon Sep 17 00:00:00 2001 From: Julien Danjou Date: Mon, 8 Apr 2013 00:38:55 +0200 Subject: [PATCH 2/4] Be sure errors are raised at by compile, not tokenize Signed-off-by: Julien Danjou --- tests/compilers/test_ast.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/compilers/test_ast.py b/tests/compilers/test_ast.py index 31daf14..b8cbcd5 100644 --- a/tests/compilers/test_ast.py +++ b/tests/compilers/test_ast.py @@ -1,4 +1,5 @@ # Copyright (c) 2013 Paul Tagliamonte +# Copyright (c) 2013 Julien Danjou # # Permission is hereby granted, free of charge, to any person obtaining a # copy of this software and associated documentation files (the "Software"), @@ -35,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 From 83d91c3f8150c041adf7d18c6f299c0fc2604224 Mon Sep 17 00:00:00 2001 From: "Paul R. Tagliamonte" Date: Sun, 7 Apr 2013 18:39:30 -0400 Subject: [PATCH 3/4] Asserting `fd' exists inside the with --- tests/native_tests/language.hy | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/native_tests/language.hy b/tests/native_tests/language.hy index 47dd111..9df1751 100644 --- a/tests/native_tests/language.hy +++ b/tests/native_tests/language.hy @@ -293,7 +293,7 @@ (defn test-context [] "NATIVE: test with" - (with [fd (open "README.md" "r")] (pass)) + (with [fd (open "README.md" "r")] (assert fd)) (with [(open "README.md" "r")] (pass))) From e22a0ff73c8e567ae4ed58be659b3e2c2927cd22 Mon Sep 17 00:00:00 2001 From: "Paul R. Tagliamonte" Date: Sun, 7 Apr 2013 18:41:41 -0400 Subject: [PATCH 4/4] Mangle a macro until it stops moving this helps if we use a macro in something that got tree-mangled back out. --- hy/core/__init__.py | 9 ++++++--- tests/native_tests/language.hy | 5 +++++ 2 files changed, 11 insertions(+), 3 deletions(-) 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/native_tests/language.hy b/tests/native_tests/language.hy index 9eaf0f5..5beaf6f 100644 --- a/tests/native_tests/language.hy +++ b/tests/native_tests/language.hy @@ -377,6 +377,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)