Merge pull request #1224 from Kodiologist/refactor-models
Refactor hy.models
This commit is contained in:
commit
92d5d6b42c
@ -44,7 +44,7 @@ Hy parser.
|
|||||||
HyList
|
HyList
|
||||||
~~~~~~
|
~~~~~~
|
||||||
|
|
||||||
``hy.models.list.HyList`` is the base class of "iterable" Hy models. Its
|
``hy.models.HyList`` is the base class of "iterable" Hy models. Its
|
||||||
basic use is to represent bracketed ``[]`` lists, which, when used as a
|
basic use is to represent bracketed ``[]`` lists, which, when used as a
|
||||||
top-level expression, translate to Python list literals in the
|
top-level expression, translate to Python list literals in the
|
||||||
compilation phase.
|
compilation phase.
|
||||||
@ -58,7 +58,7 @@ objects in a macro, for instance.
|
|||||||
HyExpression
|
HyExpression
|
||||||
~~~~~~~~~~~~
|
~~~~~~~~~~~~
|
||||||
|
|
||||||
``hy.models.expression.HyExpression`` inherits :ref:`HyList` for
|
``hy.models.HyExpression`` inherits :ref:`HyList` for
|
||||||
parenthesized ``()`` expressions. The compilation result of those
|
parenthesized ``()`` expressions. The compilation result of those
|
||||||
expressions depends on the first element of the list: the compiler
|
expressions depends on the first element of the list: the compiler
|
||||||
dispatches expressions between compiler special-forms, user-defined
|
dispatches expressions between compiler special-forms, user-defined
|
||||||
@ -69,7 +69,7 @@ macros, and regular Python function calls.
|
|||||||
HyDict
|
HyDict
|
||||||
~~~~~~
|
~~~~~~
|
||||||
|
|
||||||
``hy.models.dict.HyDict`` inherits :ref:`HyList` for curly-bracketed ``{}``
|
``hy.models.HyDict`` inherits :ref:`HyList` for curly-bracketed ``{}``
|
||||||
expressions, which compile down to a Python dictionary literal.
|
expressions, which compile down to a Python dictionary literal.
|
||||||
|
|
||||||
The decision of using a list instead of a dict as the base class for
|
The decision of using a list instead of a dict as the base class for
|
||||||
@ -101,7 +101,7 @@ the following order:
|
|||||||
HyString
|
HyString
|
||||||
~~~~~~~~
|
~~~~~~~~
|
||||||
|
|
||||||
``hy.models.string.HyString`` is the base class of string-equivalent Hy
|
``hy.models.HyString`` is the base class of string-equivalent Hy
|
||||||
models. It also represents double-quoted string literals, ``""``, which
|
models. It also represents double-quoted string literals, ``""``, which
|
||||||
compile down to unicode string literals in Python. ``HyStrings`` inherit
|
compile down to unicode string literals in Python. ``HyStrings`` inherit
|
||||||
unicode objects in Python 2, and string objects in Python 3 (and are
|
unicode objects in Python 2, and string objects in Python 3 (and are
|
||||||
@ -118,12 +118,12 @@ strings.
|
|||||||
Numeric Models
|
Numeric Models
|
||||||
~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~
|
||||||
|
|
||||||
``hy.models.integer.HyInteger`` represents integer literals (using the
|
``hy.models.HyInteger`` represents integer literals (using the
|
||||||
``long`` type on Python 2, and ``int`` on Python 3).
|
``long`` type on Python 2, and ``int`` on Python 3).
|
||||||
|
|
||||||
``hy.models.float.HyFloat`` represents floating-point literals.
|
``hy.models.HyFloat`` represents floating-point literals.
|
||||||
|
|
||||||
``hy.models.complex.HyComplex`` represents complex literals.
|
``hy.models.HyComplex`` represents complex literals.
|
||||||
|
|
||||||
Numeric models are parsed using the corresponding Python routine, and
|
Numeric models are parsed using the corresponding Python routine, and
|
||||||
valid numeric python literals will be turned into their Hy counterpart.
|
valid numeric python literals will be turned into their Hy counterpart.
|
||||||
@ -133,7 +133,7 @@ valid numeric python literals will be turned into their Hy counterpart.
|
|||||||
HySymbol
|
HySymbol
|
||||||
~~~~~~~~
|
~~~~~~~~
|
||||||
|
|
||||||
``hy.models.symbol.HySymbol`` is the model used to represent symbols
|
``hy.models.HySymbol`` is the model used to represent symbols
|
||||||
in the Hy language. It inherits :ref:`HyString`.
|
in the Hy language. It inherits :ref:`HyString`.
|
||||||
|
|
||||||
``HySymbol`` objects are mangled in the parsing phase, to help Python
|
``HySymbol`` objects are mangled in the parsing phase, to help Python
|
||||||
@ -153,7 +153,7 @@ source code. Such a mechanism is used by :ref:`gensym` to generate
|
|||||||
HyKeyword
|
HyKeyword
|
||||||
~~~~~~~~~
|
~~~~~~~~~
|
||||||
|
|
||||||
``hy.models.keyword.HyKeyword`` represents keywords in Hy. Keywords are
|
``hy.models.HyKeyword`` represents keywords in Hy. Keywords are
|
||||||
symbols starting with a ``:``. The class inherits :ref:`HyString`.
|
symbols starting with a ``:``. The class inherits :ref:`HyString`.
|
||||||
|
|
||||||
To distinguish :ref:`HyKeywords <HyKeyword>` from :ref:`HySymbols
|
To distinguish :ref:`HyKeywords <HyKeyword>` from :ref:`HySymbols
|
||||||
@ -166,7 +166,7 @@ literal before storage.
|
|||||||
Cons Cells
|
Cons Cells
|
||||||
==========
|
==========
|
||||||
|
|
||||||
``hy.models.cons.HyCons`` is a representation of Python-friendly `cons
|
``hy.models.HyCons`` is a representation of Python-friendly `cons
|
||||||
cells`_. Cons cells are especially useful to mimic features of "usual"
|
cells`_. Cons cells are especially useful to mimic features of "usual"
|
||||||
LISP variants such as Scheme or Common Lisp.
|
LISP variants such as Scheme or Common Lisp.
|
||||||
|
|
||||||
|
@ -26,17 +26,7 @@ except ImportError:
|
|||||||
__version__ = 'unknown'
|
__version__ = 'unknown'
|
||||||
|
|
||||||
|
|
||||||
from hy.models.expression import HyExpression # NOQA
|
from hy.models import HyExpression, HyInteger, HyKeyword, HyComplex, HyString, HySymbol, HyFloat, HyDict, HyList, HySet, HyCons # NOQA
|
||||||
from hy.models.integer import HyInteger # NOQA
|
|
||||||
from hy.models.keyword import HyKeyword # NOQA
|
|
||||||
from hy.models.complex import HyComplex # NOQA
|
|
||||||
from hy.models.string import HyString # NOQA
|
|
||||||
from hy.models.symbol import HySymbol # NOQA
|
|
||||||
from hy.models.float import HyFloat # NOQA
|
|
||||||
from hy.models.dict import HyDict # NOQA
|
|
||||||
from hy.models.list import HyList # NOQA
|
|
||||||
from hy.models.set import HySet # NOQA
|
|
||||||
from hy.models.cons import HyCons # NOQA
|
|
||||||
|
|
||||||
|
|
||||||
import hy.importer # NOQA
|
import hy.importer # NOQA
|
||||||
|
@ -48,9 +48,7 @@ from hy.completer import Completer
|
|||||||
from hy.errors import HyIOError
|
from hy.errors import HyIOError
|
||||||
|
|
||||||
from hy.macros import macro, require
|
from hy.macros import macro, require
|
||||||
from hy.models.expression import HyExpression
|
from hy.models import HyExpression, HyString, HySymbol
|
||||||
from hy.models.string import HyString
|
|
||||||
from hy.models.symbol import HySymbol
|
|
||||||
|
|
||||||
from hy._compat import builtins, PY3
|
from hy._compat import builtins, PY3
|
||||||
|
|
||||||
|
@ -24,18 +24,8 @@
|
|||||||
# 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.expression import HyExpression
|
from hy.models import (HyExpression, HyKeyword, HyInteger, HyComplex, HyString,
|
||||||
from hy.models.keyword import HyKeyword
|
HySymbol, HyFloat, HyList, HySet, HyDict, HyCons)
|
||||||
from hy.models.integer import HyInteger
|
|
||||||
from hy.models.complex import HyComplex
|
|
||||||
from hy.models.string import HyString
|
|
||||||
from hy.models.symbol import HySymbol
|
|
||||||
from hy.models.float import HyFloat
|
|
||||||
from hy.models.list import HyList
|
|
||||||
from hy.models.set import HySet
|
|
||||||
from hy.models.dict import HyDict
|
|
||||||
from hy.models.cons import HyCons
|
|
||||||
|
|
||||||
from hy.errors import HyCompileError, HyTypeError
|
from hy.errors import HyCompileError, HyTypeError
|
||||||
|
|
||||||
from hy.lex.parser import hy_symbol_mangle
|
from hy.lex.parser import hy_symbol_mangle
|
||||||
|
@ -21,9 +21,7 @@
|
|||||||
;; DEALINGS IN THE SOFTWARE.
|
;; DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
(import [collections [defaultdict]]
|
(import [collections [defaultdict]]
|
||||||
[hy.models.expression [HyExpression]]
|
[hy [HyExpression HyList HyString]])
|
||||||
[hy.models.list [HyList]]
|
|
||||||
[hy.models.string [HyString]])
|
|
||||||
|
|
||||||
(defclass MultiDispatch [object] [
|
(defclass MultiDispatch [object] [
|
||||||
|
|
||||||
|
@ -33,9 +33,7 @@
|
|||||||
(import [StringIO [StringIO]])
|
(import [StringIO [StringIO]])
|
||||||
(import [io [StringIO]]))
|
(import [io [StringIO]]))
|
||||||
(import [hy._compat [long-type]]) ; long for python2, int for python3
|
(import [hy._compat [long-type]]) ; long for python2, int for python3
|
||||||
(import [hy.models.cons [HyCons]]
|
(import [hy.models [HyCons HySymbol HyKeyword]])
|
||||||
[hy.models.symbol [HySymbol]]
|
|
||||||
[hy.models.keyword [HyKeyword *keyword-prefix*]])
|
|
||||||
(import [hy.lex [LexException PrematureEndOfInput tokenize]])
|
(import [hy.lex [LexException PrematureEndOfInput tokenize]])
|
||||||
(import [hy.compiler [HyASTCompiler]])
|
(import [hy.compiler [HyASTCompiler]])
|
||||||
|
|
||||||
@ -458,7 +456,7 @@
|
|||||||
(defn keyword [value]
|
(defn keyword [value]
|
||||||
"Create a keyword from the given value. Strings numbers and even objects
|
"Create a keyword from the given value. Strings numbers and even objects
|
||||||
with the __name__ magic will work"
|
with the __name__ magic will work"
|
||||||
(if (and (string? value) (value.startswith *keyword-prefix*))
|
(if (and (string? value) (value.startswith HyKeyword.PREFIX))
|
||||||
(hyify value)
|
(hyify value)
|
||||||
(if (string? value)
|
(if (string? value)
|
||||||
(HyKeyword (+ ":" (hyify value)))
|
(HyKeyword (+ ":" (hyify value)))
|
||||||
@ -469,7 +467,7 @@
|
|||||||
(defn name [value]
|
(defn name [value]
|
||||||
"Convert the given value to a string. Keyword special character will be stripped.
|
"Convert the given value to a string. Keyword special character will be stripped.
|
||||||
String will be used as is. Even objects with the __name__ magic will work"
|
String will be used as is. Even objects with the __name__ magic will work"
|
||||||
(if (and (string? value) (value.startswith *keyword-prefix*))
|
(if (and (string? value) (value.startswith HyKeyword.PREFIX))
|
||||||
(hyify (cut value 2))
|
(hyify (cut value 2))
|
||||||
(if (string? value)
|
(if (string? value)
|
||||||
(hyify value)
|
(hyify value)
|
||||||
|
@ -26,8 +26,7 @@
|
|||||||
;;; They are automatically required in every module, except inside hy.core
|
;;; They are automatically required in every module, except inside hy.core
|
||||||
|
|
||||||
|
|
||||||
(import [hy.models.list [HyList]]
|
(import [hy.models [HyList HySymbol]]
|
||||||
[hy.models.symbol [HySymbol]]
|
|
||||||
[hy._compat [PY33 PY34]])
|
[hy._compat [PY33 PY34]])
|
||||||
|
|
||||||
(defmacro as-> [head name &rest rest]
|
(defmacro as-> [head name &rest rest]
|
||||||
|
@ -23,18 +23,8 @@ from functools import wraps
|
|||||||
|
|
||||||
from rply import ParserGenerator
|
from rply import ParserGenerator
|
||||||
|
|
||||||
from hy.models.complex import HyComplex
|
from hy.models import (HyComplex, HyCons, HyDict, HyExpression, HyFloat,
|
||||||
from hy.models.cons import HyCons
|
HyInteger, HyKeyword, HyList, HySet, HyString, HySymbol)
|
||||||
from hy.models.dict import HyDict
|
|
||||||
from hy.models.expression import HyExpression
|
|
||||||
from hy.models.float import HyFloat
|
|
||||||
from hy.models.integer import HyInteger
|
|
||||||
from hy.models.keyword import HyKeyword
|
|
||||||
from hy.models.list import HyList
|
|
||||||
from hy.models.set import HySet
|
|
||||||
from hy.models.string import HyString
|
|
||||||
from hy.models.symbol import HySymbol
|
|
||||||
|
|
||||||
from .lexer import lexer
|
from .lexer import lexer
|
||||||
from .exceptions import LexException, PrematureEndOfInput
|
from .exceptions import LexException, PrematureEndOfInput
|
||||||
|
|
||||||
|
@ -19,9 +19,7 @@
|
|||||||
# DEALINGS IN THE SOFTWARE.
|
# DEALINGS IN THE SOFTWARE.
|
||||||
|
|
||||||
from inspect import getargspec, formatargspec
|
from inspect import getargspec, formatargspec
|
||||||
from hy.models import replace_hy_obj, wrap_value
|
from hy.models import replace_hy_obj, wrap_value, HyExpression, HyString
|
||||||
from hy.models.expression import HyExpression
|
|
||||||
from hy.models.string import HyString
|
|
||||||
|
|
||||||
from hy.errors import HyTypeError, HyMacroExpansionError
|
from hy.errors import HyTypeError, HyMacroExpansionError
|
||||||
|
|
||||||
|
332
hy/models.py
Normal file
332
hy/models.py
Normal file
@ -0,0 +1,332 @@
|
|||||||
|
# Copyright (c) 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"),
|
||||||
|
# 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 __future__ import unicode_literals
|
||||||
|
from hy._compat import PY3, str_type, long_type, string_types
|
||||||
|
|
||||||
|
|
||||||
|
class HyObject(object):
|
||||||
|
"""
|
||||||
|
Generic Hy Object model. This is helpful to inject things into all the
|
||||||
|
Hy lexing Objects at once.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def replace(self, other):
|
||||||
|
if isinstance(other, HyObject):
|
||||||
|
for attr in ["start_line", "end_line",
|
||||||
|
"start_column", "end_column"]:
|
||||||
|
if not hasattr(self, attr) and hasattr(other, attr):
|
||||||
|
setattr(self, attr, getattr(other, attr))
|
||||||
|
else:
|
||||||
|
raise TypeError("Can't replace a non Hy object with a Hy object")
|
||||||
|
|
||||||
|
return self
|
||||||
|
|
||||||
|
|
||||||
|
_wrappers = {}
|
||||||
|
|
||||||
|
|
||||||
|
def wrap_value(x):
|
||||||
|
"""Wrap `x` into the corresponding Hy type.
|
||||||
|
|
||||||
|
This allows replace_hy_obj to convert a non Hy object to a Hy object.
|
||||||
|
|
||||||
|
This also allows a macro to return an unquoted expression transparently.
|
||||||
|
|
||||||
|
"""
|
||||||
|
|
||||||
|
wrapper = _wrappers.get(type(x))
|
||||||
|
if wrapper is None:
|
||||||
|
return x
|
||||||
|
else:
|
||||||
|
return wrapper(x)
|
||||||
|
|
||||||
|
|
||||||
|
def replace_hy_obj(obj, other):
|
||||||
|
|
||||||
|
if isinstance(obj, HyObject):
|
||||||
|
return obj.replace(other)
|
||||||
|
|
||||||
|
wrapped_obj = wrap_value(obj)
|
||||||
|
|
||||||
|
if isinstance(wrapped_obj, HyObject):
|
||||||
|
return wrapped_obj.replace(other)
|
||||||
|
else:
|
||||||
|
raise TypeError("Don't know how to wrap a %s object to a HyObject"
|
||||||
|
% type(obj))
|
||||||
|
|
||||||
|
|
||||||
|
class HyString(HyObject, str_type):
|
||||||
|
"""
|
||||||
|
Generic Hy String object. Helpful to store string literals from Hy
|
||||||
|
scripts. It's either a ``str`` or a ``unicode``, depending on the
|
||||||
|
Python version.
|
||||||
|
"""
|
||||||
|
pass
|
||||||
|
|
||||||
|
_wrappers[str_type] = HyString
|
||||||
|
|
||||||
|
|
||||||
|
class HySymbol(HyString):
|
||||||
|
"""
|
||||||
|
Hy Symbol. Basically a String.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __init__(self, string):
|
||||||
|
self += string
|
||||||
|
|
||||||
|
_wrappers[bool] = lambda x: HySymbol("True") if x else HySymbol("False")
|
||||||
|
_wrappers[type(None)] = lambda foo: HySymbol("None")
|
||||||
|
|
||||||
|
|
||||||
|
class HyKeyword(HyObject, str_type):
|
||||||
|
"""Generic Hy Keyword object. It's either a ``str`` or a ``unicode``,
|
||||||
|
depending on the Python version.
|
||||||
|
"""
|
||||||
|
|
||||||
|
PREFIX = "\uFDD0"
|
||||||
|
|
||||||
|
def __new__(cls, value):
|
||||||
|
if not value.startswith(cls.PREFIX):
|
||||||
|
value = cls.PREFIX + value
|
||||||
|
|
||||||
|
obj = str_type.__new__(cls, value)
|
||||||
|
return obj
|
||||||
|
|
||||||
|
|
||||||
|
def strip_digit_separators(number):
|
||||||
|
return (number.replace("_", "").replace(",", "")
|
||||||
|
if isinstance(number, string_types)
|
||||||
|
else number)
|
||||||
|
|
||||||
|
|
||||||
|
class HyInteger(HyObject, long_type):
|
||||||
|
"""
|
||||||
|
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
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __new__(cls, number, *args, **kwargs):
|
||||||
|
if isinstance(number, string_types):
|
||||||
|
number = strip_digit_separators(number)
|
||||||
|
bases = {"0x": 16, "0o": 8, "0b": 2}
|
||||||
|
for leader, base in bases.items():
|
||||||
|
if number.startswith(leader):
|
||||||
|
# We've got a string, known leader, set base.
|
||||||
|
number = long_type(number, base=base)
|
||||||
|
break
|
||||||
|
else:
|
||||||
|
# We've got a string, no known leader; base 10.
|
||||||
|
number = long_type(number, base=10)
|
||||||
|
else:
|
||||||
|
# We've got a non-string; convert straight.
|
||||||
|
number = long_type(number)
|
||||||
|
return super(HyInteger, cls).__new__(cls, number)
|
||||||
|
|
||||||
|
|
||||||
|
_wrappers[int] = HyInteger
|
||||||
|
if not PY3: # do not add long on python3
|
||||||
|
_wrappers[long_type] = HyInteger
|
||||||
|
|
||||||
|
|
||||||
|
class HyFloat(HyObject, float):
|
||||||
|
"""
|
||||||
|
Internal representation of a Hy Float. May raise a ValueError as if
|
||||||
|
float(foo) was called, given HyFloat(foo).
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __new__(cls, number, *args, **kwargs):
|
||||||
|
number = float(strip_digit_separators(number))
|
||||||
|
return super(HyFloat, cls).__new__(cls, number)
|
||||||
|
|
||||||
|
_wrappers[float] = HyFloat
|
||||||
|
|
||||||
|
|
||||||
|
class HyComplex(HyObject, complex):
|
||||||
|
"""
|
||||||
|
Internal representation of a Hy Complex. May raise a ValueError as if
|
||||||
|
complex(foo) was called, given HyComplex(foo).
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __new__(cls, number, *args, **kwargs):
|
||||||
|
number = complex(strip_digit_separators(number))
|
||||||
|
return super(HyComplex, cls).__new__(cls, number)
|
||||||
|
|
||||||
|
_wrappers[complex] = HyComplex
|
||||||
|
|
||||||
|
|
||||||
|
class HyList(HyObject, list):
|
||||||
|
"""
|
||||||
|
Hy List. Basically just a list.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def replace(self, other):
|
||||||
|
for x in self:
|
||||||
|
replace_hy_obj(x, other)
|
||||||
|
|
||||||
|
HyObject.replace(self, other)
|
||||||
|
return self
|
||||||
|
|
||||||
|
def __add__(self, other):
|
||||||
|
return self.__class__(super(HyList, self).__add__(other))
|
||||||
|
|
||||||
|
def __getslice__(self, start, end):
|
||||||
|
return self.__class__(super(HyList, self).__getslice__(start, end))
|
||||||
|
|
||||||
|
def __getitem__(self, item):
|
||||||
|
ret = super(HyList, self).__getitem__(item)
|
||||||
|
|
||||||
|
if isinstance(item, slice):
|
||||||
|
return self.__class__(ret)
|
||||||
|
|
||||||
|
return ret
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "[%s]" % (" ".join([repr(x) for x in self]))
|
||||||
|
|
||||||
|
_wrappers[list] = lambda l: HyList(wrap_value(x) for x in l)
|
||||||
|
_wrappers[tuple] = lambda t: HyList(wrap_value(x) for x in t)
|
||||||
|
|
||||||
|
|
||||||
|
class HyDict(HyList):
|
||||||
|
"""
|
||||||
|
HyDict (just a representation of a dict)
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "{%s}" % (" ".join([repr(x) for x in self]))
|
||||||
|
|
||||||
|
def keys(self):
|
||||||
|
return self[0::2]
|
||||||
|
|
||||||
|
def values(self):
|
||||||
|
return self[1::2]
|
||||||
|
|
||||||
|
def items(self):
|
||||||
|
return list(zip(self.keys(), self.values()))
|
||||||
|
|
||||||
|
_wrappers[dict] = lambda d: HyDict(wrap_value(x) for x in sum(d.items(), ()))
|
||||||
|
|
||||||
|
|
||||||
|
class HyExpression(HyList):
|
||||||
|
"""
|
||||||
|
Hy S-Expression. Basically just a list.
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "(%s)" % (" ".join([repr(x) for x in self]))
|
||||||
|
|
||||||
|
_wrappers[HyExpression] = lambda e: HyExpression(wrap_value(x) for x in e)
|
||||||
|
|
||||||
|
|
||||||
|
class HySet(HyList):
|
||||||
|
"""
|
||||||
|
Hy set (just a representation of a set)
|
||||||
|
"""
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return "#{%s}" % (" ".join([repr(x) for x in self]))
|
||||||
|
|
||||||
|
_wrappers[set] = lambda s: HySet(wrap_value(x) for x in s)
|
||||||
|
|
||||||
|
|
||||||
|
class HyCons(HyObject):
|
||||||
|
"""
|
||||||
|
HyCons: a cons object.
|
||||||
|
|
||||||
|
Building a HyCons of something and a HyList really builds a HyList
|
||||||
|
"""
|
||||||
|
|
||||||
|
__slots__ = ["car", "cdr"]
|
||||||
|
|
||||||
|
def __new__(cls, car, cdr):
|
||||||
|
if isinstance(cdr, list):
|
||||||
|
|
||||||
|
# Keep unquotes in the cdr of conses
|
||||||
|
if type(cdr) == HyExpression:
|
||||||
|
if len(cdr) > 0 and type(cdr[0]) == HySymbol:
|
||||||
|
if cdr[0] in ("unquote", "unquote_splice"):
|
||||||
|
return super(HyCons, cls).__new__(cls)
|
||||||
|
|
||||||
|
return cdr.__class__([wrap_value(car)] + cdr)
|
||||||
|
|
||||||
|
elif cdr is None:
|
||||||
|
return HyExpression([wrap_value(car)])
|
||||||
|
|
||||||
|
else:
|
||||||
|
return super(HyCons, cls).__new__(cls)
|
||||||
|
|
||||||
|
def __init__(self, car, cdr):
|
||||||
|
self.car = wrap_value(car)
|
||||||
|
self.cdr = wrap_value(cdr)
|
||||||
|
|
||||||
|
def __getitem__(self, n):
|
||||||
|
if n == 0:
|
||||||
|
return self.car
|
||||||
|
if n == slice(1, None):
|
||||||
|
return self.cdr
|
||||||
|
|
||||||
|
raise IndexError(
|
||||||
|
"Can only get the car ([0]) or the cdr ([1:]) of a HyCons")
|
||||||
|
|
||||||
|
def __setitem__(self, n, new):
|
||||||
|
if n == 0:
|
||||||
|
self.car = new
|
||||||
|
return
|
||||||
|
if n == slice(1, None):
|
||||||
|
self.cdr = new
|
||||||
|
return
|
||||||
|
|
||||||
|
raise IndexError(
|
||||||
|
"Can only set the car ([0]) or the cdr ([1:]) of a HyCons")
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
yield self.car
|
||||||
|
try:
|
||||||
|
iterator = (i for i in self.cdr)
|
||||||
|
except TypeError:
|
||||||
|
if self.cdr is not None:
|
||||||
|
yield self.cdr
|
||||||
|
raise TypeError("Iteration on malformed cons")
|
||||||
|
else:
|
||||||
|
for i in iterator:
|
||||||
|
yield i
|
||||||
|
|
||||||
|
def replace(self, other):
|
||||||
|
if self.car is not None:
|
||||||
|
replace_hy_obj(self.car, other)
|
||||||
|
if self.cdr is not None:
|
||||||
|
replace_hy_obj(self.cdr, other)
|
||||||
|
|
||||||
|
HyObject.replace(self, other)
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
if isinstance(self.cdr, self.__class__):
|
||||||
|
return "(%s %s)" % (repr(self.car), repr(self.cdr)[1:-1])
|
||||||
|
else:
|
||||||
|
return "(%s . %s)" % (repr(self.car), repr(self.cdr))
|
||||||
|
|
||||||
|
def __eq__(self, other):
|
||||||
|
return (
|
||||||
|
isinstance(other, self.__class__) and
|
||||||
|
self.car == other.car and
|
||||||
|
self.cdr == other.cdr
|
||||||
|
)
|
@ -1,69 +0,0 @@
|
|||||||
# Copyright (c) 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"),
|
|
||||||
# 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.
|
|
||||||
|
|
||||||
|
|
||||||
class HyObject(object):
|
|
||||||
"""
|
|
||||||
Generic Hy Object model. This is helpful to inject things into all the
|
|
||||||
Hy lexing Objects at once.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def replace(self, other):
|
|
||||||
if isinstance(other, HyObject):
|
|
||||||
for attr in ["start_line", "end_line",
|
|
||||||
"start_column", "end_column"]:
|
|
||||||
if not hasattr(self, attr) and hasattr(other, attr):
|
|
||||||
setattr(self, attr, getattr(other, attr))
|
|
||||||
else:
|
|
||||||
raise TypeError("Can't replace a non Hy object with a Hy object")
|
|
||||||
|
|
||||||
return self
|
|
||||||
|
|
||||||
_wrappers = {}
|
|
||||||
|
|
||||||
|
|
||||||
def wrap_value(x):
|
|
||||||
"""Wrap `x` into the corresponding Hy type.
|
|
||||||
|
|
||||||
This allows replace_hy_obj to convert a non Hy object to a Hy object.
|
|
||||||
|
|
||||||
This also allows a macro to return an unquoted expression transparently.
|
|
||||||
|
|
||||||
"""
|
|
||||||
|
|
||||||
wrapper = _wrappers.get(type(x))
|
|
||||||
if wrapper is None:
|
|
||||||
return x
|
|
||||||
else:
|
|
||||||
return wrapper(x)
|
|
||||||
|
|
||||||
|
|
||||||
def replace_hy_obj(obj, other):
|
|
||||||
|
|
||||||
if isinstance(obj, HyObject):
|
|
||||||
return obj.replace(other)
|
|
||||||
|
|
||||||
wrapped_obj = wrap_value(obj)
|
|
||||||
|
|
||||||
if isinstance(wrapped_obj, HyObject):
|
|
||||||
return wrapped_obj.replace(other)
|
|
||||||
else:
|
|
||||||
raise TypeError("Don't know how to wrap a %s object to a HyObject"
|
|
||||||
% type(obj))
|
|
@ -1,37 +0,0 @@
|
|||||||
# Copyright (c) 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"),
|
|
||||||
# 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 import HyObject, _wrappers
|
|
||||||
from hy._compat import string_types
|
|
||||||
|
|
||||||
|
|
||||||
class HyComplex(HyObject, complex):
|
|
||||||
"""
|
|
||||||
Internal representation of a Hy Complex. May raise a ValueError as if
|
|
||||||
complex(foo) was called, given HyComplex(foo).
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __new__(cls, number, *args, **kwargs):
|
|
||||||
if isinstance(number, string_types):
|
|
||||||
number = number.replace("_", "").replace(",", "")
|
|
||||||
number = complex(number)
|
|
||||||
return super(HyComplex, cls).__new__(cls, number)
|
|
||||||
|
|
||||||
_wrappers[complex] = HyComplex
|
|
@ -1,107 +0,0 @@
|
|||||||
# Copyright (c) 2013 Nicolas Dandrimont <nicolas.dandrimont@crans.org>
|
|
||||||
#
|
|
||||||
# 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 import HyObject, replace_hy_obj, wrap_value
|
|
||||||
from hy.models.expression import HyExpression
|
|
||||||
from hy.models.symbol import HySymbol
|
|
||||||
|
|
||||||
|
|
||||||
class HyCons(HyObject):
|
|
||||||
"""
|
|
||||||
HyCons: a cons object.
|
|
||||||
|
|
||||||
Building a HyCons of something and a HyList really builds a HyList
|
|
||||||
"""
|
|
||||||
|
|
||||||
__slots__ = ["car", "cdr"]
|
|
||||||
|
|
||||||
def __new__(cls, car, cdr):
|
|
||||||
if isinstance(cdr, list):
|
|
||||||
|
|
||||||
# Keep unquotes in the cdr of conses
|
|
||||||
if type(cdr) == HyExpression:
|
|
||||||
if len(cdr) > 0 and type(cdr[0]) == HySymbol:
|
|
||||||
if cdr[0] in ("unquote", "unquote_splice"):
|
|
||||||
return super(HyCons, cls).__new__(cls)
|
|
||||||
|
|
||||||
return cdr.__class__([wrap_value(car)] + cdr)
|
|
||||||
|
|
||||||
elif cdr is None:
|
|
||||||
return HyExpression([wrap_value(car)])
|
|
||||||
|
|
||||||
else:
|
|
||||||
return super(HyCons, cls).__new__(cls)
|
|
||||||
|
|
||||||
def __init__(self, car, cdr):
|
|
||||||
self.car = wrap_value(car)
|
|
||||||
self.cdr = wrap_value(cdr)
|
|
||||||
|
|
||||||
def __getitem__(self, n):
|
|
||||||
if n == 0:
|
|
||||||
return self.car
|
|
||||||
if n == slice(1, None):
|
|
||||||
return self.cdr
|
|
||||||
|
|
||||||
raise IndexError(
|
|
||||||
"Can only get the car ([0]) or the cdr ([1:]) of a HyCons")
|
|
||||||
|
|
||||||
def __setitem__(self, n, new):
|
|
||||||
if n == 0:
|
|
||||||
self.car = new
|
|
||||||
return
|
|
||||||
if n == slice(1, None):
|
|
||||||
self.cdr = new
|
|
||||||
return
|
|
||||||
|
|
||||||
raise IndexError(
|
|
||||||
"Can only set the car ([0]) or the cdr ([1:]) of a HyCons")
|
|
||||||
|
|
||||||
def __iter__(self):
|
|
||||||
yield self.car
|
|
||||||
try:
|
|
||||||
iterator = (i for i in self.cdr)
|
|
||||||
except TypeError:
|
|
||||||
if self.cdr is not None:
|
|
||||||
yield self.cdr
|
|
||||||
raise TypeError("Iteration on malformed cons")
|
|
||||||
else:
|
|
||||||
for i in iterator:
|
|
||||||
yield i
|
|
||||||
|
|
||||||
def replace(self, other):
|
|
||||||
if self.car is not None:
|
|
||||||
replace_hy_obj(self.car, other)
|
|
||||||
if self.cdr is not None:
|
|
||||||
replace_hy_obj(self.cdr, other)
|
|
||||||
|
|
||||||
HyObject.replace(self, other)
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
if isinstance(self.cdr, self.__class__):
|
|
||||||
return "(%s %s)" % (repr(self.car), repr(self.cdr)[1:-1])
|
|
||||||
else:
|
|
||||||
return "(%s . %s)" % (repr(self.car), repr(self.cdr))
|
|
||||||
|
|
||||||
def __eq__(self, other):
|
|
||||||
return (
|
|
||||||
isinstance(other, self.__class__) and
|
|
||||||
self.car == other.car and
|
|
||||||
self.cdr == other.cdr
|
|
||||||
)
|
|
@ -1,42 +0,0 @@
|
|||||||
# Copyright (c) 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"),
|
|
||||||
# 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 import _wrappers, wrap_value
|
|
||||||
from hy.models.list import HyList
|
|
||||||
|
|
||||||
|
|
||||||
class HyDict(HyList):
|
|
||||||
"""
|
|
||||||
HyDict (just a representation of a dict)
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return "{%s}" % (" ".join([repr(x) for x in self]))
|
|
||||||
|
|
||||||
def keys(self):
|
|
||||||
return self[0::2]
|
|
||||||
|
|
||||||
def values(self):
|
|
||||||
return self[1::2]
|
|
||||||
|
|
||||||
def items(self):
|
|
||||||
return list(zip(self.keys(), self.values()))
|
|
||||||
|
|
||||||
_wrappers[dict] = lambda d: HyDict(wrap_value(x) for x in sum(d.items(), ()))
|
|
@ -1,33 +0,0 @@
|
|||||||
# Copyright (c) 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"),
|
|
||||||
# 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 import _wrappers, wrap_value
|
|
||||||
from hy.models.list import HyList
|
|
||||||
|
|
||||||
|
|
||||||
class HyExpression(HyList):
|
|
||||||
"""
|
|
||||||
Hy S-Expression. Basically just a list.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return "(%s)" % (" ".join([repr(x) for x in self]))
|
|
||||||
|
|
||||||
_wrappers[HyExpression] = lambda e: HyExpression(wrap_value(x) for x in e)
|
|
@ -1,37 +0,0 @@
|
|||||||
# Copyright (c) 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"),
|
|
||||||
# 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 import HyObject, _wrappers
|
|
||||||
from hy._compat import string_types
|
|
||||||
|
|
||||||
|
|
||||||
class HyFloat(HyObject, float):
|
|
||||||
"""
|
|
||||||
Internal representation of a Hy Float. May raise a ValueError as if
|
|
||||||
float(foo) was called, given HyFloat(foo).
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __new__(cls, number, *args, **kwargs):
|
|
||||||
if isinstance(number, string_types):
|
|
||||||
number = number.replace("_", "").replace(",", "")
|
|
||||||
number = float(number)
|
|
||||||
return super(HyFloat, cls).__new__(cls, number)
|
|
||||||
|
|
||||||
_wrappers[float] = HyFloat
|
|
@ -1,55 +0,0 @@
|
|||||||
# Copyright (c) 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"),
|
|
||||||
# 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 import HyObject, _wrappers
|
|
||||||
from hy._compat import long_type, string_types
|
|
||||||
|
|
||||||
import sys
|
|
||||||
|
|
||||||
|
|
||||||
class HyInteger(HyObject, long_type):
|
|
||||||
"""
|
|
||||||
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
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __new__(cls, number, *args, **kwargs):
|
|
||||||
if isinstance(number, string_types):
|
|
||||||
number = number.replace("_", "").replace(",", "")
|
|
||||||
bases = {"0x": 16, "0o": 8, "0b": 2}
|
|
||||||
for leader, base in bases.items():
|
|
||||||
if number.startswith(leader):
|
|
||||||
# We've got a string, known leader, set base.
|
|
||||||
number = long_type(number, base=base)
|
|
||||||
break
|
|
||||||
else:
|
|
||||||
# We've got a string, no known leader; base 10.
|
|
||||||
number = long_type(number, base=10)
|
|
||||||
else:
|
|
||||||
# We've got a non-string; convert straight.
|
|
||||||
number = long_type(number)
|
|
||||||
return super(HyInteger, cls).__new__(cls, number)
|
|
||||||
|
|
||||||
|
|
||||||
_wrappers[int] = HyInteger
|
|
||||||
|
|
||||||
if sys.version_info[0] < 3: # do not add long on python3
|
|
||||||
_wrappers[long_type] = HyInteger
|
|
@ -1,39 +0,0 @@
|
|||||||
# Copyright (c) 2013 Gergely Nagy <algernon@madhouse-project.org>
|
|
||||||
#
|
|
||||||
# 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 __future__ import unicode_literals
|
|
||||||
from hy.models import HyObject
|
|
||||||
from hy._compat import str_type
|
|
||||||
|
|
||||||
|
|
||||||
KEYWORD_PREFIX = "\uFDD0"
|
|
||||||
|
|
||||||
|
|
||||||
class HyKeyword(HyObject, str_type):
|
|
||||||
"""Generic Hy Keyword object. It's either a ``str`` or a ``unicode``,
|
|
||||||
depending on the Python version.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __new__(cls, value):
|
|
||||||
if not value.startswith(KEYWORD_PREFIX):
|
|
||||||
value = KEYWORD_PREFIX + value
|
|
||||||
|
|
||||||
obj = str_type.__new__(cls, value)
|
|
||||||
return obj
|
|
@ -1,54 +0,0 @@
|
|||||||
# Copyright (c) 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"),
|
|
||||||
# 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 import HyObject, replace_hy_obj, _wrappers, wrap_value
|
|
||||||
|
|
||||||
|
|
||||||
class HyList(HyObject, list):
|
|
||||||
"""
|
|
||||||
Hy List. Basically just a list.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def replace(self, other):
|
|
||||||
for x in self:
|
|
||||||
replace_hy_obj(x, other)
|
|
||||||
|
|
||||||
HyObject.replace(self, other)
|
|
||||||
return self
|
|
||||||
|
|
||||||
def __add__(self, other):
|
|
||||||
return self.__class__(super(HyList, self).__add__(other))
|
|
||||||
|
|
||||||
def __getslice__(self, start, end):
|
|
||||||
return self.__class__(super(HyList, self).__getslice__(start, end))
|
|
||||||
|
|
||||||
def __getitem__(self, item):
|
|
||||||
ret = super(HyList, self).__getitem__(item)
|
|
||||||
|
|
||||||
if isinstance(item, slice):
|
|
||||||
return self.__class__(ret)
|
|
||||||
|
|
||||||
return ret
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return "[%s]" % (" ".join([repr(x) for x in self]))
|
|
||||||
|
|
||||||
_wrappers[list] = lambda l: HyList(wrap_value(x) for x in l)
|
|
||||||
_wrappers[tuple] = lambda t: HyList(wrap_value(x) for x in t)
|
|
@ -1,33 +0,0 @@
|
|||||||
# Copyright (c) 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"),
|
|
||||||
# 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 import _wrappers, wrap_value
|
|
||||||
from hy.models.list import HyList
|
|
||||||
|
|
||||||
|
|
||||||
class HySet(HyList):
|
|
||||||
"""
|
|
||||||
Hy set (just a representation of a set)
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __repr__(self):
|
|
||||||
return "#{%s}" % (" ".join([repr(x) for x in self]))
|
|
||||||
|
|
||||||
_wrappers[set] = lambda s: HySet(wrap_value(x) for x in s)
|
|
@ -1,33 +0,0 @@
|
|||||||
# Copyright (c) 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"),
|
|
||||||
# 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 import HyObject, _wrappers
|
|
||||||
from hy._compat import str_type
|
|
||||||
|
|
||||||
|
|
||||||
class HyString(HyObject, str_type):
|
|
||||||
"""
|
|
||||||
Generic Hy String object. Helpful to store string literals from Hy
|
|
||||||
scripts. It's either a ``str`` or a ``unicode``, depending on the
|
|
||||||
Python version.
|
|
||||||
"""
|
|
||||||
pass
|
|
||||||
|
|
||||||
_wrappers[str_type] = HyString
|
|
@ -1,34 +0,0 @@
|
|||||||
# Copyright (c) 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"),
|
|
||||||
# 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 import _wrappers
|
|
||||||
from hy.models.string import HyString
|
|
||||||
|
|
||||||
|
|
||||||
class HySymbol(HyString):
|
|
||||||
"""
|
|
||||||
Hy Symbol. Basically a String.
|
|
||||||
"""
|
|
||||||
|
|
||||||
def __init__(self, string):
|
|
||||||
self += string
|
|
||||||
|
|
||||||
_wrappers[bool] = lambda x: HySymbol("True") if x else HySymbol("False")
|
|
||||||
_wrappers[type(None)] = lambda foo: HySymbol("None")
|
|
@ -23,10 +23,7 @@ import ast
|
|||||||
import sys
|
import sys
|
||||||
|
|
||||||
from hy import compiler
|
from hy import compiler
|
||||||
from hy.models.expression import HyExpression
|
from hy.models import HyExpression, HyList, HySymbol, HyInteger
|
||||||
from hy.models.list import HyList
|
|
||||||
from hy.models.symbol import HySymbol
|
|
||||||
from hy.models.integer import HyInteger
|
|
||||||
from hy._compat import PY33
|
from hy._compat import PY33
|
||||||
|
|
||||||
if sys.version_info[0] <= 2 and sys.version_info[1] <= 6:
|
if sys.version_info[0] <= 2 and sys.version_info[1] <= 6:
|
||||||
|
@ -19,17 +19,8 @@
|
|||||||
# 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.expression import HyExpression
|
from hy.models import (HyExpression, HyInteger, HyFloat, HyComplex, HySymbol,
|
||||||
from hy.models.integer import HyInteger
|
HyString, HyDict, HyList, HySet, HyCons)
|
||||||
from hy.models.float import HyFloat
|
|
||||||
from hy.models.complex import HyComplex
|
|
||||||
from hy.models.symbol import HySymbol
|
|
||||||
from hy.models.string import HyString
|
|
||||||
from hy.models.dict import HyDict
|
|
||||||
from hy.models.list import HyList
|
|
||||||
from hy.models.set import HySet
|
|
||||||
from hy.models.cons import HyCons
|
|
||||||
|
|
||||||
from hy.lex import LexException, PrematureEndOfInput, tokenize
|
from hy.lex import LexException, PrematureEndOfInput, tokenize
|
||||||
|
|
||||||
|
|
||||||
|
@ -2,10 +2,7 @@
|
|||||||
from hy.macros import macro, macroexpand
|
from hy.macros import macro, macroexpand
|
||||||
from hy.lex import tokenize
|
from hy.lex import tokenize
|
||||||
|
|
||||||
from hy.models.string import HyString
|
from hy.models import HyString, HyList, HySymbol, HyExpression
|
||||||
from hy.models.list import HyList
|
|
||||||
from hy.models.symbol import HySymbol
|
|
||||||
from hy.models.expression import HyExpression
|
|
||||||
from hy.errors import HyMacroExpansionError
|
from hy.errors import HyMacroExpansionError
|
||||||
|
|
||||||
from hy.compiler import HyASTCompiler
|
from hy.compiler import HyASTCompiler
|
||||||
|
@ -1,56 +0,0 @@
|
|||||||
# Copyright (c) 2013 Nicolas Dandrimont <nicolas.dandrimont@crans.org>
|
|
||||||
#
|
|
||||||
# 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.cons import HyCons
|
|
||||||
|
|
||||||
|
|
||||||
def test_cons_slicing():
|
|
||||||
"""Check that cons slicing works as expected"""
|
|
||||||
cons = HyCons("car", "cdr")
|
|
||||||
assert cons[0] == "car"
|
|
||||||
assert cons[1:] == "cdr"
|
|
||||||
try:
|
|
||||||
cons[:]
|
|
||||||
assert True is False
|
|
||||||
except IndexError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
try:
|
|
||||||
cons[1]
|
|
||||||
assert True is False
|
|
||||||
except IndexError:
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
|
||||||
def test_cons_replacing():
|
|
||||||
"""Check that assigning to a cons works as expected"""
|
|
||||||
cons = HyCons("foo", "bar")
|
|
||||||
cons[0] = "car"
|
|
||||||
|
|
||||||
assert cons == HyCons("car", "bar")
|
|
||||||
|
|
||||||
cons[1:] = "cdr"
|
|
||||||
assert cons == HyCons("car", "cdr")
|
|
||||||
|
|
||||||
try:
|
|
||||||
cons[:] = "foo"
|
|
||||||
assert True is False
|
|
||||||
except IndexError:
|
|
||||||
pass
|
|
@ -1,16 +0,0 @@
|
|||||||
from hy.models.dict import HyDict
|
|
||||||
|
|
||||||
|
|
||||||
hydict = HyDict(["a", 1, "b", 2, "c", 3])
|
|
||||||
|
|
||||||
|
|
||||||
def test_dict_items():
|
|
||||||
assert hydict.items() == [("a", 1), ("b", 2), ("c", 3)]
|
|
||||||
|
|
||||||
|
|
||||||
def test_dict_keys():
|
|
||||||
assert hydict.keys() == ["a", "b", "c"]
|
|
||||||
|
|
||||||
|
|
||||||
def test_dict_values():
|
|
||||||
assert hydict.values() == [1, 2, 3]
|
|
@ -1,22 +0,0 @@
|
|||||||
from hy.models.list import HyList
|
|
||||||
|
|
||||||
|
|
||||||
def test_list_add():
|
|
||||||
"""Check that adding two HyLists generates a HyList"""
|
|
||||||
a = HyList([1, 2, 3])
|
|
||||||
b = HyList([3, 4, 5])
|
|
||||||
c = a + b
|
|
||||||
assert c == [1, 2, 3, 3, 4, 5]
|
|
||||||
assert c.__class__ == HyList
|
|
||||||
|
|
||||||
|
|
||||||
def test_list_slice():
|
|
||||||
"""Check that slicing a HyList produces a HyList"""
|
|
||||||
a = HyList([1, 2, 3, 4])
|
|
||||||
sl1 = a[1:]
|
|
||||||
sl5 = a[5:]
|
|
||||||
|
|
||||||
assert type(sl1) == HyList
|
|
||||||
assert sl1 == HyList([2, 3, 4])
|
|
||||||
assert type(sl5) == HyList
|
|
||||||
assert sl5 == HyList([])
|
|
@ -1,26 +0,0 @@
|
|||||||
from hy._compat import long_type, str_type
|
|
||||||
from hy.models.string import HyString
|
|
||||||
from hy.models.integer import HyInteger
|
|
||||||
from hy.models.list import HyList
|
|
||||||
|
|
||||||
from hy.models import replace_hy_obj
|
|
||||||
|
|
||||||
|
|
||||||
def test_replace_long_type():
|
|
||||||
""" Test replacing integers."""
|
|
||||||
replaced = replace_hy_obj(long_type(0), HyInteger(13))
|
|
||||||
assert replaced == HyInteger(0)
|
|
||||||
|
|
||||||
|
|
||||||
def test_replace_string_type():
|
|
||||||
"""Test replacing python string"""
|
|
||||||
replaced = replace_hy_obj(str_type("foo"), HyString("bar"))
|
|
||||||
assert replaced == HyString("foo")
|
|
||||||
|
|
||||||
|
|
||||||
def test_replace_tuple():
|
|
||||||
""" Test replacing tuples."""
|
|
||||||
replaced = replace_hy_obj((long_type(0), ), HyInteger(13))
|
|
||||||
assert type(replaced) == HyList
|
|
||||||
assert type(replaced[0]) == HyInteger
|
|
||||||
assert replaced == HyList([HyInteger(0)])
|
|
@ -1,8 +0,0 @@
|
|||||||
from hy.models.set import HySet
|
|
||||||
|
|
||||||
|
|
||||||
hyset = HySet([3, 1, 2, 2])
|
|
||||||
|
|
||||||
|
|
||||||
def test_set():
|
|
||||||
assert hyset == [3, 1, 2, 2]
|
|
@ -1,28 +0,0 @@
|
|||||||
from hy._compat import long_type
|
|
||||||
from hy.models.integer import HyInteger
|
|
||||||
from hy.models.list import HyList
|
|
||||||
from hy.models.expression import HyExpression
|
|
||||||
|
|
||||||
from hy.models import wrap_value
|
|
||||||
|
|
||||||
|
|
||||||
def test_wrap_long_type():
|
|
||||||
""" Test conversion of integers."""
|
|
||||||
wrapped = wrap_value(long_type(0))
|
|
||||||
assert type(wrapped) == HyInteger
|
|
||||||
|
|
||||||
|
|
||||||
def test_wrap_tuple():
|
|
||||||
""" Test conversion of tuples."""
|
|
||||||
wrapped = wrap_value((HyInteger(0),))
|
|
||||||
assert type(wrapped) == HyList
|
|
||||||
assert type(wrapped[0]) == HyInteger
|
|
||||||
assert wrapped == HyList([HyInteger(0)])
|
|
||||||
|
|
||||||
|
|
||||||
def test_wrap_nested_expr():
|
|
||||||
""" Test conversion of HyExpressions with embedded non-HyObjects."""
|
|
||||||
wrapped = wrap_value(HyExpression([long_type(0)]))
|
|
||||||
assert type(wrapped) == HyExpression
|
|
||||||
assert type(wrapped[0]) == HyInteger
|
|
||||||
assert wrapped == HyExpression([HyInteger(0)])
|
|
@ -241,7 +241,7 @@
|
|||||||
|
|
||||||
(defn test-gensym []
|
(defn test-gensym []
|
||||||
"NATIVE: testing the gensym function"
|
"NATIVE: testing the gensym function"
|
||||||
(import [hy.models.symbol [HySymbol]])
|
(import [hy.models [HySymbol]])
|
||||||
(setv s1 (gensym))
|
(setv s1 (gensym))
|
||||||
(assert (isinstance s1 HySymbol))
|
(assert (isinstance s1 HySymbol))
|
||||||
(assert (= 0 (.find s1 ":G_")))
|
(assert (= 0 (.find s1 ":G_")))
|
||||||
|
@ -1363,7 +1363,7 @@
|
|||||||
(if-python2
|
(if-python2
|
||||||
(import [StringIO [StringIO]])
|
(import [StringIO [StringIO]])
|
||||||
(import [io [StringIO]]))
|
(import [io [StringIO]]))
|
||||||
(import [hy.models.expression [HyExpression]])
|
(import [hy.models [HyExpression]])
|
||||||
|
|
||||||
(def stdin-buffer (StringIO "(+ 2 2)\n(- 2 2)"))
|
(def stdin-buffer (StringIO "(+ 2 2)\n(- 2 2)"))
|
||||||
(assert (= (eval (read stdin-buffer)) 4))
|
(assert (= (eval (read stdin-buffer)) 4))
|
||||||
|
123
tests/test_models.py
Normal file
123
tests/test_models.py
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
from hy._compat import long_type, str_type
|
||||||
|
from hy.models import (wrap_value, replace_hy_obj, HyString, HyInteger, HyList,
|
||||||
|
HyDict, HySet, HyExpression, HyCons)
|
||||||
|
|
||||||
|
|
||||||
|
def test_wrap_long_type():
|
||||||
|
""" Test conversion of integers."""
|
||||||
|
wrapped = wrap_value(long_type(0))
|
||||||
|
assert type(wrapped) == HyInteger
|
||||||
|
|
||||||
|
|
||||||
|
def test_wrap_tuple():
|
||||||
|
""" Test conversion of tuples."""
|
||||||
|
wrapped = wrap_value((HyInteger(0),))
|
||||||
|
assert type(wrapped) == HyList
|
||||||
|
assert type(wrapped[0]) == HyInteger
|
||||||
|
assert wrapped == HyList([HyInteger(0)])
|
||||||
|
|
||||||
|
|
||||||
|
def test_wrap_nested_expr():
|
||||||
|
""" Test conversion of HyExpressions with embedded non-HyObjects."""
|
||||||
|
wrapped = wrap_value(HyExpression([long_type(0)]))
|
||||||
|
assert type(wrapped) == HyExpression
|
||||||
|
assert type(wrapped[0]) == HyInteger
|
||||||
|
assert wrapped == HyExpression([HyInteger(0)])
|
||||||
|
|
||||||
|
|
||||||
|
def test_replace_long_type():
|
||||||
|
""" Test replacing integers."""
|
||||||
|
replaced = replace_hy_obj(long_type(0), HyInteger(13))
|
||||||
|
assert replaced == HyInteger(0)
|
||||||
|
|
||||||
|
|
||||||
|
def test_replace_string_type():
|
||||||
|
"""Test replacing python string"""
|
||||||
|
replaced = replace_hy_obj(str_type("foo"), HyString("bar"))
|
||||||
|
assert replaced == HyString("foo")
|
||||||
|
|
||||||
|
|
||||||
|
def test_replace_tuple():
|
||||||
|
""" Test replacing tuples."""
|
||||||
|
replaced = replace_hy_obj((long_type(0), ), HyInteger(13))
|
||||||
|
assert type(replaced) == HyList
|
||||||
|
assert type(replaced[0]) == HyInteger
|
||||||
|
assert replaced == HyList([HyInteger(0)])
|
||||||
|
|
||||||
|
|
||||||
|
def test_list_add():
|
||||||
|
"""Check that adding two HyLists generates a HyList"""
|
||||||
|
a = HyList([1, 2, 3])
|
||||||
|
b = HyList([3, 4, 5])
|
||||||
|
c = a + b
|
||||||
|
assert c == [1, 2, 3, 3, 4, 5]
|
||||||
|
assert c.__class__ == HyList
|
||||||
|
|
||||||
|
|
||||||
|
def test_list_slice():
|
||||||
|
"""Check that slicing a HyList produces a HyList"""
|
||||||
|
a = HyList([1, 2, 3, 4])
|
||||||
|
sl1 = a[1:]
|
||||||
|
sl5 = a[5:]
|
||||||
|
|
||||||
|
assert type(sl1) == HyList
|
||||||
|
assert sl1 == HyList([2, 3, 4])
|
||||||
|
assert type(sl5) == HyList
|
||||||
|
assert sl5 == HyList([])
|
||||||
|
|
||||||
|
|
||||||
|
hydict = HyDict(["a", 1, "b", 2, "c", 3])
|
||||||
|
|
||||||
|
|
||||||
|
def test_dict_items():
|
||||||
|
assert hydict.items() == [("a", 1), ("b", 2), ("c", 3)]
|
||||||
|
|
||||||
|
|
||||||
|
def test_dict_keys():
|
||||||
|
assert hydict.keys() == ["a", "b", "c"]
|
||||||
|
|
||||||
|
|
||||||
|
def test_dict_values():
|
||||||
|
assert hydict.values() == [1, 2, 3]
|
||||||
|
|
||||||
|
|
||||||
|
hyset = HySet([3, 1, 2, 2])
|
||||||
|
|
||||||
|
|
||||||
|
def test_set():
|
||||||
|
assert hyset == [3, 1, 2, 2]
|
||||||
|
|
||||||
|
|
||||||
|
def test_cons_slicing():
|
||||||
|
"""Check that cons slicing works as expected"""
|
||||||
|
cons = HyCons("car", "cdr")
|
||||||
|
assert cons[0] == "car"
|
||||||
|
assert cons[1:] == "cdr"
|
||||||
|
try:
|
||||||
|
cons[:]
|
||||||
|
assert True is False
|
||||||
|
except IndexError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
try:
|
||||||
|
cons[1]
|
||||||
|
assert True is False
|
||||||
|
except IndexError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
|
||||||
|
def test_cons_replacing():
|
||||||
|
"""Check that assigning to a cons works as expected"""
|
||||||
|
cons = HyCons("foo", "bar")
|
||||||
|
cons[0] = "car"
|
||||||
|
|
||||||
|
assert cons == HyCons("car", "bar")
|
||||||
|
|
||||||
|
cons[1:] = "cdr"
|
||||||
|
assert cons == HyCons("car", "cdr")
|
||||||
|
|
||||||
|
try:
|
||||||
|
cons[:] = "foo"
|
||||||
|
assert True is False
|
||||||
|
except IndexError:
|
||||||
|
pass
|
Loading…
Reference in New Issue
Block a user