Merge branch 'kwapply-macro' of https://github.com/Willyfrog/hy into Willyfrog-kwapply-macro
Conflicts: hy/core/language.hy hy/core/macros.hy tests/native_tests/language.hy
This commit is contained in:
commit
ec2b5fb7ad
@ -1273,19 +1273,33 @@ class HyASTCompiler(object):
|
|||||||
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@builds("kwapply")
|
@builds("apply")
|
||||||
@checkargs(2)
|
@checkargs(min=1, max=3)
|
||||||
def compile_kwapply_expression(self, expr):
|
def compile_apply_expression(self, expr):
|
||||||
expr.pop(0) # kwapply
|
expr.pop(0) # apply
|
||||||
call = self.compile(expr.pop(0))
|
call = self.compile(expr.pop(0))
|
||||||
|
call = ast.Call(func=call.expr,
|
||||||
|
args=[],
|
||||||
|
keywords=[],
|
||||||
|
starargs=None,
|
||||||
|
kwargs=None,
|
||||||
|
lineno=expr.start_line,
|
||||||
|
col_offset=expr.start_column)
|
||||||
|
ret = call
|
||||||
|
|
||||||
|
if expr:
|
||||||
|
stargs = expr.pop(0)
|
||||||
|
if stargs is not None:
|
||||||
|
stargs = self.compile(stargs)
|
||||||
|
call.starargs = stargs.force_expr
|
||||||
|
ret = stargs + ret
|
||||||
|
|
||||||
|
if expr:
|
||||||
kwargs = self.compile(expr.pop(0))
|
kwargs = self.compile(expr.pop(0))
|
||||||
|
call.kwargs = kwargs.force_expr
|
||||||
|
ret = kwargs + ret
|
||||||
|
|
||||||
if type(call.expr) != ast.Call:
|
return ret
|
||||||
raise HyTypeError(expr, "kwapplying a non-call")
|
|
||||||
|
|
||||||
call.expr.kwargs = kwargs.force_expr
|
|
||||||
|
|
||||||
return kwargs + call
|
|
||||||
|
|
||||||
@builds("not")
|
@builds("not")
|
||||||
@builds("~")
|
@builds("~")
|
||||||
|
@ -126,3 +126,21 @@
|
|||||||
`(defmacro ~name [~@args]
|
`(defmacro ~name [~@args]
|
||||||
(let ~(HyList (map (fn [x] `[~x (gensym (slice '~x 2))]) syms))
|
(let ~(HyList (map (fn [x] `[~x (gensym (slice '~x 2))]) syms))
|
||||||
~@body))))
|
~@body))))
|
||||||
|
|
||||||
|
|
||||||
|
(defmacro kwapply [call kwargs]
|
||||||
|
"Use a dictionary as keyword arguments"
|
||||||
|
(let [[-fun (car call)]
|
||||||
|
[-args (cdr call)]
|
||||||
|
[-okwargs `[(list (.items ~kwargs))]]]
|
||||||
|
(while (= -fun "kwapply") ;; join any further kw
|
||||||
|
(if (not (= (len -args) 2))
|
||||||
|
(macro-error
|
||||||
|
call
|
||||||
|
(.format "Trying to call nested kwapply with {0} args instead of 2"
|
||||||
|
(len -args))))
|
||||||
|
(.insert -okwargs 0 `(list (.items ~(car (cdr -args)))))
|
||||||
|
(setv -fun (car (car -args)))
|
||||||
|
(setv -args (cdr (car -args))))
|
||||||
|
|
||||||
|
`(apply ~-fun [~@-args] (dict (sum ~-okwargs [])))))
|
||||||
|
27
tests/compilers/test_error_reporting.py
Normal file
27
tests/compilers/test_error_reporting.py
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
# Copyright (c) 2013 Nicolas Dandrimont <nicolas.dandrimont@crans.org>
|
||||||
|
#
|
||||||
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
# copy of this software and associated documentation files (the "Software"),
|
||||||
|
# to deal in the Software without restriction, including without limitation
|
||||||
|
# the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
# and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
# Software is furnished to do so, subject to the following conditions:
|
||||||
|
#
|
||||||
|
# The above copyright notice and this permission notice shall be included in
|
||||||
|
# all copies or substantial portions of the Software.
|
||||||
|
#
|
||||||
|
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
# DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
|
from .test_ast import can_compile, cant_compile
|
||||||
|
|
||||||
|
|
||||||
|
def test_macro_nested_kwapply():
|
||||||
|
"Make sure nested kwapply compile correctly"
|
||||||
|
can_compile("(kwapply (kwapply (foo) bar) baz)")
|
||||||
|
cant_compile("(kwapply (kwapply (foo)) bar)")
|
@ -152,8 +152,27 @@
|
|||||||
(assert (= (kwapply (kwtest) {"one" "two"}) {"one" "two"}))
|
(assert (= (kwapply (kwtest) {"one" "two"}) {"one" "two"}))
|
||||||
(setv mydict {"one" "three"})
|
(setv mydict {"one" "three"})
|
||||||
(assert (= (kwapply (kwtest) mydict) mydict))
|
(assert (= (kwapply (kwtest) mydict) mydict))
|
||||||
(assert (= (kwapply (kwtest) ((fn [] {"one" "two"}))) {"one" "two"})))
|
(assert (= (kwapply (kwtest) ((fn [] {"one" "two"}))) {"one" "two"}))
|
||||||
|
(assert (= (kwapply
|
||||||
|
(kwapply
|
||||||
|
(kwapply
|
||||||
|
(kwapply
|
||||||
|
(kwapply (kwtest) {"x" 4})
|
||||||
|
mydict)
|
||||||
|
{"x" 8})
|
||||||
|
{"x" (- 3 2) "y" 2})
|
||||||
|
{"y" 5 "z" 3})
|
||||||
|
{"x" 1 "y" 5 "z" 3 "one" "three"})))
|
||||||
|
|
||||||
|
(defn test-apply []
|
||||||
|
"NATIVE: test working with args and functions"
|
||||||
|
(defn sumit [a b c] (+ a b c))
|
||||||
|
(assert (= (apply sumit [1] {"b" 2 "c" 3}) 6))
|
||||||
|
(assert (= (apply sumit [1 2 2]) 5))
|
||||||
|
(assert (= (apply sumit [] {"a" 1 "b" 1 "c" 2}) 4))
|
||||||
|
(assert (= (apply sumit ((fn [] [1 1])) {"c" 1}) 3))
|
||||||
|
(defn noargs [] [1 2 3])
|
||||||
|
(assert (= (apply noargs) [1 2 3])))
|
||||||
|
|
||||||
(defn test-dotted []
|
(defn test-dotted []
|
||||||
"NATIVE: test dotted invocation"
|
"NATIVE: test dotted invocation"
|
||||||
|
Loading…
Reference in New Issue
Block a user