diff --git a/.mailmap b/.mailmap new file mode 100644 index 0000000..678f585 --- /dev/null +++ b/.mailmap @@ -0,0 +1,12 @@ +Paul R. Tagliamonte Paul Tagliamonte +Paul R. Tagliamonte Paul Tagliamonte +Paul R. Tagliamonte Paul Tagliamonte +Paul R. Tagliamonte Paul Tagliamonte +Morten Linderud Foxboron +Morten Linderud +James King agentultra +James King J Kenneth King +Abhishek L +Bob Tolbert Bob Tolbert +Guillermo Vaya Guillermo Vaya +Gergely Nagy Gergely Nagy \ No newline at end of file diff --git a/docs/language/core.rst b/docs/language/core.rst index e0785a0..f5e31cb 100644 --- a/docs/language/core.rst +++ b/docs/language/core.rst @@ -902,6 +902,33 @@ Return an iterator of `x`, `fn(x)`, `fn(fn(x))`. [5, 25, 625, 390625, 152587890625] +.. _read-fn: + +read +---- + +Usage: ``(read [from-file eof])`` + +Reads the next hy expression from `from-file` (defaults to `sys.stdin`), and +can take a single byte as EOF (defaults to an empty string). +Raises an `EOFError` if `from-file` ends before a complete expression can be +parsed. + +.. code-block:: hy + => (read) + (+ 2 2) + ('+' 2 2) + => (eval (read)) + (+ 2 2) + 4 + => (import io) + => (def buffer (io.StringIO "(+ 2 2)\n(- 2 1)")) + => (eval (apply read [] {"from_file" buffer})) + 4 + => (eval (apply read [] {"from_file" buffer})) + 1 + + .. _remove-fn: remove diff --git a/hy/core/language.hy b/hy/core/language.hy index e74bc8a..cb04eea 100644 --- a/hy/core/language.hy +++ b/hy/core/language.hy @@ -26,8 +26,10 @@ (import itertools) (import functools) (import collections) +(import sys) (import [hy._compat [long-type]]) ; long for python2, int for python3 (import [hy.models.cons [HyCons]]) +(import [hy.lex [LexException PrematureEndOfInput tokenize]]) (defn _numeric-check [x] @@ -334,12 +336,29 @@ (_numeric_check n) (= n 0)) +(defn read [&optional [from-file sys.stdin] + [eof ""]] + "Read from input and returns a tokenized string. + Can take a given input buffer to read from" + (def buff "") + (while true + (def inn (str (.read from-file 1))) + (if (= inn eof) + (throw (EOFError "Reached end of file" ))) + (setv buff (+ buff inn)) + (try + (def parsed (first (tokenize buff))) + (except [e [LexException PrematureEndOfInput IndexError]]) + (else (if parsed (break))))) + parsed) + + (def *exports* '[butlast calling-module-name coll? cons cons? cycle dec distinct disassemble drop drop-while empty? even? every? first filter filterfalse flatten float? gensym identity inc input instance? integer integer? integer-char? interleave interpose iterable? iterate iterator? keyword? list* macroexpand macroexpand-1 map neg? nil? none? nth - numeric? odd? pos? range remove repeat repeatedly + numeric? odd? pos? range read remove repeat repeatedly rest reduce second some string string? take take-nth take-while zero? zip zip_longest zipwith]) diff --git a/hy/models/complex.py b/hy/models/complex.py index 9647997..26ac863 100644 --- a/hy/models/complex.py +++ b/hy/models/complex.py @@ -23,7 +23,7 @@ from hy.models import HyObject class HyComplex(HyObject, complex): """ - Internal represntation of a Hy Complex. May raise a ValueError as if + Internal representation of a Hy Complex. May raise a ValueError as if complex(foo) was called, given HyComplex(foo). """ diff --git a/hy/models/float.py b/hy/models/float.py index 184c3a3..ffcf455 100644 --- a/hy/models/float.py +++ b/hy/models/float.py @@ -23,7 +23,7 @@ from hy.models import HyObject class HyFloat(HyObject, float): """ - Internal represntation of a Hy Float. May raise a ValueError as if + Internal representation of a Hy Float. May raise a ValueError as if float(foo) was called, given HyFloat(foo). """ diff --git a/hy/models/integer.py b/hy/models/integer.py index 0eacef7..614520f 100644 --- a/hy/models/integer.py +++ b/hy/models/integer.py @@ -24,7 +24,7 @@ from hy._compat import long_type class HyInteger(HyObject, long_type): """ - Internal represntation of a Hy Integer. May raise a ValueError as if + Internal representation of a Hy Integer. May raise a ValueError as if int(foo) was called, given HyInteger(foo). On python 2.x long will be used instead """ diff --git a/tests/native_tests/language.hy b/tests/native_tests/language.hy index b7888e2..cc104fa 100644 --- a/tests/native_tests/language.hy +++ b/tests/native_tests/language.hy @@ -1028,3 +1028,29 @@ (foo [&rest spam] 1) (catch [NameError] True) (else (raise AssertionError)))) + +(defn test-read [] + "NATIVE: test that read takes something for stdin and reads" + (if-python2 + (import [StringIO [StringIO]]) + (import [io [StringIO]])) + (import [hy.models.expression [HyExpression]]) + + (def stdin-buffer (StringIO "(+ 2 2)\n(- 2 2)")) + (assert (= (eval (read stdin-buffer)) 4)) + (assert (isinstance (read stdin-buffer) HyExpression)) + + "Multiline test" + (def stdin-buffer (StringIO "(\n+\n41\n1\n)\n(-\n2\n1\n)")) + (assert (= (eval (read stdin-buffer)) 42)) + (assert (= (eval (read stdin-buffer)) 1)) + + "EOF test" + (def stdin-buffer (StringIO "(+ 2 2)")) + (read stdin-buffer) + (try + (read stdin-buffer) + (catch [e Exception] + (assert (isinstance e EOFError))))) + +