Exemple #1
0
def for_macro(*tree):
    ret = None
    # for [x iter y iter] ...
    # ->
    # foreach x iter
    #   foreach y iter
    #     ...

    tree = HyExpression(tree).replace(tree[0])

    it = iter(tree.pop(0))
    blocks = list(zip(it, it))  # List for Python 3.x degenerating.

    key, val = blocks.pop(0)
    ret = HyExpression([HySymbol("foreach"),
                        HyList([key, val])])
    root = ret
    ret.replace(tree)

    for key, val in blocks:
        # x, [1, 2, 3,  4]
        nret = HyExpression([HySymbol("foreach"),
                             HyList([key, val])])
        nret.replace(key)
        ret.append(nret)
        ret = nret

    [ret.append(x) for x in tree]  # we really need ~@
    return root
Exemple #2
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
Exemple #3
0
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([])
def test_preprocessor_expression():
    """ Test inner macro expantion """
    obj = process(tokenize('(test (test "one" "two"))')[0])

    assert type(obj) == HyList
    assert type(obj[0]) == HyList

    assert obj[0] == HyList([HyString("one"), HyString("two")])

    obj = HyList([HyString("one"), HyString("two")])
    obj = tokenize('(shill ["one" "two"])')[0][1]
    assert obj == process(obj)
Exemple #5
0
def process(tree):
    if isinstance(tree, HyExpression):
        fn = tree[0]
        ntree = HyExpression([fn] + [process(x) for x in tree[1:]])
        ntree.replace(tree)

        if isinstance(fn, HyString):
            if fn in _hy_macros:
                m = _hy_macros[fn]
                obj = m(ntree)
                obj.replace(tree)
                return obj

        ntree.replace(tree)
        return ntree

    if isinstance(tree, HyDict):
        obj = HyDict(dict((process(x), process(tree[x])) for x in tree))
        obj.replace(tree)
        return obj

    if isinstance(tree, HyList):
        obj = HyList([process(x) for x in tree])  # NOQA
        # flake8 thinks we're redefining from 52.
        obj.replace(tree)
        return obj

    if isinstance(tree, list):
        return [process(x) for x in tree]

    return tree
Exemple #6
0
    def test_compiler_yield_return(self):
        """
        Check that the compiler correctly generates return statements for
        a generator function. In Python versions prior to 3.3, the return
        statement in a generator can't take a value, so the final expression
        should not generate a return statement. From 3.3 onwards a return
        value should be generated.
        """
        ret = self.c.compile_function_def(
            self._make_expression(HySymbol("fn"),
                                  HyList(),
                                  HyExpression([HySymbol("yield"),
                                                HyInteger(2)]),
                                  HyExpression([HySymbol("+"),
                                                HyInteger(1),
                                                HyInteger(1)])))

        self.assertEqual(len(ret.stmts), 1)
        stmt = ret.stmts[0]
        self.assertIsInstance(stmt, ast.FunctionDef)
        body = stmt.body
        self.assertEquals(len(body), 2)
        self.assertIsInstance(body[0], ast.Expr)
        self.assertIsInstance(body[0].value, ast.Yield)

        if PY33:
            # From 3.3+, the final statement becomes a return value
            self.assertIsInstance(body[1], ast.Return)
            self.assertIsInstance(body[1].value, ast.BinOp)
        else:
            # In earlier versions, the expression is not returned
            self.assertIsInstance(body[1], ast.Expr)
            self.assertIsInstance(body[1].value, ast.BinOp)
