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
|
||||
install:
|
||||
- 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 == 'pypy' ]]; then pip install astor --use-mirrors; fi
|
||||
- python setup.py -q install
|
||||
|
@ -36,14 +36,14 @@ from hy.models.list import HyList
|
||||
from hy.models.dict import HyDict
|
||||
|
||||
import hy.importer
|
||||
from hy.core import process
|
||||
|
||||
from hy.util import str_type
|
||||
|
||||
from hy.macros import require
|
||||
from hy.util import str_type
|
||||
from hy.core import process
|
||||
|
||||
import codecs
|
||||
import traceback
|
||||
import importlib
|
||||
import codecs
|
||||
import ast
|
||||
import sys
|
||||
|
||||
@ -61,6 +61,17 @@ def compile_time_ns(module_name):
|
||||
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):
|
||||
def __init__(self, exception, traceback=None):
|
||||
self.exception = exception
|
||||
@ -339,6 +350,9 @@ class HyASTCompiler(object):
|
||||
self.anon_var_count = 0
|
||||
self.imports = defaultdict(set)
|
||||
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):
|
||||
self.anon_var_count += 1
|
||||
@ -1432,6 +1446,10 @@ class HyASTCompiler(object):
|
||||
ret = self.compile_atom(fn, expression)
|
||||
if ret:
|
||||
return ret
|
||||
|
||||
if fn in _stdlib:
|
||||
self.imports[_stdlib[fn]].add(fn)
|
||||
|
||||
if fn.startswith("."):
|
||||
# (.split "test test") -> "test test".split()
|
||||
|
||||
|
@ -24,6 +24,10 @@ MACROS = [
|
||||
"hy.core.bootstrap",
|
||||
]
|
||||
|
||||
STDLIB = [
|
||||
"hy.core.language"
|
||||
]
|
||||
|
||||
|
||||
def process(tree, module_name):
|
||||
load_macros()
|
||||
|
@ -137,21 +137,6 @@ def let_macro(variables, *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")
|
||||
def when_macro(test, *body):
|
||||
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 []
|
||||
"NATIVE: test drop"
|
||||
(assert (= (drop 0 [2 3]) [2 3]))
|
||||
(assert (= (drop 1 [2 3]) [3]))
|
||||
(assert (= (drop 2 [2 3]) [])))
|
||||
(assert (= (list (drop 0 [2 3])) [2 3]))
|
||||
(assert (= (list (drop 1 [2 3])) [3]))
|
||||
(assert (= (list (drop 2 [2 3])) [])))
|
||||
|
||||
|
||||
(defn test-rest []
|
||||
@ -741,6 +741,13 @@
|
||||
(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 []
|
||||
"NATIVE: test checking if break actually breaks"
|
||||
(defn holy-grail [] (for [x (range 10)] (if (= x 5) (break))) x)
|
||||
|
Loading…
Reference in New Issue
Block a user