Add in a new core language file.
This will let us implement common functions seen in other lisps, and allow them to be importable, without explicit imports. The goal is to keep this as small as we can; we don't want too much magic. I've added `take' and `drop' as examples of what we can do.
This commit is contained in:
parent
b65c2a4596
commit
86af7eacf1
@ -8,7 +8,7 @@ python:
|
|||||||
# command to install dependencies
|
# command to install dependencies
|
||||||
install:
|
install:
|
||||||
- pip install -r requirements.txt --use-mirrors
|
- pip install -r requirements.txt --use-mirrors
|
||||||
- if [[ $TRAVIS_PYTHON_VERSION == '2.6' ]]; then pip install unittest2 astor --use-mirrors; fi
|
- if [[ $TRAVIS_PYTHON_VERSION == '2.6' ]]; then pip install importlib unittest2 astor --use-mirrors; fi
|
||||||
- if [[ $TRAVIS_PYTHON_VERSION == '2.7' ]]; then pip install 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
|
- if [[ $TRAVIS_PYTHON_VERSION == 'pypy' ]]; then pip install astor --use-mirrors; fi
|
||||||
- python setup.py -q install
|
- python setup.py -q install
|
||||||
|
@ -36,14 +36,14 @@ from hy.models.list import HyList
|
|||||||
from hy.models.dict import HyDict
|
from hy.models.dict import HyDict
|
||||||
|
|
||||||
import hy.importer
|
import hy.importer
|
||||||
from hy.core import process
|
|
||||||
|
|
||||||
from hy.util import str_type
|
|
||||||
|
|
||||||
from hy.macros import require
|
from hy.macros import require
|
||||||
|
from hy.util import str_type
|
||||||
|
from hy.core import process
|
||||||
|
|
||||||
import codecs
|
|
||||||
import traceback
|
import traceback
|
||||||
|
import importlib
|
||||||
|
import codecs
|
||||||
import ast
|
import ast
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
@ -61,6 +61,17 @@ def compile_time_ns(module_name):
|
|||||||
return ns
|
return ns
|
||||||
|
|
||||||
|
|
||||||
|
_stdlib = {}
|
||||||
|
|
||||||
|
|
||||||
|
def load_stdlib():
|
||||||
|
import hy.core
|
||||||
|
for module in hy.core.STDLIB:
|
||||||
|
mod = importlib.import_module(module)
|
||||||
|
for e in mod.EXPORTS:
|
||||||
|
_stdlib[e] = module
|
||||||
|
|
||||||
|
|
||||||
class HyCompileError(HyError):
|
class HyCompileError(HyError):
|
||||||
def __init__(self, exception, traceback=None):
|
def __init__(self, exception, traceback=None):
|
||||||
self.exception = exception
|
self.exception = exception
|
||||||
@ -339,6 +350,9 @@ class HyASTCompiler(object):
|
|||||||
self.anon_var_count = 0
|
self.anon_var_count = 0
|
||||||
self.imports = defaultdict(set)
|
self.imports = defaultdict(set)
|
||||||
self.module_name = module_name
|
self.module_name = module_name
|
||||||
|
if not module_name.startswith("hy.core"):
|
||||||
|
# everything in core needs to be explicit.
|
||||||
|
load_stdlib()
|
||||||
|
|
||||||
def get_anon_var(self):
|
def get_anon_var(self):
|
||||||
self.anon_var_count += 1
|
self.anon_var_count += 1
|
||||||
@ -1432,6 +1446,10 @@ class HyASTCompiler(object):
|
|||||||
ret = self.compile_atom(fn, expression)
|
ret = self.compile_atom(fn, expression)
|
||||||
if ret:
|
if ret:
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
if fn in _stdlib:
|
||||||
|
self.imports[_stdlib[fn]].add(fn)
|
||||||
|
|
||||||
if fn.startswith("."):
|
if fn.startswith("."):
|
||||||
# (.split "test test") -> "test test".split()
|
# (.split "test test") -> "test test".split()
|
||||||
|
|
||||||
|
@ -24,6 +24,10 @@ MACROS = [
|
|||||||
"hy.core.bootstrap",
|
"hy.core.bootstrap",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
STDLIB = [
|
||||||
|
"hy.core.language"
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
def process(tree, module_name):
|
def process(tree, module_name):
|
||||||
load_macros()
|
load_macros()
|
||||||
|
@ -137,21 +137,6 @@ def let_macro(variables, *body):
|
|||||||
return HyExpression([expr + list(body)])
|
return HyExpression([expr + list(body)])
|
||||||
|
|
||||||
|
|
||||||
@macro("take")
|
|
||||||
def take_macro(n, lst):
|
|
||||||
return HyExpression([HySymbol('slice'),
|
|
||||||
lst,
|
|
||||||
HyInteger(0),
|
|
||||||
HyInteger(n)])
|
|
||||||
|
|
||||||
|
|
||||||
@macro("drop")
|
|
||||||
def drop_macro(n, lst):
|
|
||||||
return HyExpression([HySymbol('slice'),
|
|
||||||
lst,
|
|
||||||
HyInteger(n)])
|
|
||||||
|
|
||||||
|
|
||||||
@macro("when")
|
@macro("when")
|
||||||
def when_macro(test, *body):
|
def when_macro(test, *body):
|
||||||
return HyExpression([
|
return HyExpression([
|
||||||
|
22
hy/core/language.hy
Normal file
22
hy/core/language.hy
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
;;;; This contains some of the core Hy functions used
|
||||||
|
;;;; to make functional programming slightly easier.
|
||||||
|
;;;;
|
||||||
|
|
||||||
|
|
||||||
|
(defn take [count what]
|
||||||
|
"Take `count` elements from `what`, or the whole set if the total
|
||||||
|
number of entries in `what` is less than `count`."
|
||||||
|
(setv what (iter what))
|
||||||
|
(for [i (range count)]
|
||||||
|
(yield (next what))))
|
||||||
|
|
||||||
|
|
||||||
|
(defn drop [count coll]
|
||||||
|
"Drop `count` elements from `coll` and return the iter"
|
||||||
|
(let [ [citer (iter coll)] ]
|
||||||
|
(for [i (range count)]
|
||||||
|
(next citer))
|
||||||
|
citer))
|
||||||
|
|
||||||
|
|
||||||
|
(def *exports* ["take" "drop"])
|
@ -385,9 +385,9 @@
|
|||||||
|
|
||||||
(defn test-drop []
|
(defn test-drop []
|
||||||
"NATIVE: test drop"
|
"NATIVE: test drop"
|
||||||
(assert (= (drop 0 [2 3]) [2 3]))
|
(assert (= (list (drop 0 [2 3])) [2 3]))
|
||||||
(assert (= (drop 1 [2 3]) [3]))
|
(assert (= (list (drop 1 [2 3])) [3]))
|
||||||
(assert (= (drop 2 [2 3]) [])))
|
(assert (= (list (drop 2 [2 3])) [])))
|
||||||
|
|
||||||
|
|
||||||
(defn test-rest []
|
(defn test-rest []
|
||||||
@ -741,6 +741,13 @@
|
|||||||
(assert (= "test" (:foo {:foo "test"}))))
|
(assert (= "test" (:foo {:foo "test"}))))
|
||||||
|
|
||||||
|
|
||||||
|
(defn test-take []
|
||||||
|
"NATIVE: test the take operator"
|
||||||
|
(assert (= [1 2 3] (list (take 3 [1 2 3]))))
|
||||||
|
(assert (= [1 2 3] (list (take 4 [1 2 3]))))
|
||||||
|
(assert (= [1 2] (list (take 2 [1 2 4])))))
|
||||||
|
|
||||||
|
|
||||||
(defn test-break-breaking []
|
(defn test-break-breaking []
|
||||||
"NATIVE: test checking if break actually breaks"
|
"NATIVE: test checking if break actually breaks"
|
||||||
(defn holy-grail [] (for [x (range 10)] (if (= x 5) (break))) x)
|
(defn holy-grail [] (for [x (range 10)] (if (= x 5) (break))) x)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user