Exemple #7
0
def hy_compile(tree, root=None):
    " Compile a HyObject tree into a Python AST tree. "
    compiler = HyASTCompiler()
    tlo = root
    if root is None:
        tlo = ast.Module

    _ast = compiler.compile(tree)
    if type(_ast) == list:
        _ast = compiler._mangle_branch(_ast, 0, 0)

        if hasattr(sys, "subversion"):
            implementation = sys.subversion[0].lower()
        elif hasattr(sys, "implementation"):
            implementation = sys.implementation.name.lower()

        imports = []
        for package in compiler.imports:
            imported = set()
            syms = compiler.imports[package]
            for entry, form in syms:
                if entry in imported:
                    continue

                replace = form
                if implementation != "cpython":
                    # using form causes pypy to blow up; let's conditionally
                    # add this for cpython, since it won't go through and make
                    # sure the AST makes sense. Muhahaha. - PRT
                    replace = tree[0]

                imported.add(entry)
                imports.append(
                    HyExpression([
                        HySymbol("import"),
                        HyList([HySymbol(package),
                                HyList([HySymbol(entry)])])
                    ]).replace(replace))

        _ast = compiler.compile(imports) + _ast

    ret = tlo(body=_ast)
    return ret
Exemple #8
0
 def visit(self, tree):
     if isinstance(tree, HyExpression) and tree != []:
         call = tree[0]
         if call == "if" and self.should_hoist():
             # If we've got a hoistable if statement
             fn = HyExpression(
                 [HyExpression([HySymbol("fn"),
                                HyList([]), tree])])
             fn.replace(tree)
             return fn
Exemple #9
0
def test_cons_list():
    """Check that cons of something and a list gets tokenized as a list"""
    entry = tokenize("(a . [])")[0]
    assert entry == HyList([HySymbol("a")])
    assert type(entry) == HyList
    entry = tokenize("(a . ())")[0]
    assert entry == HyExpression([HySymbol("a")])
    assert type(entry) == HyExpression
    entry = tokenize("(a b . {})")[0]
    assert entry == HyDict([HySymbol("a"), HySymbol("b")])
    assert type(entry) == HyDict
Exemple #10
0
def let_macro(variables, *body):
    expr = HyExpression([HySymbol("fn"), HyList([])])

    for var in variables:
        if isinstance(var, list):
            expr.append(HyExpression([HySymbol("setf"), var[0], var[1]]))
        else:
            expr.append(HyExpression([HySymbol("setf"), var,
                                      HySymbol("None")]))

    return HyExpression([expr + list(body)])
Exemple #11
0
    def _render_quoted_form(self, form):
        name = form.__class__.__name__
        self.imports["hy"].append((name, form))

        if isinstance(form, HyList):
            return HyExpression([
                HySymbol(name),
                HyList([self._render_quoted_form(x) for x in form])
            ]).replace(form)
        elif isinstance(form, HySymbol):
            return HyExpression([HySymbol(name), HyString(form)]).replace(form)
        return HyExpression([HySymbol(name), form]).replace(form)
Exemple #12
0
def test_preprocessor_expression():
    """ Test that macro expansion doesn't recurse"""
    obj = macroexpand(tokenize('(test (test "one" "two"))')[0], __name__)

    assert type(obj) == HyList
    assert type(obj[0]) == HyExpression

    assert obj[0] == HyExpression([HySymbol("test"),
                                   HyString("one"),
                                   HyString("two")])

    obj = HyList([HyString("one"), HyString("two")])
    obj = tokenize('(shill ["one" "two"])')[0][1]
    assert obj == macroexpand(obj, '')
Exemple #13
0
def process(tree):
    if isinstance(tree, HyExpression):
        fn = tree[0]
        ntree = HyExpression([fn] + [process(x) for x in tree[1:]])

        if isinstance(fn, HyString):
            if fn in _hy_macros:
                m = _hy_macros[fn]
                obj = m(ntree)
                obj.replace(tree)
                return obj

        ntree.replace(tree)
        return ntree

    if isinstance(tree, HyList):
        obj = HyList([process(x) for x in tree])
        obj.replace(tree)
        return obj

    if isinstance(tree, list):
        return [process(x) for x in tree]

    return tree
Exemple #14
0
    def test_fn_compiler_empty_function(self):
        ret = self.c.compile_function_def(self._make_expression(
            "fn", HyList()))
        self.assertEqual(ret.imports, {})

        self.assertEqual(len(ret.stmts), 1)
        stmt = ret.stmts[0]
        self.assertIsInstance(stmt, ast.FunctionDef)
        self.assertIsInstance(stmt.args, ast.arguments)
        self.assertEqual(stmt.args.vararg, None)
        self.assertEqual(stmt.args.kwarg, None)
        self.assertEqual(stmt.args.defaults, [])
        self.assertEqual(stmt.decorator_list, [])
        self.assertEqual(len(stmt.body), 1)
        self.assertIsInstance(stmt.body[0], ast.Pass)

        self.assertIsInstance(ret.expr, ast.Name)
