Merge branch 'master' into pr/593
This commit is contained in:
commit
f3ecb96119
@ -305,7 +305,7 @@ Some example usage:
|
|||||||
Yeah, really!
|
Yeah, really!
|
||||||
|
|
||||||
;; assuming that (side-effect) is a function that we want to call for each
|
;; assuming that (side-effect) is a function that we want to call for each
|
||||||
;; and every value in the list, but which return values we do not care
|
;; and every value in the list, but whose return value we do not care about
|
||||||
=> (list-comp (do (side-effect x)
|
=> (list-comp (do (side-effect x)
|
||||||
... (if (< x 5) (* 2 x)
|
... (if (< x 5) (* 2 x)
|
||||||
... (* 4 x)))
|
... (* 4 x)))
|
||||||
@ -416,7 +416,7 @@ Parameters may have following keywords in front of them:
|
|||||||
arguments may be specified after this one.
|
arguments may be specified after this one.
|
||||||
|
|
||||||
The following code example defines a function that can be given 0 to n
|
The following code example defines a function that can be given 0 to n
|
||||||
numerical parameters. It then sums every odd number and substracts
|
numerical parameters. It then sums every odd number and subtracts
|
||||||
every even number.
|
every even number.
|
||||||
|
|
||||||
.. code-block:: clj
|
.. code-block:: clj
|
||||||
@ -1293,23 +1293,48 @@ file is automatically closed after it has been processed.
|
|||||||
with-decorator
|
with-decorator
|
||||||
--------------
|
--------------
|
||||||
|
|
||||||
`with-decorator` is used to wrap a function with another. The function performing
|
`with-decorator` is used to wrap a function with another. The function
|
||||||
decoration should accept a single value, the function being decorated and return
|
performing decoration should accept a single value, the function being
|
||||||
a new function. `with-decorator` takes two parameters, the function performing
|
decorated and return a new function. `with-decorator` takes a minimum
|
||||||
decoration and the function being decorated.
|
of two parameters, the function performing decoration and the function
|
||||||
|
being decorated. More than one decorator function can be applied, they
|
||||||
In the following example, `inc-decorator` is used to decorate function `addition`
|
will be applied in order from outermost to innermost, ie. the first
|
||||||
with a function that takes two parameters and calls the decorated function with
|
decorator will be the outermost one & so on. Decorators with arguments
|
||||||
values that are incremented by 1. When decorated `addition` is called with values
|
are called just like a function call.
|
||||||
1 and 1, the end result will be 4 (1+1 + 1+1).
|
|
||||||
|
|
||||||
.. code-block:: clj
|
.. code-block:: clj
|
||||||
|
|
||||||
=> (defn inc-decorator [func]
|
(with-decorator decorator-fun
|
||||||
|
(defn some-function [] ...)
|
||||||
|
|
||||||
|
(with-decorator decorator1 decorator2 ...
|
||||||
|
(defn some-function [] ...)
|
||||||
|
|
||||||
|
(with-decorator (decorator arg) ..
|
||||||
|
(defn some-function [] ...)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
In the following example, `inc-decorator` is used to decorate function
|
||||||
|
`addition` with a function that takes two parameters and calls the
|
||||||
|
decorated function with values that are incremented by 1. When
|
||||||
|
decorated `addition` is called with values 1 and 1, the end result
|
||||||
|
will be 4 (1+1 + 1+1).
|
||||||
|
|
||||||
|
.. code-block:: clj
|
||||||
|
|
||||||
|
=> (defn inc-decorator [func]
|
||||||
... (fn [value-1 value-2] (func (+ value-1 1) (+ value-2 1))))
|
... (fn [value-1 value-2] (func (+ value-1 1) (+ value-2 1))))
|
||||||
|
=> (defn inc2-decorator [func]
|
||||||
|
... (fn [value-1 value-2] (func (+ value-1 2) (+ value-2 2))))
|
||||||
|
|
||||||
=> (with-decorator inc-decorator (defn addition [a b] (+ a b)))
|
=> (with-decorator inc-decorator (defn addition [a b] (+ a b)))
|
||||||
=> (addition 1 1)
|
=> (addition 1 1)
|
||||||
4
|
4
|
||||||
|
=> (with-decorator inc2-decorator inc-decorator
|
||||||
|
... (defn addition [a b] (+ a b)))
|
||||||
|
=> (addition 1 1)
|
||||||
|
8
|
||||||
|
|
||||||
|
|
||||||
.. _with-gensyms:
|
.. _with-gensyms:
|
||||||
|
@ -23,7 +23,6 @@ from hy.version import __version__, __appname__ # NOQA
|
|||||||
|
|
||||||
|
|
||||||
from hy.models.expression import HyExpression # NOQA
|
from hy.models.expression import HyExpression # NOQA
|
||||||
from hy.models.lambdalist import HyLambdaListKeyword # NOQA
|
|
||||||
from hy.models.integer import HyInteger # NOQA
|
from hy.models.integer import HyInteger # NOQA
|
||||||
from hy.models.keyword import HyKeyword # NOQA
|
from hy.models.keyword import HyKeyword # NOQA
|
||||||
from hy.models.complex import HyComplex # NOQA
|
from hy.models.complex import HyComplex # NOQA
|
||||||
|
@ -47,7 +47,7 @@ from hy.models.expression import HyExpression
|
|||||||
from hy.models.string import HyString
|
from hy.models.string import HyString
|
||||||
from hy.models.symbol import HySymbol
|
from hy.models.symbol import HySymbol
|
||||||
|
|
||||||
from hy._compat import builtins
|
from hy._compat import builtins, PY3
|
||||||
|
|
||||||
|
|
||||||
class HyQuitter(object):
|
class HyQuitter(object):
|
||||||
@ -327,6 +327,7 @@ def hyc_main():
|
|||||||
|
|
||||||
# entry point for cmd line script "hy2py"
|
# entry point for cmd line script "hy2py"
|
||||||
def hy2py_main():
|
def hy2py_main():
|
||||||
|
import platform
|
||||||
module_name = "<STDIN>"
|
module_name = "<STDIN>"
|
||||||
|
|
||||||
options = dict(prog="hy2py", usage="%(prog)s [options] FILE",
|
options = dict(prog="hy2py", usage="%(prog)s [options] FILE",
|
||||||
@ -349,17 +350,42 @@ def hy2py_main():
|
|||||||
|
|
||||||
if options.with_source:
|
if options.with_source:
|
||||||
hst = import_file_to_hst(options.args[0])
|
hst = import_file_to_hst(options.args[0])
|
||||||
print(hst)
|
# need special printing on Windows in case the
|
||||||
|
# codepage doesn't support utf-8 characters
|
||||||
|
if PY3 and platform.system() == "Windows":
|
||||||
|
for h in hst:
|
||||||
|
try:
|
||||||
|
print(h)
|
||||||
|
except:
|
||||||
|
print(str(h).encode('utf-8'))
|
||||||
|
else:
|
||||||
|
print(hst)
|
||||||
print()
|
print()
|
||||||
print()
|
print()
|
||||||
|
|
||||||
_ast = import_file_to_ast(options.args[0], module_name)
|
_ast = import_file_to_ast(options.args[0], module_name)
|
||||||
if options.with_ast:
|
if options.with_ast:
|
||||||
print(astor.dump(_ast))
|
if PY3 and platform.system() == "Windows":
|
||||||
|
_print_for_windows(astor.dump(_ast))
|
||||||
|
else:
|
||||||
|
print(astor.dump(_ast))
|
||||||
print()
|
print()
|
||||||
print()
|
print()
|
||||||
|
|
||||||
if not options.without_python:
|
if not options.without_python:
|
||||||
print(astor.codegen.to_source(_ast))
|
if PY3 and platform.system() == "Windows":
|
||||||
|
_print_for_windows(astor.codegen.to_source(_ast))
|
||||||
|
else:
|
||||||
|
print(astor.codegen.to_source(_ast))
|
||||||
|
|
||||||
parser.exit(0)
|
parser.exit(0)
|
||||||
|
|
||||||
|
|
||||||
|
# need special printing on Windows in case the
|
||||||
|
# codepage doesn't support utf-8 characters
|
||||||
|
def _print_for_windows(src):
|
||||||
|
for line in src.split("\n"):
|
||||||
|
try:
|
||||||
|
print(line)
|
||||||
|
except:
|
||||||
|
print(line.encode('utf-8'))
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
# -*- encoding: utf-8 -*-
|
# -*- encoding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# Copyright (c) 2013 Paul Tagliamonte <paultag@debian.org>
|
# Copyright (c) 2013, 2014 Paul Tagliamonte <paultag@debian.org>
|
||||||
# Copyright (c) 2013 Julien Danjou <julien@danjou.info>
|
# Copyright (c) 2013 Julien Danjou <julien@danjou.info>
|
||||||
# Copyright (c) 2013 Nicolas Dandrimont <nicolas.dandrimont@crans.org>
|
# Copyright (c) 2013 Nicolas Dandrimont <nicolas.dandrimont@crans.org>
|
||||||
# Copyright (c) 2013 James King <james@agentultra.com>
|
# Copyright (c) 2013 James King <james@agentultra.com>
|
||||||
# Copyright (c) 2013 Bob Tolbert <bob@tolbert.org>
|
# Copyright (c) 2013, 2014 Bob Tolbert <bob@tolbert.org>
|
||||||
#
|
#
|
||||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
# copy of this software and associated documentation files (the "Software"),
|
# copy of this software and associated documentation files (the "Software"),
|
||||||
@ -24,7 +24,6 @@
|
|||||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
# DEALINGS IN THE SOFTWARE.
|
# DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
from hy.models.lambdalist import HyLambdaListKeyword
|
|
||||||
from hy.models.expression import HyExpression
|
from hy.models.expression import HyExpression
|
||||||
from hy.models.keyword import HyKeyword
|
from hy.models.keyword import HyKeyword
|
||||||
from hy.models.integer import HyInteger
|
from hy.models.integer import HyInteger
|
||||||
@ -430,6 +429,7 @@ class HyASTCompiler(object):
|
|||||||
|
|
||||||
def _parse_lambda_list(self, exprs):
|
def _parse_lambda_list(self, exprs):
|
||||||
""" Return FunctionDef parameter values from lambda list."""
|
""" Return FunctionDef parameter values from lambda list."""
|
||||||
|
ll_keywords = ("&rest", "&optional", "&key", "&kwargs")
|
||||||
ret = Result()
|
ret = Result()
|
||||||
args = []
|
args = []
|
||||||
defaults = []
|
defaults = []
|
||||||
@ -439,10 +439,7 @@ class HyASTCompiler(object):
|
|||||||
|
|
||||||
for expr in exprs:
|
for expr in exprs:
|
||||||
|
|
||||||
if isinstance(expr, HyLambdaListKeyword):
|
if expr in ll_keywords:
|
||||||
if expr not in expr._valid_types:
|
|
||||||
raise HyTypeError(expr, "{0} is not a valid "
|
|
||||||
"lambda-keyword.".format(repr(expr)))
|
|
||||||
if expr == "&rest" and lambda_keyword is None:
|
if expr == "&rest" and lambda_keyword is None:
|
||||||
lambda_keyword = expr
|
lambda_keyword = expr
|
||||||
elif expr == "&optional":
|
elif expr == "&optional":
|
||||||
@ -616,7 +613,7 @@ class HyASTCompiler(object):
|
|||||||
|
|
||||||
return imports, ret.replace(form), False
|
return imports, ret.replace(form), False
|
||||||
|
|
||||||
elif isinstance(form, (HySymbol, HyLambdaListKeyword)):
|
elif isinstance(form, HySymbol):
|
||||||
return imports, HyExpression([HySymbol(name),
|
return imports, HyExpression([HySymbol(name),
|
||||||
HyString(form)]).replace(form), False
|
HyString(form)]).replace(form), False
|
||||||
|
|
||||||
@ -707,7 +704,8 @@ class HyASTCompiler(object):
|
|||||||
lineno=expr.start_line,
|
lineno=expr.start_line,
|
||||||
col_offset=expr.start_column)
|
col_offset=expr.start_column)
|
||||||
|
|
||||||
returnable = Result(expr=expr_name, temp_variables=[expr_name, name])
|
returnable = Result(expr=expr_name, temp_variables=[expr_name, name],
|
||||||
|
contains_yield=body.contains_yield)
|
||||||
|
|
||||||
body += ast.Assign(targets=[name],
|
body += ast.Assign(targets=[name],
|
||||||
value=body.force_expr,
|
value=body.force_expr,
|
||||||
@ -999,7 +997,10 @@ class HyASTCompiler(object):
|
|||||||
@checkargs(max=1)
|
@checkargs(max=1)
|
||||||
def compile_yield_expression(self, expr):
|
def compile_yield_expression(self, expr):
|
||||||
expr.pop(0)
|
expr.pop(0)
|
||||||
ret = Result(contains_yield=True)
|
if PY33:
|
||||||
|
ret = Result(contains_yield=False)
|
||||||
|
else:
|
||||||
|
ret = Result(contains_yield=True)
|
||||||
|
|
||||||
value = None
|
value = None
|
||||||
if expr != []:
|
if expr != []:
|
||||||
|
@ -84,18 +84,20 @@
|
|||||||
|
|
||||||
(defmacro ap-first [predfn lst]
|
(defmacro ap-first [predfn lst]
|
||||||
"Yield the first element that passes `predfn`"
|
"Yield the first element that passes `predfn`"
|
||||||
`(let [[n (gensym)]]
|
(with-gensyms [n]
|
||||||
(ap-each ~lst (when ~predfn (setv n it) (break)))
|
`(let [[~n None]]
|
||||||
n))
|
(ap-each ~lst (when ~predfn (setv ~n it) (break)))
|
||||||
|
~n)))
|
||||||
|
|
||||||
|
|
||||||
(defmacro ap-last [predfn lst]
|
(defmacro ap-last [predfn lst]
|
||||||
"Yield the last element that passes `predfn`"
|
"Yield the last element that passes `predfn`"
|
||||||
`(let [[n (gensym)]]
|
(with-gensyms [n]
|
||||||
(ap-each ~lst (none? n)
|
`(let [[~n None]]
|
||||||
(when ~predfn
|
(ap-each ~lst (none? ~n)
|
||||||
(setv n it)))
|
(when ~predfn
|
||||||
n))
|
(setv ~n it)))
|
||||||
|
~n)))
|
||||||
|
|
||||||
|
|
||||||
(defmacro ap-reduce [form lst &optional [initial-value None]]
|
(defmacro ap-reduce [form lst &optional [initial-value None]]
|
||||||
|
@ -1,3 +1,4 @@
|
|||||||
STDLIB = [
|
STDLIB = [
|
||||||
"hy.core.language"
|
"hy.core.language",
|
||||||
|
"hy.core.shadow"
|
||||||
]
|
]
|
||||||
|
@ -92,7 +92,8 @@
|
|||||||
(setv map itertools.imap)
|
(setv map itertools.imap)
|
||||||
(setv zip itertools.izip)
|
(setv zip itertools.izip)
|
||||||
(setv range xrange)
|
(setv range xrange)
|
||||||
(setv input raw_input))
|
(setv input raw_input)
|
||||||
|
(setv reduce reduce))
|
||||||
(do
|
(do
|
||||||
(setv reduce functools.reduce)
|
(setv reduce functools.reduce)
|
||||||
(setv filterfalse itertools.filterfalse)
|
(setv filterfalse itertools.filterfalse)
|
||||||
@ -331,10 +332,12 @@
|
|||||||
(_numeric_check n)
|
(_numeric_check n)
|
||||||
(= n 0))
|
(= n 0))
|
||||||
|
|
||||||
(def *exports* '[butlast calling-module-name coll? cons cons? cycle dec distinct
|
(def *exports* '[butlast calling-module-name coll? cons cons? cycle
|
||||||
disassemble drop drop-while empty? even? every? first filter
|
dec distinct disassemble drop drop-while empty? even?
|
||||||
flatten float? gensym identity inc instance? integer
|
every? first filter flatten float? gensym identity
|
||||||
integer? integer-char? iterable? iterate iterator? keyword?
|
inc instance? integer integer? integer-char?
|
||||||
list* macroexpand macroexpand-1 map neg? nil? none? nth
|
iterable? iterate iterator? keyword? list*
|
||||||
numeric? odd? pos? range remove repeat repeatedly rest second
|
macroexpand macroexpand-1 map neg? nil? none? nth
|
||||||
some string string? take take-nth take-while zero? zip zipwith])
|
numeric? odd? pos? range remove repeat repeatedly
|
||||||
|
rest reduce second some string string? take take-nth
|
||||||
|
take-while zero? zip zipwith])
|
||||||
|
61
hy/core/shadow.hy
Normal file
61
hy/core/shadow.hy
Normal file
@ -0,0 +1,61 @@
|
|||||||
|
;; Copyright (c) 2014 Paul Tagliamonte <paultag@debian.org>
|
||||||
|
;; Copyright (c) 2014 James King <james@agentultra.com>
|
||||||
|
|
||||||
|
;; 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.
|
||||||
|
|
||||||
|
;;;; Hy shadow functions
|
||||||
|
|
||||||
|
(import operator)
|
||||||
|
|
||||||
|
|
||||||
|
(defn + [&rest args]
|
||||||
|
"Shadow + operator for when we need to import / map it against something"
|
||||||
|
(if (= (len args) 0)
|
||||||
|
0
|
||||||
|
(sum args))) ; shortcut here.
|
||||||
|
|
||||||
|
|
||||||
|
(defn - [&rest args]
|
||||||
|
"Shadow - operator for when we need to import / map it against something"
|
||||||
|
(let [[count (len args)]]
|
||||||
|
(if (= count 0)
|
||||||
|
(raise (TypeError "Need at least 1 argument to subtract"))
|
||||||
|
(if (= count 1)
|
||||||
|
(- (get args 0))
|
||||||
|
(reduce operator.sub args)))))
|
||||||
|
|
||||||
|
|
||||||
|
(defn * [&rest args]
|
||||||
|
"Shadow * operator for when we need to import / map it against something"
|
||||||
|
(if (= (len args) 0)
|
||||||
|
1 ; identity
|
||||||
|
(reduce operator.mul args)))
|
||||||
|
|
||||||
|
|
||||||
|
(defn / [&rest args]
|
||||||
|
"Shadow / operator for when we need to import / map it against something"
|
||||||
|
(let [[count (len args)]]
|
||||||
|
(if (= count 0)
|
||||||
|
(raise (TypeError "Need at least 1 argument to divide"))
|
||||||
|
(if (= count 1)
|
||||||
|
(operator.truediv 1 (get args 0))
|
||||||
|
(reduce operator.truediv args)))))
|
||||||
|
|
||||||
|
|
||||||
|
(setv *exports* ['+ '- '* '/])
|
@ -30,7 +30,6 @@ from hy.models.expression import HyExpression
|
|||||||
from hy.models.float import HyFloat
|
from hy.models.float import HyFloat
|
||||||
from hy.models.integer import HyInteger
|
from hy.models.integer import HyInteger
|
||||||
from hy.models.keyword import HyKeyword
|
from hy.models.keyword import HyKeyword
|
||||||
from hy.models.lambdalist import HyLambdaListKeyword
|
|
||||||
from hy.models.list import HyList
|
from hy.models.list import HyList
|
||||||
from hy.models.string import HyString
|
from hy.models.string import HyString
|
||||||
from hy.models.symbol import HySymbol
|
from hy.models.symbol import HySymbol
|
||||||
@ -271,9 +270,6 @@ def t_identifier(p):
|
|||||||
if obj.startswith(":"):
|
if obj.startswith(":"):
|
||||||
return HyKeyword(obj)
|
return HyKeyword(obj)
|
||||||
|
|
||||||
if obj.startswith("&"):
|
|
||||||
return HyLambdaListKeyword(obj)
|
|
||||||
|
|
||||||
def mangle(p):
|
def mangle(p):
|
||||||
if p.startswith("*") and p.endswith("*") and p not in ("*", "**"):
|
if p.startswith("*") and p.endswith("*") and p not in ("*", "**"):
|
||||||
p = p[1:-1].upper()
|
p = p[1:-1].upper()
|
||||||
|
@ -1,39 +0,0 @@
|
|||||||
# Copyright (c) 2013 James King <james@agentultra.com>
|
|
||||||
#
|
|
||||||
# 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 hy.models.string import HyString
|
|
||||||
|
|
||||||
|
|
||||||
class HyLambdaListKeyword(HyString):
|
|
||||||
"""
|
|
||||||
Hy LambdaListKeyword. Demarcates arguments in an argument list.
|
|
||||||
|
|
||||||
(defun my-fun (x &rest xs &optional (foo "default string")))
|
|
||||||
|
|
||||||
becomes:
|
|
||||||
|
|
||||||
def my_fun(x, *xs, foo="default string"):
|
|
||||||
pass
|
|
||||||
"""
|
|
||||||
|
|
||||||
_valid_types = ["&rest", "&optional", "&key", "&kwargs"]
|
|
||||||
|
|
||||||
def __init__(self, string):
|
|
||||||
self += string
|
|
@ -21,7 +21,6 @@
|
|||||||
|
|
||||||
from hy.models.expression import HyExpression
|
from hy.models.expression import HyExpression
|
||||||
from hy.models.integer import HyInteger
|
from hy.models.integer import HyInteger
|
||||||
from hy.models.lambdalist import HyLambdaListKeyword
|
|
||||||
from hy.models.float import HyFloat
|
from hy.models.float import HyFloat
|
||||||
from hy.models.complex import HyComplex
|
from hy.models.complex import HyComplex
|
||||||
from hy.models.symbol import HySymbol
|
from hy.models.symbol import HySymbol
|
||||||
@ -85,14 +84,6 @@ def test_lex_expression_integer():
|
|||||||
assert objs == [HyExpression([HySymbol("foo"), HyInteger(2)])]
|
assert objs == [HyExpression([HySymbol("foo"), HyInteger(2)])]
|
||||||
|
|
||||||
|
|
||||||
def test_lex_lambda_list_keyword():
|
|
||||||
""" Make sure expressions can produce lambda list keywords """
|
|
||||||
objs = tokenize("(x &rest xs)")
|
|
||||||
assert objs == [HyExpression([HySymbol("x"),
|
|
||||||
HyLambdaListKeyword("&rest"),
|
|
||||||
HySymbol("xs")])]
|
|
||||||
|
|
||||||
|
|
||||||
def test_lex_symbols():
|
def test_lex_symbols():
|
||||||
""" Make sure that symbols are valid expressions"""
|
""" Make sure that symbols are valid expressions"""
|
||||||
objs = tokenize("foo ")
|
objs = tokenize("foo ")
|
||||||
|
@ -87,12 +87,14 @@
|
|||||||
(defn test-ap-first []
|
(defn test-ap-first []
|
||||||
"NATIVE: testing anaphoric first"
|
"NATIVE: testing anaphoric first"
|
||||||
(assert-equal (ap-first (> it 5) (range 10)) 6)
|
(assert-equal (ap-first (> it 5) (range 10)) 6)
|
||||||
(assert-equal (ap-first (even? it) [1 2 3 4]) 2))
|
(assert-equal (ap-first (even? it) [1 2 3 4]) 2)
|
||||||
|
(assert-equal (ap-first (> it 10) (range 10)) None))
|
||||||
|
|
||||||
(defn test-ap-last []
|
(defn test-ap-last []
|
||||||
"NATIVE: testing anaphoric last"
|
"NATIVE: testing anaphoric last"
|
||||||
(assert-equal (ap-last (> it 5) (range 10)) 9)
|
(assert-equal (ap-last (> it 5) (range 10)) 9)
|
||||||
(assert-equal (ap-last (even? it) [1 2 3 4]) 4))
|
(assert-equal (ap-last (even? it) [1 2 3 4]) 4)
|
||||||
|
(assert-equal (ap-last (> it 10) (range 10)) None))
|
||||||
|
|
||||||
(defn test-ap-reduce []
|
(defn test-ap-reduce []
|
||||||
"NATIVE: testing anaphoric reduce"
|
"NATIVE: testing anaphoric reduce"
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
[sys :as systest])
|
[sys :as systest])
|
||||||
(import sys)
|
(import sys)
|
||||||
|
|
||||||
|
(import [hy._compat [PY33 PY34]])
|
||||||
|
|
||||||
(defn test-sys-argv []
|
(defn test-sys-argv []
|
||||||
"NATIVE: test sys.argv"
|
"NATIVE: test sys.argv"
|
||||||
@ -448,6 +449,29 @@
|
|||||||
(for [y (gen)] (setv ret (+ ret y)))
|
(for [y (gen)] (setv ret (+ ret y)))
|
||||||
(assert (= ret 10)))
|
(assert (= ret 10)))
|
||||||
|
|
||||||
|
(defn test-yield-with-return []
|
||||||
|
"NATIVE: test yield with return"
|
||||||
|
(defn gen [] (yield 3) "goodbye")
|
||||||
|
(if PY33
|
||||||
|
(do (setv gg (gen))
|
||||||
|
(assert (= 3 (next gg)))
|
||||||
|
(try (next gg)
|
||||||
|
(except [e StopIteration] (assert (hasattr e "value"))
|
||||||
|
(assert (= (getattr e "value") "goodbye")))))
|
||||||
|
(do (setv gg (gen))
|
||||||
|
(assert (= 3 (next gg)))
|
||||||
|
(try (next gg)
|
||||||
|
(except [e StopIteration] (assert (not (hasattr e "value"))))))))
|
||||||
|
|
||||||
|
|
||||||
|
(defn test-yield-in-try []
|
||||||
|
"NATIVE: test yield in try"
|
||||||
|
(defn gen []
|
||||||
|
(let [[x 1]]
|
||||||
|
(try (yield x)
|
||||||
|
(finally (print x)))))
|
||||||
|
(setv output (list (gen)))
|
||||||
|
(assert (= [1] output)))
|
||||||
|
|
||||||
(defn test-first []
|
(defn test-first []
|
||||||
"NATIVE: test firsty things"
|
"NATIVE: test firsty things"
|
||||||
@ -975,3 +999,10 @@
|
|||||||
"NATIVE: test keyword quoting magic"
|
"NATIVE: test keyword quoting magic"
|
||||||
(assert (= :foo "\ufdd0:foo"))
|
(assert (= :foo "\ufdd0:foo"))
|
||||||
(assert (= `:foo "\ufdd0:foo")))
|
(assert (= `:foo "\ufdd0:foo")))
|
||||||
|
|
||||||
|
(defn test-only-parse-lambda-list-in-defn []
|
||||||
|
"NATIVE: test lambda lists are only parsed in defn"
|
||||||
|
(try
|
||||||
|
(foo [&rest spam] 1)
|
||||||
|
(catch [NameError] True)
|
||||||
|
(else (raise AssertionError))))
|
||||||
|
@ -77,12 +77,6 @@
|
|||||||
(assert (= q qq)))
|
(assert (= q qq)))
|
||||||
|
|
||||||
|
|
||||||
(defn test-quote-lambdalistkeyword []
|
|
||||||
"NATIVE: test quoting lambda list keywords"
|
|
||||||
(setv opt (quote &optional))
|
|
||||||
(assert (isinstance opt hy.HyLambdaListKeyword))
|
|
||||||
(assert (= (str opt) "&optional")))
|
|
||||||
|
|
||||||
(defmacro doodle [&rest body]
|
(defmacro doodle [&rest body]
|
||||||
`(do ~@body))
|
`(do ~@body))
|
||||||
|
|
||||||
|
41
tests/native_tests/shadow.hy
Normal file
41
tests/native_tests/shadow.hy
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
|
||||||
|
|
||||||
|
(defn test-shadow-addition []
|
||||||
|
"NATIVE: test shadow addition"
|
||||||
|
(let [[x +]]
|
||||||
|
(assert (= (x) 0))
|
||||||
|
(assert (= (x 1 2 3 4) 10))
|
||||||
|
(assert (= (x 1 2 3 4 5) 15))))
|
||||||
|
|
||||||
|
|
||||||
|
(defn test-shadow-subtraction []
|
||||||
|
"NATIVE: test shadow subtraction"
|
||||||
|
(let [[x -]]
|
||||||
|
(assert (try
|
||||||
|
(x)
|
||||||
|
(catch [TypeError] True)
|
||||||
|
(else (throw AssertionError))))
|
||||||
|
(assert (= (x 1) -1))
|
||||||
|
(assert (= (x 2 1) 1))
|
||||||
|
(assert (= (x 2 1 1) 0))))
|
||||||
|
|
||||||
|
|
||||||
|
(defn test-shadow-multiplication []
|
||||||
|
"NATIVE: test shadow multiplication"
|
||||||
|
(let [[x *]]
|
||||||
|
(assert (= (x) 1))
|
||||||
|
(assert (= (x 3) 3))
|
||||||
|
(assert (= (x 3 3) 9))))
|
||||||
|
|
||||||
|
|
||||||
|
(defn test-shadow-division []
|
||||||
|
"NATIVE: test shadow division"
|
||||||
|
(let [[x /]]
|
||||||
|
(assert (try
|
||||||
|
(x)
|
||||||
|
(catch [TypeError] True)
|
||||||
|
(else (throw AssertionError))))
|
||||||
|
(assert (= (x 1) 1))
|
||||||
|
(assert (= (x 8 2) 4))
|
||||||
|
(assert (= (x 8 2 2) 2))
|
||||||
|
(assert (= (x 8 2 2 2) 1))))
|
Loading…
x
Reference in New Issue
Block a user