Merge branch 'master' into pr/237
This commit is contained in:
commit
967bb95534
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,6 +1,7 @@
|
||||
*.pyc
|
||||
*swp
|
||||
*hy*egg*
|
||||
*pyreadline*egg*
|
||||
.tox
|
||||
*pycache*
|
||||
dist
|
||||
|
@ -8,7 +8,7 @@ python:
|
||||
# command to install dependencies
|
||||
install:
|
||||
- pip install -r requirements.txt --use-mirrors
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == '2.6' ]]; then pip install importlib unittest2 astor --use-mirrors; fi
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == '2.6' ]]; then pip install argparse importlib unittest2 astor --use-mirrors; fi
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then pip install astor --use-mirrors; fi
|
||||
- if [[ $TRAVIS_PYTHON_VERSION == 'pypy' ]]; then pip install astor --use-mirrors; fi
|
||||
- python setup.py -q install
|
||||
|
1
AUTHORS
1
AUTHORS
@ -14,4 +14,5 @@
|
||||
* Thomas Ballinger <thomasballinger@gmail.com>
|
||||
* Morten Linderud <mcfoxax@gmail.com>
|
||||
* Guillermo Vayá <guivaya@gmail.com>
|
||||
* Bob Tolbert <bob@tolbert.org>
|
||||
* Ralph Möritz <ralph.moeritz@outlook.com>
|
||||
|
8
bin/hy
8
bin/hy
@ -1,8 +0,0 @@
|
||||
#!/usr/bin/env python
|
||||
|
||||
import sys
|
||||
from hy.cmdline import cmdline_handler
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
sys.exit(cmdline_handler("hy", sys.argv))
|
6
bin/hyc
6
bin/hyc
@ -1,6 +0,0 @@
|
||||
#!/usr/bin/env hy
|
||||
|
||||
(import sys)
|
||||
(import [hy.importer [write-hy-as-pyc]])
|
||||
|
||||
(write-hy-as-pyc (get sys.argv 1))
|
@ -177,7 +177,7 @@ Some example usage:
|
||||
`do` can accept any number of arguments, from 1 to n.
|
||||
|
||||
|
||||
def / setf / setv
|
||||
def / setv
|
||||
-----------------
|
||||
|
||||
`def` and `setv` are used to bind value, object or a function to a symbol. For
|
||||
|
@ -6,6 +6,6 @@
|
||||
|
||||
|
||||
(with-as (ThreadPoolExecutor 10) executor
|
||||
(setf jobs (list-comp (.submit executor task-to-do) (x (range 0 10))))
|
||||
(setv jobs (list-comp (.submit executor task-to-do) (x (range 0 10))))
|
||||
(for (future (as-completed jobs))
|
||||
(.result future)))
|
||||
|
@ -24,7 +24,7 @@
|
||||
# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||
# DEALINGS IN THE SOFTWARE.
|
||||
|
||||
import optparse
|
||||
import argparse
|
||||
import code
|
||||
import ast
|
||||
import sys
|
||||
@ -198,26 +198,40 @@ def run_icommand(source):
|
||||
return run_repl(hr)
|
||||
|
||||
|
||||
USAGE = "usage: %prog [-h | -i cmd | -c cmd | file | -]"
|
||||
VERSION = "%prog " + hy.__version__
|
||||
USAGE = "%(prog)s [-h | -i cmd | -c cmd | file | -] [arg] ..."
|
||||
VERSION = "%(prog)s " + hy.__version__
|
||||
EPILOG = """ file program read from script
|
||||
- program read from stdin
|
||||
[arg] ... arguments passed to program in sys.argv[1:]
|
||||
"""
|
||||
|
||||
|
||||
def cmdline_handler(scriptname, argv):
|
||||
parser = optparse.OptionParser(usage=USAGE, version=VERSION)
|
||||
parser.add_option(
|
||||
"-c", dest="command", metavar="COMMAND",
|
||||
help="program passed in as string")
|
||||
parser.add_option(
|
||||
"-i", dest="icommand", metavar="ICOMMAND",
|
||||
help="program passed in as string, then stay in repl")
|
||||
parser = argparse.ArgumentParser(
|
||||
prog="hy",
|
||||
usage=USAGE,
|
||||
formatter_class=argparse.RawDescriptionHelpFormatter,
|
||||
epilog=EPILOG)
|
||||
parser.add_argument("-c", dest="command",
|
||||
help="program passed in as a string")
|
||||
parser.add_argument(
|
||||
"-i", dest="icommand",
|
||||
help="program passed in as a string, then stay in REPL")
|
||||
|
||||
# Hylarious way of adding non-option options to help text
|
||||
parser.format_epilog = lambda self: EPILOG
|
||||
parser.add_argument("-v", action="version", version=VERSION)
|
||||
|
||||
(options, args) = parser.parse_args()
|
||||
# this will contain the script/program name and any arguments for it.
|
||||
parser.add_argument('args', nargs=argparse.REMAINDER,
|
||||
help=argparse.SUPPRESS)
|
||||
|
||||
# stash the hy exectuable in case we need it later
|
||||
# mimics Python sys.executable
|
||||
hy.executable = argv[0]
|
||||
|
||||
options = parser.parse_args(argv[1:])
|
||||
|
||||
# reset sys.argv like Python
|
||||
sys.argv = options.args
|
||||
|
||||
if options.command:
|
||||
# User did "hy -c ..."
|
||||
@ -227,14 +241,25 @@ def cmdline_handler(scriptname, argv):
|
||||
# User did "hy -i ..."
|
||||
return run_icommand(options.icommand)
|
||||
|
||||
if args:
|
||||
if args[0] == "-":
|
||||
if options.args:
|
||||
if options.args[0] == "-":
|
||||
# Read the program from stdin
|
||||
return run_command(sys.stdin.read())
|
||||
|
||||
else:
|
||||
# User did "hy <filename>"
|
||||
return run_file(args[0])
|
||||
return run_file(options.args[0])
|
||||
|
||||
# User did NOTHING!
|
||||
return run_repl()
|
||||
|
||||
|
||||
# entry point for cmd line script "hy"
|
||||
def hy_main():
|
||||
sys.exit(cmdline_handler("hy", sys.argv))
|
||||
|
||||
|
||||
# entry point for cmd line script "hyc"
|
||||
def hyc_main():
|
||||
from hy.importer import write_hy_as_pyc
|
||||
write_hy_as_pyc(sys.argv[1])
|
||||
|
@ -1481,7 +1481,6 @@ class HyASTCompiler(object):
|
||||
return func + ret
|
||||
|
||||
@builds("def")
|
||||
@builds("setf")
|
||||
@builds("setv")
|
||||
@checkargs(2)
|
||||
def compile_def_expression(self, expression):
|
||||
|
@ -128,10 +128,10 @@ def let_macro(variables, *body):
|
||||
|
||||
for var in variables:
|
||||
if isinstance(var, list):
|
||||
expr.append(HyExpression([HySymbol("setf"),
|
||||
expr.append(HyExpression([HySymbol("setv"),
|
||||
var[0], var[1]]))
|
||||
else:
|
||||
expr.append(HyExpression([HySymbol("setf"),
|
||||
expr.append(HyExpression([HySymbol("setv"),
|
||||
var, HySymbol("None")]))
|
||||
|
||||
return HyExpression([expr + list(body)])
|
||||
|
116
make.bat
Normal file
116
make.bat
Normal file
@ -0,0 +1,116 @@
|
||||
@ECHO OFF
|
||||
|
||||
REM Make batch file for Hy development
|
||||
|
||||
if "%1" == "" goto help
|
||||
|
||||
if "%1" == "help" (
|
||||
:help
|
||||
echo. No default step. Use setup.py
|
||||
echo.
|
||||
echo. Other targets:
|
||||
echo.
|
||||
echo. - docs
|
||||
echo. - full
|
||||
echo.
|
||||
echo. - dev "test & flake"
|
||||
echo. - flake
|
||||
echo. - test
|
||||
echo. - diff
|
||||
echo. - tox
|
||||
echo. - d
|
||||
echo. - r
|
||||
echo.
|
||||
goto end
|
||||
)
|
||||
|
||||
if "%1" == "docs" (
|
||||
:docs
|
||||
echo.docs not yet supported under Windows
|
||||
goto :EOF
|
||||
)
|
||||
|
||||
if "%1" == "upload" (
|
||||
:upload
|
||||
python setup.py sdist upload
|
||||
goto :EOF
|
||||
)
|
||||
|
||||
if "%1" == "clear" (
|
||||
:clear
|
||||
cls
|
||||
goto :EOF
|
||||
)
|
||||
|
||||
if "%1" == "d" (
|
||||
:d
|
||||
call :clear
|
||||
call :dev
|
||||
goto :EOF
|
||||
)
|
||||
|
||||
if "%1" == "test" (
|
||||
:test
|
||||
call :venv
|
||||
nosetests -sv
|
||||
goto :EOF
|
||||
)
|
||||
|
||||
if "%1" == "venv" (
|
||||
:venv
|
||||
echo.%VIRTUAL_ENV% | findstr /C:"hy" 1>nul
|
||||
if errorlevel 1 (
|
||||
echo.You're not in a Hy virtualenv. FOR SHAME
|
||||
) ELSE (
|
||||
echo.We're properly in a virtualenv. Going ahead.
|
||||
)
|
||||
goto :EOF
|
||||
)
|
||||
|
||||
if "%1" == "flake" (
|
||||
:flake
|
||||
echo.flake8 hy
|
||||
flake8 hy
|
||||
goto :EOF
|
||||
)
|
||||
|
||||
if "%1" == "dev" (
|
||||
:dev
|
||||
call :test
|
||||
call :flake
|
||||
goto :EOF
|
||||
)
|
||||
|
||||
if "%1" == "tox" (
|
||||
:tox
|
||||
call :venv
|
||||
tox -e "py26,py27,py32,py33,flake8"
|
||||
goto :EOF
|
||||
)
|
||||
|
||||
if "%1" == "d" (
|
||||
:d
|
||||
call :clear
|
||||
call :dev
|
||||
goto :EOF
|
||||
)
|
||||
|
||||
if "%i" == "diff" (
|
||||
:diff
|
||||
git diff --color
|
||||
goto :EOF
|
||||
)
|
||||
|
||||
if "%1" == "r" (
|
||||
:r
|
||||
call :d
|
||||
call :tox
|
||||
call :diff
|
||||
goto :EOF
|
||||
)
|
||||
|
||||
if "%1" == full (
|
||||
call :docs
|
||||
call :d
|
||||
call :tox
|
||||
)
|
15
setup.py
15
setup.py
@ -1,5 +1,5 @@
|
||||
#!/usr/bin/env python
|
||||
# Copyright (c) 2012 Paul Tagliamonte <paultag@debian.org>
|
||||
# Copyright (c) 2012, 2013 Paul Tagliamonte <paultag@debian.org>
|
||||
#
|
||||
# Permission is hereby granted, free of charge, to any person obtaining a
|
||||
# copy of this software and associated documentation files (the "Software"),
|
||||
@ -23,12 +23,15 @@
|
||||
from hy import __appname__, __version__
|
||||
from setuptools import setup
|
||||
import os
|
||||
import sys
|
||||
|
||||
long_description = """Hy is a Python <--> Lisp layer. It helps
|
||||
make things work nicer, and lets Python and the Hy lisp variant play
|
||||
nice together. """
|
||||
|
||||
install_requires = []
|
||||
if sys.version_info[0] == 2:
|
||||
install_requires.append('argparse>=1.2.1')
|
||||
if os.name == 'nt':
|
||||
install_requires.append('pyreadline==2.0')
|
||||
|
||||
@ -36,10 +39,12 @@ setup(
|
||||
name=__appname__,
|
||||
version=__version__,
|
||||
install_requires=install_requires,
|
||||
scripts=[
|
||||
"bin/hy",
|
||||
"bin/hyc",
|
||||
],
|
||||
entry_points={
|
||||
'console_scripts': [
|
||||
'hy = hy.cmdline:hy_main',
|
||||
'hyc = hy.cmdline:hyc_main'
|
||||
]
|
||||
},
|
||||
packages=[
|
||||
'hy',
|
||||
'hy.lex',
|
||||
|
@ -408,11 +408,11 @@
|
||||
|
||||
(defn test-for-doodle []
|
||||
"NATIVE: test for-do"
|
||||
(do (do (do (do (do (do (do (do (do (setf (, x y) (, 0 0)))))))))))
|
||||
(do (do (do (do (do (do (do (do (do (setv (, x y) (, 0 0)))))))))))
|
||||
(foreach [- [1 2]]
|
||||
(do
|
||||
(setf x (+ x 1))
|
||||
(setf y (+ y 1))))
|
||||
(setv x (+ x 1))
|
||||
(setv y (+ y 1))))
|
||||
(assert (= y x 2)))
|
||||
|
||||
|
||||
@ -597,10 +597,10 @@
|
||||
(defn test-eval []
|
||||
"NATIVE: test eval"
|
||||
(assert (= 2 (eval (quote (+ 1 1)))))
|
||||
(setf x 2)
|
||||
(setv x 2)
|
||||
(assert (= 4 (eval (quote (+ x 2)))))
|
||||
(setf test-payload (quote (+ x 2)))
|
||||
(setf x 4)
|
||||
(setv test-payload (quote (+ x 2)))
|
||||
(setv x 4)
|
||||
(assert (= 6 (eval test-payload)))
|
||||
(assert (= 9 ((eval (quote (fn [x] (+ 3 3 x)))) 3)))
|
||||
(assert (= 1 (eval (quote 1))))
|
||||
@ -689,9 +689,9 @@
|
||||
(defn test-try-except-return []
|
||||
"NATIVE: test we can return from in a try except"
|
||||
(assert (= ((fn [] (try xxx (except [NameError] (+ 1 1))))) 2))
|
||||
(setf foo (try xxx (except [NameError] (+ 1 1))))
|
||||
(setv foo (try xxx (except [NameError] (+ 1 1))))
|
||||
(assert (= foo 2))
|
||||
(setf foo (try (+ 2 2) (except [NameError] (+ 1 1))))
|
||||
(setv foo (try (+ 2 2) (except [NameError] (+ 1 1))))
|
||||
(assert (= foo 4)))
|
||||
|
||||
|
||||
|
@ -3,22 +3,22 @@
|
||||
|
||||
(defn test-quote []
|
||||
"NATIVE: test for quoting functionality"
|
||||
(setf q (quote (a b c)))
|
||||
(setv q (quote (a b c)))
|
||||
(assert (= (len q) 3))
|
||||
(assert (= q [(quote a) (quote b) (quote c)])))
|
||||
|
||||
|
||||
(defn test-quoted-hoistable []
|
||||
"NATIVE: check whether quote works on hoisted things"
|
||||
(setf f (quote (if true true true)))
|
||||
(setv f (quote (if true true true)))
|
||||
(assert (= (car f) (quote if)))
|
||||
(assert (= (cdr f) (quote (true true true)))))
|
||||
|
||||
|
||||
(defn test-quoted-macroexpand []
|
||||
"NATIVE: check that we don't expand macros in quoted expressions"
|
||||
(setf q1 (quote (-> a b c)))
|
||||
(setf q2 (quasiquote (-> a b c)))
|
||||
(setv q1 (quote (-> a b c)))
|
||||
(setv q2 (quasiquote (-> a b c)))
|
||||
(assert (= q1 q2))
|
||||
(assert (= (car q1) (quote ->)))
|
||||
(assert (= (cdr q1) (quote (a b c)))))
|
||||
@ -26,7 +26,7 @@
|
||||
|
||||
(defn test-quote-dicts []
|
||||
"NATIVE: test quoting dicts"
|
||||
(setf q (quote {foo bar baz quux}))
|
||||
(setv q (quote {foo bar baz quux}))
|
||||
(assert (= (len q) 4))
|
||||
(assert (= (get q 0) (quote foo)))
|
||||
(assert (= (get q 1) (quote bar)))
|
||||
@ -37,41 +37,41 @@
|
||||
|
||||
(defn test-quote-expr-in-dict []
|
||||
"NATIVE: test quoting nested exprs in dict"
|
||||
(setf q (quote {(foo bar) 0}))
|
||||
(setv q (quote {(foo bar) 0}))
|
||||
(assert (= (len q) 2))
|
||||
(setf qq (get q 0))
|
||||
(setv qq (get q 0))
|
||||
(assert (= qq (quote (foo bar)))))
|
||||
|
||||
|
||||
(defn test-quasiquote []
|
||||
"NATIVE: test that quasiquote and quote are equivalent for simple cases"
|
||||
(setf q (quote (a b c)))
|
||||
(setf qq (quasiquote (a b c)))
|
||||
(setv q (quote (a b c)))
|
||||
(setv qq (quasiquote (a b c)))
|
||||
(assert (= q qq)))
|
||||
|
||||
|
||||
(defn test-unquote []
|
||||
"NATIVE: test that unquote works as expected"
|
||||
(setf q (quote (unquote foo)))
|
||||
(setv q (quote (unquote foo)))
|
||||
(assert (= (len q) 2))
|
||||
(assert (= (get q 1) (quote foo)))
|
||||
(setf qq (quasiquote (a b c (unquote (+ 1 2)))))
|
||||
(setv qq (quasiquote (a b c (unquote (+ 1 2)))))
|
||||
(assert (= (len qq) 4))
|
||||
(assert (= qq (quote (a b c 3)))))
|
||||
|
||||
|
||||
(defn test-unquote-splice []
|
||||
"NATIVE: test splicing unquotes"
|
||||
(setf q (quote (c d e)))
|
||||
(setf qq (quasiquote (a b (unquote-splice q) f (unquote-splice q))))
|
||||
(setv q (quote (c d e)))
|
||||
(setv qq (quasiquote (a b (unquote-splice q) f (unquote-splice q))))
|
||||
(assert (= (len qq) 9))
|
||||
(assert (= qq (quote (a b c d e f c d e)))))
|
||||
|
||||
|
||||
(defn test-nested-quasiquote []
|
||||
"NATIVE: test nested quasiquotes"
|
||||
(setf qq (quasiquote (1 (quasiquote (unquote (+ 1 (unquote (+ 2 3))))) 4)))
|
||||
(setf q (quote (1 (quasiquote (unquote (+ 1 5))) 4)))
|
||||
(setv qq (quasiquote (1 (quasiquote (unquote (+ 1 (unquote (+ 2 3))))) 4)))
|
||||
(setv q (quote (1 (quasiquote (unquote (+ 1 5))) 4)))
|
||||
(assert (= (len q) 3))
|
||||
(assert (= (get qq 1) (quote (quasiquote (unquote (+ 1 5))))))
|
||||
(assert (= q qq)))
|
||||
|
18
tests/resources/argparse_ex.hy
Executable file
18
tests/resources/argparse_ex.hy
Executable file
@ -0,0 +1,18 @@
|
||||
#!/usr/bin/env hy
|
||||
|
||||
(import sys)
|
||||
(import argparse)
|
||||
|
||||
(setv parser (argparse.ArgumentParser))
|
||||
|
||||
(.add_argument parser "-i")
|
||||
(.add_argument parser "-c")
|
||||
|
||||
(setv args (.parse_args parser))
|
||||
|
||||
;; using (cond) allows -i to take precedence over -c
|
||||
|
||||
(cond (args.i
|
||||
(print (str args.i)))
|
||||
(args.c
|
||||
(print (str "got c"))))
|
@ -25,13 +25,18 @@ import subprocess
|
||||
import sys
|
||||
|
||||
|
||||
def run_cmd(cmd):
|
||||
def run_cmd(cmd, stdin_data=None):
|
||||
p = subprocess.Popen(cmd,
|
||||
stdin=subprocess.PIPE,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
shell=True)
|
||||
stdout = ""
|
||||
stderr = ""
|
||||
if stdin_data is not None:
|
||||
p.stdin.write(stdin_data.encode('ASCII'))
|
||||
p.stdin.flush()
|
||||
p.stdin.close()
|
||||
# Read stdout and stderr otherwise if the PIPE buffer is full, we might
|
||||
# wait for ever…
|
||||
while p.poll() is None:
|
||||
@ -41,28 +46,28 @@ def run_cmd(cmd):
|
||||
|
||||
|
||||
def test_bin_hy():
|
||||
ret = run_cmd("echo | bin/hy")
|
||||
ret = run_cmd("hy", "")
|
||||
assert ret[0] == 0
|
||||
|
||||
|
||||
def test_bin_hy_stdin():
|
||||
ret = run_cmd("echo \"(koan)\" | bin/hy")
|
||||
ret = run_cmd("hy", '(koan)')
|
||||
assert ret[0] == 0
|
||||
assert "monk" in ret[1]
|
||||
|
||||
|
||||
def test_bin_hy_cmd():
|
||||
ret = run_cmd("bin/hy -c \"(koan)\"")
|
||||
ret = run_cmd("hy -c \"(koan)\"")
|
||||
assert ret[0] == 0
|
||||
assert "monk" in ret[1]
|
||||
|
||||
ret = run_cmd("bin/hy -c \"(koan\"")
|
||||
ret = run_cmd("hy -c \"(koan\"")
|
||||
assert ret[0] == 1
|
||||
assert "LexException" in ret[1]
|
||||
|
||||
|
||||
def test_bin_hy_icmd():
|
||||
ret = run_cmd("echo \"(ideas)\" | bin/hy -i \"(koan)\"")
|
||||
ret = run_cmd("hy -i \"(koan)\"", "(ideas)")
|
||||
assert ret[0] == 0
|
||||
output = ret[1]
|
||||
|
||||
@ -71,16 +76,41 @@ def test_bin_hy_icmd():
|
||||
|
||||
|
||||
def test_bin_hy_file():
|
||||
ret = run_cmd("bin/hy eg/nonfree/halting-problem/halting.hy")
|
||||
ret = run_cmd("hy eg/nonfree/halting-problem/halting.hy")
|
||||
assert ret[0] == 0
|
||||
assert "27" in ret[1]
|
||||
|
||||
|
||||
def test_bin_hy_missing_file():
|
||||
ret = run_cmd("hy foobarbaz")
|
||||
assert ret[0] == 1
|
||||
assert "No such file" in ret[2]
|
||||
|
||||
|
||||
def test_bin_hy_file_with_args():
|
||||
ret = run_cmd("hy tests/resources/argparse_ex.hy -h")
|
||||
assert ret[0] == 0
|
||||
assert "usage" in ret[1]
|
||||
ret = run_cmd("hy tests/resources/argparse_ex.hy -c bar")
|
||||
assert ret[0] == 0
|
||||
assert "got c" in ret[1]
|
||||
ret = run_cmd("hy tests/resources/argparse_ex.hy -i foo")
|
||||
assert ret[0] == 0
|
||||
assert "foo" in ret[1]
|
||||
ret = run_cmd("hy tests/resources/argparse_ex.hy -i foo -c bar")
|
||||
assert ret[0] == 0
|
||||
assert "foo" in ret[1]
|
||||
|
||||
|
||||
def test_hy2py():
|
||||
# XXX Astor doesn't seem to support Python3 :(
|
||||
if sys.version_info[0] == 3:
|
||||
return
|
||||
|
||||
# and running this script this way doesn't work on Windows
|
||||
if os.name == "nt":
|
||||
return
|
||||
|
||||
i = 0
|
||||
for dirpath, dirnames, filenames in os.walk("tests/native_tests"):
|
||||
for f in filenames:
|
||||
|
Loading…
Reference in New Issue
Block a user