Unify illegal special forms
This commit is contained in:
parent
45e8783997
commit
57b5fa49b1
@ -62,12 +62,6 @@ def load_stdlib():
|
|||||||
_stdlib[e] = module
|
_stdlib[e] = module
|
||||||
|
|
||||||
|
|
||||||
_compile_table = {}
|
|
||||||
_decoratables = (ast.FunctionDef, ast.ClassDef)
|
|
||||||
if PY35:
|
|
||||||
_decoratables += (ast.AsyncFunctionDef,)
|
|
||||||
|
|
||||||
|
|
||||||
def ast_str(x, piecewise=False):
|
def ast_str(x, piecewise=False):
|
||||||
if piecewise:
|
if piecewise:
|
||||||
return ".".join(ast_str(s) if s else "" for s in x.split("."))
|
return ".".join(ast_str(s) if s else "" for s in x.split("."))
|
||||||
@ -75,6 +69,17 @@ def ast_str(x, piecewise=False):
|
|||||||
return x if PY3 else x.encode('UTF8')
|
return x if PY3 else x.encode('UTF8')
|
||||||
|
|
||||||
|
|
||||||
|
_compile_table = {}
|
||||||
|
_decoratables = (ast.FunctionDef, ast.ClassDef)
|
||||||
|
if PY35:
|
||||||
|
_decoratables += (ast.AsyncFunctionDef,)
|
||||||
|
# _bad_roots are fake special operators, which are used internally
|
||||||
|
# by other special forms (e.g., `except` in `try`) but can't be
|
||||||
|
# used to construct special forms themselves.
|
||||||
|
_bad_roots = tuple(ast_str(x) for x in (
|
||||||
|
"unquote", "unquote-splice", "unpack-mapping", "except"))
|
||||||
|
|
||||||
|
|
||||||
def builds(*types, **kwargs):
|
def builds(*types, **kwargs):
|
||||||
# A decorator that adds the decorated method to _compile_table for
|
# A decorator that adds the decorated method to _compile_table for
|
||||||
# compiling `types`, but only if kwargs['iff'] (if provided) is
|
# compiling `types`, but only if kwargs['iff'] (if provided) is
|
||||||
@ -433,6 +438,9 @@ class HyASTCompiler(object):
|
|||||||
def compile_atom(self, atom_type, atom):
|
def compile_atom(self, atom_type, atom):
|
||||||
if isinstance(atom_type, string_types):
|
if isinstance(atom_type, string_types):
|
||||||
atom_type = ast_str(atom_type)
|
atom_type = ast_str(atom_type)
|
||||||
|
if atom_type in _bad_roots:
|
||||||
|
raise HyTypeError(atom, "The special form '{}' "
|
||||||
|
"is not allowed here".format(atom_type))
|
||||||
if atom_type in _compile_table:
|
if atom_type in _compile_table:
|
||||||
# _compile_table[atom_type] is a method for compiling this
|
# _compile_table[atom_type] is a method for compiling this
|
||||||
# type of atom, so call it. If it has an extra parameter,
|
# type of atom, so call it. If it has an extra parameter,
|
||||||
@ -672,11 +680,6 @@ class HyASTCompiler(object):
|
|||||||
ret.add_imports("hy", imports)
|
ret.add_imports("hy", imports)
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@builds("unquote", "unquote-splice")
|
|
||||||
def compile_unquote(self, expr):
|
|
||||||
raise HyTypeError(expr,
|
|
||||||
"`%s' can't be used at the top-level" % expr[0])
|
|
||||||
|
|
||||||
@special("unpack-iterable", [FORM])
|
@special("unpack-iterable", [FORM])
|
||||||
def compile_unpack_iterable(self, expr, root, arg):
|
def compile_unpack_iterable(self, expr, root, arg):
|
||||||
if not PY3:
|
if not PY3:
|
||||||
@ -685,10 +688,6 @@ class HyASTCompiler(object):
|
|||||||
ret += asty.Starred(expr, value=ret.force_expr, ctx=ast.Load())
|
ret += asty.Starred(expr, value=ret.force_expr, ctx=ast.Load())
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
@builds("unpack-mapping")
|
|
||||||
def compile_unpack_mapping(self, expr):
|
|
||||||
raise HyTypeError(expr, "`unpack-mapping` isn't allowed here")
|
|
||||||
|
|
||||||
@special([(not PY3, "exec*")], [FORM, maybe(FORM), maybe(FORM)])
|
@special([(not PY3, "exec*")], [FORM, maybe(FORM), maybe(FORM)])
|
||||||
# Under Python 3, `exec` is a function rather than a statement type, so Hy
|
# Under Python 3, `exec` is a function rather than a statement type, so Hy
|
||||||
# doesn't need a special form for it.
|
# doesn't need a special form for it.
|
||||||
@ -804,11 +803,6 @@ class HyASTCompiler(object):
|
|||||||
expr, body=body, handlers=handlers, orelse=orelse)
|
expr, body=body, handlers=handlers, orelse=orelse)
|
||||||
return handler_results + x + returnable
|
return handler_results + x + returnable
|
||||||
|
|
||||||
@builds("except")
|
|
||||||
def magic_internal_form(self, expr):
|
|
||||||
raise HyTypeError(expr,
|
|
||||||
"Error: `%s' can't be used like that." % (expr[0]))
|
|
||||||
|
|
||||||
def _compile_catch_expression(self, expr, var, exceptions, body):
|
def _compile_catch_expression(self, expr, var, exceptions, body):
|
||||||
# exceptions catch should be either:
|
# exceptions catch should be either:
|
||||||
# [[list of exceptions]]
|
# [[list of exceptions]]
|
||||||
|
@ -585,11 +585,11 @@ def test_setv_builtins():
|
|||||||
def test_top_level_unquote():
|
def test_top_level_unquote():
|
||||||
with pytest.raises(HyTypeError) as excinfo:
|
with pytest.raises(HyTypeError) as excinfo:
|
||||||
can_compile("(unquote)")
|
can_compile("(unquote)")
|
||||||
assert excinfo.value.message == "`unquote' can't be used at the top-level"
|
assert excinfo.value.message == "The special form 'unquote' is not allowed here"
|
||||||
|
|
||||||
with pytest.raises(HyTypeError) as excinfo:
|
with pytest.raises(HyTypeError) as excinfo:
|
||||||
can_compile("(unquote-splice)")
|
can_compile("(unquote-splice)")
|
||||||
assert excinfo.value.message == "`unquote-splice' can't be used at the top-level"
|
assert excinfo.value.message == "The special form 'unquote-splice' is not allowed here"
|
||||||
|
|
||||||
|
|
||||||
def test_lots_of_comment_lines():
|
def test_lots_of_comment_lines():
|
||||||
|
Loading…
Reference in New Issue
Block a user