Exemple #15
0
def let_macro(tree):
    tree.pop(0)  # "let"
    variables = tree.pop(0)
    # tree is now the body
    expr = HyExpression([HySymbol("fn"), HyList([])])

    for var in variables:
        if isinstance(var, list):
            expr.append(HyExpression([HySymbol("setf"),
                                      var[0], var[1]]))
        else:
            expr.append(HyExpression([HySymbol("setf"),
                                      var, HySymbol("None")]))

    for stmt in tree:
        expr.append(stmt)

    return HyExpression([expr])
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)])
Exemple #17
0
    def compile_catch_expression(self, expr):
        catch = expr.pop(0)  # catch

        try:
            exceptions = expr.pop(0)
        except IndexError:
            exceptions = HyList()
        # exceptions catch should be either:
        # [[list of exceptions]]
        # or
        # [variable [list of exceptions]]
        # or
        # [variable exception]
        # or
        # [exception]
        # or
        # []
        if not isinstance(exceptions, HyList):
            raise HyTypeError(exceptions,
                              "`%s' exceptions list is not a list" % catch)
        if len(exceptions) > 2:
            raise HyTypeError(exceptions,
                              "`%s' exceptions list is too long" % catch)

        # [variable [list of exceptions]]
        # let's pop variable and use it as name
        if len(exceptions) == 2:
            name = exceptions.pop(0)
            if sys.version_info[0] >= 3:
                # Python3 features a change where the Exception handler
                # moved the name from a Name() to a pure Python String type.
                #
                # We'll just make sure it's a pure "string", and let it work
                # it's magic.
                name = ast_str(name)
            else:
                # Python2 requires an ast.Name, set to ctx Store.
                name = self._storeize(self.compile(name))
        else:
            name = None

        try:
            exceptions_list = exceptions.pop(0)
        except IndexError:
            exceptions_list = []

        if isinstance(exceptions_list, list):
            if len(exceptions_list):
                # [FooBar BarFoo] → catch Foobar and BarFoo exceptions
                _type = ast.Tuple(
                    elts=[self.compile(x) for x in exceptions_list],
                    lineno=expr.start_line,
                    col_offset=expr.start_column,
                    ctx=ast.Load())
            else:
                # [] → all exceptions catched
                _type = None
        elif isinstance(exceptions_list, HySymbol):
            _type = self.compile(exceptions_list)
        else:
            raise HyTypeError(exceptions,
                              "`%s' needs a valid exception list" % catch)

        body = self._code_branch([self.compile(x) for x in expr],
                                 expr.start_line, expr.start_column)

        return ast.ExceptHandler(lineno=expr.start_line,
                                 col_offset=expr.start_column,
                                 type=_type,
                                 name=name,
                                 body=body)
Exemple #18
0
def test_preprocessor_simple():
    """ Test basic macro expansion """
    obj = macroexpand(tokenize('(test "one" "two")')[0], __name__)
    assert obj == HyList(["one", "two"])
    assert type(obj) == HyList
Exemple #19
0
def tmac(*tree):
    """ Turn an expression into a list """
    return HyList(tree)
Exemple #20
0
def t_empty_list(p):
    return HyList([])
