Skip to content

Commit

Permalink
Adds raise from compilation
Browse files Browse the repository at this point in the history
  • Loading branch information
evhub committed Feb 1, 2016
1 parent dd24c90 commit 77a3363
Show file tree
Hide file tree
Showing 2 changed files with 25 additions and 8 deletions.
11 changes: 10 additions & 1 deletion DOCS.md
Original file line number Diff line number Diff line change
Expand Up @@ -138,7 +138,7 @@ While Coconut syntax is based off of Python 3, Coconut code compiled in universa

_Note: The tested against implementations are [CPython](https://www.python.org/) `2.6, 2.7, 3.2, 3.3, 3.4, 3.5` and [PyPy](http://pypy.org/) `2.7, 3.2`._

If the version of Python that the compiled code will be running on is known ahead of time, one of `2` (for the `2.x` branch) or `3` (for the `3.x` branch) should be specified as the `--target`. The given target will only affect the compiled code and whether or not Python-3-specific syntax is allowed. Where Python 3 and Python 2 syntax standards differ, Coconut syntax will always follow Python 3 accross all targets.
If the version of Python that the compiled code will be running on is known ahead of time, one of `2` (for the `2.x` branch) or `3` (for the `3.x` branch) should be specified as the `--target`. The given target will only affect the compiled code and whether or not certain Python-3-specific syntax is allowed, detailed below. Where Python 3 and Python 2 syntax standards differ, Coconut syntax will always follow Python 3 accross all targets.

As part of Coconut's cross-compatibility efforts, Coconut adds in new Python 3 built-ins and overwrites Python 2 built-ins to use the Python 3 versions where possible. If access to the Python 2 versions is desired, the old builtins can be retrieved by prefixing them with `py2_`. The old built-ins available are:
- `py2_filter`
Expand All @@ -155,6 +155,15 @@ As part of Coconut's cross-compatibility efforts, Coconut adds in new Python 3 b
- `py2_input`
- `py2_raw_input`

Finally, while Coconut will try to compile Python-3-specific syntax to its universal equivalent, the follow constructs have no equivalent in Python 2, and require `--target 3` to be specified to be used:
- destructuring assignment with `*`s (use Coconut pattern-matching instead)
- dictionary comprehension
- function type annotation
- the `nonlocal` keyword
- keyword class definition
- `@` as matrix multiplication (new in Python 3.5)
- `async` and `await` statements (new in Python 3.5)

### `--strict` Mode

If the `--strict` or `-s` flag is enabled, Coconut will throw errors on various style problems. These are:
Expand Down
22 changes: 15 additions & 7 deletions coconut/compiler.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
import_as_var = "_coconut_import"
yield_from_var = "_coconut_yield_from"
yield_item_var = "_coconut_yield_item"
raise_from_var = "_coconut_raise_from"
wildcard = "_"
keywords = (
"and",
Expand Down Expand Up @@ -1169,6 +1170,7 @@ def bind(self):
self.set_letter_literal_ref <<= self.trace(attach(self.set_letter_literal, self.set_letter_literal_convert), "set_letter_literal")
self.classlist_ref <<= self.trace(attach(self.classlist, self.classlist_repl), "classlist")
self.import_stmt_ref <<= self.trace(attach(self.import_stmt, self.import_repl), "import_stmt")
self.complex_raise_stmt_ref <<= self.trace(attach(self.complex_raise_stmt, self.complex_raise_stmt_repl), "complex_raise_stmt")
self.augassign_stmt_ref <<= attach(self.augassign_stmt, self.augassign_repl)
self.u_string_ref <<= attach(self.u_string, self.u_string_check)
self.typedef_ref <<= attach(self.typedef, self.typedef_check)
Expand All @@ -1183,7 +1185,6 @@ def bind(self):
self.async_match_funcdef_ref <<= attach(self.async_match_funcdef, self.async_stmt_check)
self.async_block_ref <<= attach(self.async_block, self.async_stmt_check)
self.await_keyword_ref <<= attach(self.await_keyword, self.await_keyword_check)
self.complex_raise_stmt_ref <<= attach(self.complex_raise_stmt, self.complex_raise_stmt_check)

def clean(self):
"""Resets references."""
Expand Down Expand Up @@ -1838,6 +1839,17 @@ def import_repl(self, original, location, tokens):
stmts.append(closeindent)
return "\n".join(stmts)

def complex_raise_stmt_repl(self, tokens):
"""Checks for Python 3 raise from statement."""
if len(tokens) != 2:
raise CoconutException("invalid raise from tokens", tokens)
elif self.version == "3":
return "raise " + tokens[0] + " from " + tokens[1]
else:
return (raise_from_var + " = " + tokens[0] + "\n"
+ raise_from_var + ".__cause__ = " + tokens[1] + "\n"
+ "raise " + raise_from_var)

def check_strict(self, name, original, location, tokens):
"""Checks that syntax meets --strict requirements."""
if len(tokens) != 1:
Expand Down Expand Up @@ -1892,10 +1904,6 @@ def await_keyword_check(self, original, location, tokens):
"""Checks for Python 3.5 await statement."""
return self.check_py3("Python 3.5 await expression", original, location, tokens)

def complex_raise_stmt_check(self, original, location, tokens):
"""Checks for Python 3 raise from statement."""
return self.check_py3("Python 3 raise from statement", original, location, tokens)

def set_literal_convert(self, tokens):
"""Converts set literals to the right form for the target Python."""
if len(tokens) != 1:
Expand Down Expand Up @@ -2306,8 +2314,8 @@ def parse(self, inputstring, parser, preargs, postargs):
continue_stmt = Keyword("continue")
return_stmt = addspace(Keyword("return") + Optional(testlist))
simple_raise_stmt = addspace(Keyword("raise") + Optional(test))
complex_raise_stmt = addspace(simple_raise_stmt + Keyword("from") + test)
raise_stmt = simple_raise_stmt | complex_raise_stmt_ref
complex_raise_stmt = Keyword("raise").suppress() + Optional(test) + Keyword("from").suppress() + test
raise_stmt = complex_raise_stmt_ref | simple_raise_stmt
flow_stmt = break_stmt | continue_stmt | return_stmt | raise_stmt | yield_expr

dotted_as_name = Group(dotted_name + Optional(Keyword("as").suppress() + name))
Expand Down

0 comments on commit 77a3363

Please sign in to comment.