Exemple #21
0
    def compile_catch_expression(self, expr):
        catch = expr.pop(0)  # catch

        try:
            exceptions = expr.pop(0)
        except IndexError:
            exceptions = HyList()
        # exceptions catch should be either:
        # [[list of exceptions]]
        # or
        # [variable [list of exceptions]]
        # or
        # [variable exception]
        # or
        # [exception]
        # or
        # []
        if not isinstance(exceptions, HyList):
            raise HyTypeError(exceptions,
                              "`%s' exceptions list is not a list" % catch)
        if len(exceptions) > 2:
            raise HyTypeError(exceptions,
                              "`%s' exceptions list is too long" % catch)

        # [variable [list of exceptions]]
        # let's pop variable and use it as name
        if len(exceptions) == 2:
            name = exceptions.pop(0)
            if sys.version_info[0] >= 3:
                # Python3 features a change where the Exception handler
                # moved the name from a Name() to a pure Python String type.
                #
                # We'll just make sure it's a pure "string", and let it work
                # it's magic.
                name = ast_str(name)
            else:
                # Python2 requires an ast.Name, set to ctx Store.
                name = self._storeize(self.compile(name))
        else:
            name = None

        try:
            exceptions_list = exceptions.pop(0)
        except IndexError:
            exceptions_list = []

        if isinstance(exceptions_list, list):
            if len(exceptions_list):
                # [FooBar BarFoo] → catch Foobar and BarFoo exceptions
                _type = ast.Tuple(elts=[self.compile(x)
                                        for x in exceptions_list],
                                  lineno=expr.start_line,
                                  col_offset=expr.start_column,
                                  ctx=ast.Load())
            else:
                # [] → all exceptions catched
                _type = None
        elif isinstance(exceptions_list, HySymbol):
            _type = self.compile(exceptions_list)
        else:
            raise HyTypeError(exceptions,
                              "`%s' needs a valid exception list" % catch)

        body = self._code_branch([self.compile(x) for x in expr],
                                 expr.start_line,
                                 expr.start_column)

        return ast.ExceptHandler(
            lineno=expr.start_line,
            col_offset=expr.start_column,
            type=_type,
            name=name,
            body=body)
Exemple #22
0
    readers = _hy_reader[source_module]
    reader_refs = _hy_reader[target_module]
    for name, reader in readers.items():
        reader_refs[name] = reader


# type -> wrapping function mapping for _wrap_value
_wrappers = {
    int: HyInteger,
    bool: lambda x: HySymbol("True") if x else HySymbol("False"),
    float: HyFloat,
    complex: HyComplex,
    str_type: HyString,
    dict: lambda d: HyDict(_wrap_value(x) for x in sum(d.items(), ())),
    list: lambda l: HyList(_wrap_value(x) for x in l),
    tuple: lambda t: HyList(_wrap_value(x) for x in t),
    type(None): lambda foo: HySymbol("None"),
    HyExpression: lambda e: HyExpression(_wrap_value(x) for x in e),
}

if sys.version_info[0] < 3:  # do not add long on python3
    _wrappers[long_type] = HyInteger


def _wrap_value(x):
    """Wrap `x` into the corresponding Hy type.

    This allows a macro to return an unquoted expression transparently.

    """
Exemple #23
0
def t_list(p):
    return HyList(p[1])
Exemple #24
0
def get_route_macro(*tree):
    return router(tree, rkwargs=HyList([HyString("GET")]))
Exemple #25
0
def post_route_macro(*tree):
    return router(tree, rkwargs=HyList([HyString("POST")]))
Exemple #26
0
def test_list_add():
    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
Exemple #27
0
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)])
Exemple #28
0
def _wrap_value(x):
    wrapper = _wrappers.get(type(x))
    if wrapper is None:
        return x
    else:
        return wrapper(x)


_wrappers = {
    int: HyInteger,
    bool: lambda x: HySymbol("True") if x else HySymbol("False"),
    float: HyFloat,
    complex: HyComplex,
    str_type: HyString,
    dict: lambda d: HyDict(_wrap_value(x) for x in sum(d.items(), ())),
    list: lambda l: HyList(_wrap_value(x) for x in l)
}


def process(tree, module_name):
    if isinstance(tree, HyExpression):
        fn = tree[0]
        if fn in ("quote", "quasiquote"):
            return tree
        ntree = HyExpression([fn] +
                             [process(x, module_name) for x in tree[1:]])
        ntree.replace(tree)

        if isinstance(fn, HyString):
            m = _hy_macros[module_name].get(fn)
            if m is None: