diff --git a/numba_rvsdg-demo.ipynb b/numba_rvsdg-demo.ipynb index daf3ca6..a00d86c 100644 --- a/numba_rvsdg-demo.ipynb +++ b/numba_rvsdg-demo.ipynb @@ -18,6 +18,18 @@ "The code in this demo is a faithful implementation of the Algorithms described in `Bahmann2015` -- https://dl.acm.org/doi/pdf/10.1145/2693261" ] }, + { + "cell_type": "markdown", + "id": "a3ea9c10-af0c-472e-8efd-ff5b4db60b14", + "metadata": {}, + "source": [ + "## Motiviation\n", + "\n", + "* Abstract away control flow\n", + "* Make it easier for compilers to optimize\n", + "* Beginning of a source frontend for Numba" + ] + }, { "cell_type": "markdown", "id": "dbcd23bd-917c-4778-85d3-4d0aca647a86", @@ -112,8 +124,9 @@ "def compile_ast(ast_):\n", " \"\"\"Custom `compile` function via `exec`. \"\"\"\n", " exec_locals = {}\n", + " name = ast_.name\n", " exec(ast.unparse(ast_), {}, exec_locals)\n", - " transformed = exec_locals[\"transformed_function\"]\n", + " transformed = exec_locals[name]\n", " return transformed\n", "\n", "# https://github.com/ipython/ipython/issues/11747#issuecomment-528694702\n", @@ -151,7 +164,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 2, "id": "ad7ed127-8784-4eaf-a9c2-f66a6701e996", "metadata": { "editable": true, @@ -162,7 +175,7 @@ }, "outputs": [], "source": [ - "def branch(b: int):\n", + "def branch(b: int) -> int:\n", " if b:\n", " r = 1\n", " else:\n", @@ -172,7 +185,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 3, "id": "77aacace-1738-491e-be24-3266bfc077d5", "metadata": { "editable": true, @@ -188,7 +201,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 4, "id": "50495ec4-38c5-424e-ac0d-426069c28758", "metadata": { "editable": true, @@ -302,7 +315,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 5, "id": "3db30dd3-d79c-4ff3-aad7-4026466267ce", "metadata": { "editable": true, @@ -318,7 +331,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 6, "id": "a81b68d8-70c8-4e97-a304-921eb28644c3", "metadata": { "editable": true, @@ -457,7 +470,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 7, "id": "00dd7c03-f84f-424c-9a5d-3f8ab9a656da", "metadata": {}, "outputs": [ @@ -611,7 +624,7 @@ ".jp-RenderedHTML .vg { color: #19177C } /* Name.Variable.Global */\n", ".jp-RenderedHTML .vi { color: #19177C } /* Name.Variable.Instance */\n", ".jp-RenderedHTML .vm { color: #19177C } /* Name.Variable.Magic */\n", - ".jp-RenderedHTML .il { color: #666666 } /* Literal.Number.Integer.Long */
def transformed_function(b: int):\n",
+ ".jp-RenderedHTML .il { color: #666666 } /* Literal.Number.Integer.Long */def transformed_branch(b: int) -> int:\n",
" if b:\n",
" r = 1\n",
" else:\n",
@@ -621,7 +634,7 @@
],
"text/latex": [
"\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
- "\\PY{k}{def} \\PY{n+nf}{transformed\\PYZus{}function}\\PY{p}{(}\\PY{n}{b}\\PY{p}{:} \\PY{n+nb}{int}\\PY{p}{)}\\PY{p}{:}\n",
+ "\\PY{k}{def} \\PY{n+nf}{transformed\\PYZus{}branch}\\PY{p}{(}\\PY{n}{b}\\PY{p}{:} \\PY{n+nb}{int}\\PY{p}{)} \\PY{o}{\\PYZhy{}}\\PY{o}{\\PYZgt{}} \\PY{n+nb}{int}\\PY{p}{:}\n",
" \\PY{k}{if} \\PY{n}{b}\\PY{p}{:}\n",
" \\PY{n}{r} \\PY{o}{=} \\PY{l+m+mi}{1}\n",
" \\PY{k}{else}\\PY{p}{:}\n",
@@ -630,7 +643,7 @@
"\\end{Verbatim}\n"
],
"text/plain": [
- "def transformed_function(b: int):\n",
+ "def transformed_branch(b: int) -> int:\n",
" if b:\n",
" r = 1\n",
" else:\n",
@@ -638,7 +651,7 @@
" return r"
]
},
- "execution_count": 8,
+ "execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
@@ -651,7 +664,7 @@
},
{
"cell_type": "code",
- "execution_count": 9,
+ "execution_count": 8,
"id": "153d97ed-1588-4b84-9087-293ce749cd1b",
"metadata": {},
"outputs": [
@@ -661,7 +674,7 @@
"(2, 1)"
]
},
- "execution_count": 9,
+ "execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
@@ -689,12 +702,12 @@
},
{
"cell_type": "code",
- "execution_count": 10,
+ "execution_count": 9,
"id": "c180fa36-d6fc-4b55-8534-384cbbb2ceee",
"metadata": {},
"outputs": [],
"source": [
- "def multi_return(b: int):\n",
+ "def multi_return(b: int) -> int:\n",
" if b:\n",
" return 1\n",
" else:\n",
@@ -703,7 +716,7 @@
},
{
"cell_type": "code",
- "execution_count": 11,
+ "execution_count": 10,
"id": "263882ae-4929-4619-99d1-6e5af8081f77",
"metadata": {},
"outputs": [],
@@ -713,7 +726,7 @@
},
{
"cell_type": "code",
- "execution_count": 12,
+ "execution_count": 11,
"id": "a7e1aa87-d0cd-4ca7-90c7-311d4d9065b9",
"metadata": {},
"outputs": [
@@ -797,12 +810,12 @@
"id": "ce5c9a8b-5285-476b-82d5-6e5b7ac76988",
"metadata": {},
"source": [
- "## Close CFG: restructure"
+ "## Close CFG: Restructure"
]
},
{
"cell_type": "code",
- "execution_count": 13,
+ "execution_count": 12,
"id": "4206ca5e-263b-4bfe-946f-658e8fea917c",
"metadata": {},
"outputs": [],
@@ -812,7 +825,7 @@
},
{
"cell_type": "code",
- "execution_count": 14,
+ "execution_count": 13,
"id": "0a132a5d-988c-4def-a21a-05380d90d9b8",
"metadata": {},
"outputs": [
@@ -944,7 +957,7 @@
},
{
"cell_type": "code",
- "execution_count": 15,
+ "execution_count": 14,
"id": "57b3ec44-f98c-4c13-9c86-29bd574afa25",
"metadata": {},
"outputs": [
@@ -1098,7 +1111,7 @@
".jp-RenderedHTML .vg { color: #19177C } /* Name.Variable.Global */\n",
".jp-RenderedHTML .vi { color: #19177C } /* Name.Variable.Instance */\n",
".jp-RenderedHTML .vm { color: #19177C } /* Name.Variable.Magic */\n",
- ".jp-RenderedHTML .il { color: #666666 } /* Literal.Number.Integer.Long */def transformed_function(b: int):\n",
+ ".jp-RenderedHTML .il { color: #666666 } /* Literal.Number.Integer.Long */def transformed_multi_return(b: int) -> int:\n",
" if b:\n",
" __scfg_return_value__ = 1\n",
" else:\n",
@@ -1108,7 +1121,7 @@
],
"text/latex": [
"\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
- "\\PY{k}{def} \\PY{n+nf}{transformed\\PYZus{}function}\\PY{p}{(}\\PY{n}{b}\\PY{p}{:} \\PY{n+nb}{int}\\PY{p}{)}\\PY{p}{:}\n",
+ "\\PY{k}{def} \\PY{n+nf}{transformed\\PYZus{}multi\\PYZus{}return}\\PY{p}{(}\\PY{n}{b}\\PY{p}{:} \\PY{n+nb}{int}\\PY{p}{)} \\PY{o}{\\PYZhy{}}\\PY{o}{\\PYZgt{}} \\PY{n+nb}{int}\\PY{p}{:}\n",
" \\PY{k}{if} \\PY{n}{b}\\PY{p}{:}\n",
" \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}return\\PYZus{}value\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{l+m+mi}{1}\n",
" \\PY{k}{else}\\PY{p}{:}\n",
@@ -1117,7 +1130,7 @@
"\\end{Verbatim}\n"
],
"text/plain": [
- "def transformed_function(b: int):\n",
+ "def transformed_multi_return(b: int) -> int:\n",
" if b:\n",
" __scfg_return_value__ = 1\n",
" else:\n",
@@ -1125,7 +1138,7 @@
" return __scfg_return_value__"
]
},
- "execution_count": 15,
+ "execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
@@ -1138,7 +1151,7 @@
},
{
"cell_type": "code",
- "execution_count": 16,
+ "execution_count": 15,
"id": "34b97f2e-8131-4e65-b66f-5ae540ce38cc",
"metadata": {},
"outputs": [
@@ -1148,7 +1161,7 @@
"(2, 1)"
]
},
- "execution_count": 16,
+ "execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
@@ -1184,7 +1197,7 @@
},
{
"cell_type": "code",
- "execution_count": 17,
+ "execution_count": 16,
"id": "1ddb14d9-56f1-4f6c-b1e2-6fdde2942b3b",
"metadata": {},
"outputs": [],
@@ -1198,7 +1211,7 @@
},
{
"cell_type": "code",
- "execution_count": 18,
+ "execution_count": 17,
"id": "af9bbca7-03bb-4fb1-aecf-393e9bb62846",
"metadata": {},
"outputs": [],
@@ -1208,7 +1221,7 @@
},
{
"cell_type": "code",
- "execution_count": 19,
+ "execution_count": 18,
"id": "e72cc9eb-819e-4741-9e36-179692886c44",
"metadata": {},
"outputs": [
@@ -1305,12 +1318,12 @@
"id": "7293cab2-1722-4666-a898-fc8e4e264a18",
"metadata": {},
"source": [
- "## Loop Restructure: restructure"
+ "## Loop Restructure: Restructure"
]
},
{
"cell_type": "code",
- "execution_count": 20,
+ "execution_count": 19,
"id": "973e662a-1462-4c87-ac7e-cdebe2c60b41",
"metadata": {},
"outputs": [],
@@ -1320,7 +1333,7 @@
},
{
"cell_type": "code",
- "execution_count": 21,
+ "execution_count": 20,
"id": "1c6cc6b2-84a9-4b85-90ec-fb79af75bad3",
"metadata": {},
"outputs": [
@@ -1511,7 +1524,7 @@
},
{
"cell_type": "code",
- "execution_count": 22,
+ "execution_count": 21,
"id": "c5c4375a-541f-4c3b-9368-38210c10cdd5",
"metadata": {},
"outputs": [
@@ -1665,7 +1678,7 @@
".jp-RenderedHTML .vg { color: #19177C } /* Name.Variable.Global */\n",
".jp-RenderedHTML .vi { color: #19177C } /* Name.Variable.Instance */\n",
".jp-RenderedHTML .vm { color: #19177C } /* Name.Variable.Magic */\n",
- ".jp-RenderedHTML .il { color: #666666 } /* Literal.Number.Integer.Long */def transformed_function():\n",
+ ".jp-RenderedHTML .il { color: #666666 } /* Literal.Number.Integer.Long */def transformed_while_loop():\n",
" c = 0\n",
" __scfg_loop_cont__ = True\n",
" while __scfg_loop_cont__:\n",
@@ -1680,7 +1693,7 @@
],
"text/latex": [
"\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
- "\\PY{k}{def} \\PY{n+nf}{transformed\\PYZus{}function}\\PY{p}{(}\\PY{p}{)}\\PY{p}{:}\n",
+ "\\PY{k}{def} \\PY{n+nf}{transformed\\PYZus{}while\\PYZus{}loop}\\PY{p}{(}\\PY{p}{)}\\PY{p}{:}\n",
" \\PY{n}{c} \\PY{o}{=} \\PY{l+m+mi}{0}\n",
" \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}loop\\PYZus{}cont\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{k+kc}{True}\n",
" \\PY{k}{while} \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}loop\\PYZus{}cont\\PYZus{}\\PYZus{}}\\PY{p}{:}\n",
@@ -1694,7 +1707,7 @@
"\\end{Verbatim}\n"
],
"text/plain": [
- "def transformed_function():\n",
+ "def transformed_while_loop():\n",
" c = 0\n",
" __scfg_loop_cont__ = True\n",
" while __scfg_loop_cont__:\n",
@@ -1707,7 +1720,7 @@
" return c"
]
},
- "execution_count": 22,
+ "execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
@@ -1731,14 +1744,14 @@
"id": "249d5667-db9a-4dc3-86a4-5a5ce9189fcf",
"metadata": {},
"source": [
- "## Early Exit: example and CFG\n",
+ "## Early Exit: Example and CFG\n",
"\n",
"Things become more interesting, when the loop contains early exits:"
]
},
{
"cell_type": "code",
- "execution_count": 23,
+ "execution_count": 22,
"id": "93f8e8d3-839a-4fbb-b209-da6425fcb5cf",
"metadata": {},
"outputs": [],
@@ -1754,7 +1767,7 @@
},
{
"cell_type": "code",
- "execution_count": 24,
+ "execution_count": 23,
"id": "4dbf537f-b67d-4203-947f-9ba669eb8edb",
"metadata": {},
"outputs": [],
@@ -1764,7 +1777,7 @@
},
{
"cell_type": "code",
- "execution_count": 25,
+ "execution_count": 24,
"id": "8e3bd9f6-0b15-402f-b7d2-7233bcf881dc",
"metadata": {},
"outputs": [
@@ -1875,12 +1888,12 @@
"id": "4dd81694-0b0e-4434-baaf-62a7d037851b",
"metadata": {},
"source": [
- "## Early Exit: restructure"
+ "## Early Exit: Restructure"
]
},
{
"cell_type": "code",
- "execution_count": 26,
+ "execution_count": 25,
"id": "1fce9b69-084c-4b52-94fc-699cb28f3549",
"metadata": {},
"outputs": [],
@@ -1890,7 +1903,7 @@
},
{
"cell_type": "code",
- "execution_count": 27,
+ "execution_count": 26,
"id": "0446d173-eafd-448e-a163-ec6ba7c55784",
"metadata": {
"editable": true,
@@ -2212,7 +2225,7 @@
},
{
"cell_type": "code",
- "execution_count": 28,
+ "execution_count": 27,
"id": "9a122ad2-1eec-41c8-8fa2-ab0500ba9dfb",
"metadata": {},
"outputs": [
@@ -2366,7 +2379,7 @@
".jp-RenderedHTML .vg { color: #19177C } /* Name.Variable.Global */\n",
".jp-RenderedHTML .vi { color: #19177C } /* Name.Variable.Instance */\n",
".jp-RenderedHTML .vm { color: #19177C } /* Name.Variable.Magic */\n",
- ".jp-RenderedHTML .il { color: #666666 } /* Literal.Number.Integer.Long */def transformed_function(a: int):\n",
+ ".jp-RenderedHTML .il { color: #666666 } /* Literal.Number.Integer.Long */def transformed_while_loop_with_exit(a: int):\n",
" c = 0\n",
" __scfg_loop_cont__ = True\n",
" while __scfg_loop_cont__:\n",
@@ -2391,7 +2404,7 @@
],
"text/latex": [
"\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
- "\\PY{k}{def} \\PY{n+nf}{transformed\\PYZus{}function}\\PY{p}{(}\\PY{n}{a}\\PY{p}{:} \\PY{n+nb}{int}\\PY{p}{)}\\PY{p}{:}\n",
+ "\\PY{k}{def} \\PY{n+nf}{transformed\\PYZus{}while\\PYZus{}loop\\PYZus{}with\\PYZus{}exit}\\PY{p}{(}\\PY{n}{a}\\PY{p}{:} \\PY{n+nb}{int}\\PY{p}{)}\\PY{p}{:}\n",
" \\PY{n}{c} \\PY{o}{=} \\PY{l+m+mi}{0}\n",
" \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}loop\\PYZus{}cont\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{k+kc}{True}\n",
" \\PY{k}{while} \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}loop\\PYZus{}cont\\PYZus{}\\PYZus{}}\\PY{p}{:}\n",
@@ -2415,7 +2428,7 @@
"\\end{Verbatim}\n"
],
"text/plain": [
- "def transformed_function(a: int):\n",
+ "def transformed_while_loop_with_exit(a: int):\n",
" c = 0\n",
" __scfg_loop_cont__ = True\n",
" while __scfg_loop_cont__:\n",
@@ -2438,7 +2451,7 @@
" return __scfg_return_value__"
]
},
- "execution_count": 28,
+ "execution_count": 27,
"metadata": {},
"output_type": "execute_result"
}
@@ -2454,7 +2467,7 @@
"id": "5aa6893a-c5d5-48c9-a159-4120faf9532b",
"metadata": {},
"source": [
- "## For Loop: Example and CFG"
+ "## For-Loop: Example and CFG"
]
},
{
@@ -2472,21 +2485,21 @@
},
{
"cell_type": "code",
- "execution_count": 29,
+ "execution_count": 28,
"id": "87867a02-0b9d-46e2-85de-55de473f3c64",
"metadata": {},
"outputs": [],
"source": [
- "def for_loop():\n",
- " c = 0\n",
- " for i in range(10):\n",
- " c += i\n",
- " return c"
+ " def for_loop():\n",
+ " c = 0\n",
+ " for i in range(10):\n",
+ " c += i\n",
+ " return c"
]
},
{
"cell_type": "code",
- "execution_count": 30,
+ "execution_count": 29,
"id": "5384e244-bdbc-4214-8a6e-aa2b47315bce",
"metadata": {},
"outputs": [],
@@ -2496,7 +2509,7 @@
},
{
"cell_type": "code",
- "execution_count": 31,
+ "execution_count": 30,
"id": "f59b20e0-5f6e-4161-a202-60e3c8e9d3ae",
"metadata": {
"scrolled": true
@@ -2613,12 +2626,12 @@
"id": "6facab03-2901-4bb8-b3a2-c130a4892206",
"metadata": {},
"source": [
- "## For-loop: restructure"
+ "## For-Loop: Restructure"
]
},
{
"cell_type": "code",
- "execution_count": 32,
+ "execution_count": 31,
"id": "4a7c99b6-6bbd-43b4-9a0f-d123839c6222",
"metadata": {},
"outputs": [],
@@ -2627,194 +2640,9 @@
]
},
{
- "cell_type": "code",
- "execution_count": 33,
- "id": "6f9a2e02-1f70-4f97-8c98-12d1c574deb6",
+ "cell_type": "markdown",
+ "id": "26e4e14f-242a-48bd-9142-1e74c2008bfb",
"metadata": {},
- "outputs": [
- {
- "data": {
- "text/html": [
- "\n",
- " \n",
- " \n",
- "\n",
- "\n",
- "\n",
- "\n",
- "\n",
- " \n",
- " "
- ],
- "text/plain": [
- ""
- ]
- },
- "metadata": {},
- "output_type": "display_data"
- }
- ],
"source": [
"render_scfg_info_notebook_center(scfg)"
]
@@ -2824,12 +2652,12 @@
"id": "6ae72138-16cd-496a-b52a-c46a41f7b3bb",
"metadata": {},
"source": [
- "## For-loop: Python synthesis"
+ "## For-loop: Python Synthesis"
]
},
{
"cell_type": "code",
- "execution_count": 34,
+ "execution_count": 32,
"id": "2bdd6e26-d4af-4630-b6b0-e8f324e14733",
"metadata": {},
"outputs": [
@@ -2983,7 +2811,7 @@
".jp-RenderedHTML .vg { color: #19177C } /* Name.Variable.Global */\n",
".jp-RenderedHTML .vi { color: #19177C } /* Name.Variable.Instance */\n",
".jp-RenderedHTML .vm { color: #19177C } /* Name.Variable.Magic */\n",
- ".jp-RenderedHTML .il { color: #666666 } /* Literal.Number.Integer.Long */def transformed_function():\n",
+ ".jp-RenderedHTML .il { color: #666666 } /* Literal.Number.Integer.Long */def transformed_for_loop():\n",
" c = 0\n",
" __scfg_iterator_1__ = iter(range(10))\n",
" i = None\n",
@@ -3003,7 +2831,7 @@
],
"text/latex": [
"\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
- "\\PY{k}{def} \\PY{n+nf}{transformed\\PYZus{}function}\\PY{p}{(}\\PY{p}{)}\\PY{p}{:}\n",
+ "\\PY{k}{def} \\PY{n+nf}{transformed\\PYZus{}for\\PYZus{}loop}\\PY{p}{(}\\PY{p}{)}\\PY{p}{:}\n",
" \\PY{n}{c} \\PY{o}{=} \\PY{l+m+mi}{0}\n",
" \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}iterator\\PYZus{}1\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{n+nb}{iter}\\PY{p}{(}\\PY{n+nb}{range}\\PY{p}{(}\\PY{l+m+mi}{10}\\PY{p}{)}\\PY{p}{)}\n",
" \\PY{n}{i} \\PY{o}{=} \\PY{k+kc}{None}\n",
@@ -3022,7 +2850,7 @@
"\\end{Verbatim}\n"
],
"text/plain": [
- "def transformed_function():\n",
+ "def transformed_for_loop():\n",
" c = 0\n",
" __scfg_iterator_1__ = iter(range(10))\n",
" i = None\n",
@@ -3040,7 +2868,7 @@
" return c"
]
},
- "execution_count": 34,
+ "execution_count": 32,
"metadata": {},
"output_type": "execute_result"
}
@@ -3053,12 +2881,1035 @@
},
{
"cell_type": "markdown",
- "id": "9cec4807-fc8d-4b82-b96d-cce226f968bc",
+ "id": "7712e672-6556-4ee8-a019-8ef300bc527b",
"metadata": {},
"source": [
- "TODO\n",
- "* break and continue elimination\n",
- "* if-cascade\n",
+ "## Break and Continue: Example and CFG"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 33,
+ "id": "e241526b-b064-487f-abdc-0672c30686da",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "def break_and_continue(x: int, y: int) -> int:\n",
+ " for i in range(2):\n",
+ " if i == x:\n",
+ " i = 3\n",
+ " return i + 100\n",
+ " elif i == y:\n",
+ " i = 4\n",
+ " break\n",
+ " else:\n",
+ " continue\n",
+ " return i"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 34,
+ "id": "18aae927-21d8-4dc0-a753-39c8c23b8f7d",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "scfg = AST2SCFGTransformer(break_and_continue).transform_to_SCFG()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 35,
+ "id": "553a0fd2-3e39-4bc7-b837-f99cdd7bf3ed",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ " \n",
+ " \n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ " \n",
+ " "
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "render_scfg_info_notebook_center(scfg)"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "e54b25c2-265a-48d8-b140-d67c30e8e6dd",
+ "metadata": {},
+ "source": [
+ "## Break and Continue: restructure"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 36,
+ "id": "0c892380-af7d-4948-b9fd-3443130ee723",
+ "metadata": {},
+ "outputs": [],
+ "source": [
+ "scfg.restructure()"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 37,
+ "id": "e5d114c0-5964-4e68-82f9-cfd541ee2445",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "\n",
+ " \n",
+ " \n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ "\n",
+ " \n",
+ " "
+ ],
+ "text/plain": [
+ ""
+ ]
+ },
+ "metadata": {},
+ "output_type": "display_data"
+ }
+ ],
+ "source": [
+ "render_scfg_info_notebook_center(scfg)"
+ ]
+ },
+ {
+ "cell_type": "code",
+ "execution_count": 38,
+ "id": "a191a2ca-bc9a-4382-9242-12215de3840c",
+ "metadata": {},
+ "outputs": [
+ {
+ "data": {
+ "text/html": [
+ "def transformed_break_and_continue(x: int, y: int) -> int:\n",
+ " __scfg_iterator_1__ = iter(range(2))\n",
+ " i = None\n",
+ " __scfg_loop_cont__ = True\n",
+ " while __scfg_loop_cont__:\n",
+ " __scfg_iter_last_1__ = i\n",
+ " i = next(__scfg_iterator_1__, '__scfg_sentinel__')\n",
+ " if i != '__scfg_sentinel__':\n",
+ " if i == x:\n",
+ " __scfg_exit_var_0__ = 1\n",
+ " __scfg_backedge_var_0__ = 1\n",
+ " elif i == y:\n",
+ " __scfg_exit_var_0__ = 2\n",
+ " __scfg_backedge_var_0__ = 1\n",
+ " else:\n",
+ " __scfg_backedge_var_0__ = 0\n",
+ " __scfg_exit_var_0__ = -1\n",
+ " else:\n",
+ " __scfg_exit_var_0__ = 0\n",
+ " __scfg_backedge_var_0__ = 1\n",
+ " __scfg_loop_cont__ = not __scfg_backedge_var_0__\n",
+ " if __scfg_exit_var_0__ in (0,):\n",
+ " i = __scfg_iter_last_1__\n",
+ " __scfg_control_var_0__ = 0\n",
+ " elif __scfg_exit_var_0__ in (1,):\n",
+ " i = 3\n",
+ " __scfg_return_value__ = i + 100\n",
+ " __scfg_control_var_0__ = 1\n",
+ " else:\n",
+ " i = 4\n",
+ " __scfg_control_var_0__ = 2\n",
+ " if __scfg_control_var_0__ in (0, 2):\n",
+ " __scfg_return_value__ = i\n",
+ " else:\n",
+ " pass\n",
+ " return __scfg_return_value__\n",
+ "
\n"
+ ],
+ "text/latex": [
+ "\\begin{Verbatim}[commandchars=\\\\\\{\\}]\n",
+ "\\PY{k}{def} \\PY{n+nf}{transformed\\PYZus{}break\\PYZus{}and\\PYZus{}continue}\\PY{p}{(}\\PY{n}{x}\\PY{p}{:} \\PY{n+nb}{int}\\PY{p}{,} \\PY{n}{y}\\PY{p}{:} \\PY{n+nb}{int}\\PY{p}{)} \\PY{o}{\\PYZhy{}}\\PY{o}{\\PYZgt{}} \\PY{n+nb}{int}\\PY{p}{:}\n",
+ " \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}iterator\\PYZus{}1\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{n+nb}{iter}\\PY{p}{(}\\PY{n+nb}{range}\\PY{p}{(}\\PY{l+m+mi}{2}\\PY{p}{)}\\PY{p}{)}\n",
+ " \\PY{n}{i} \\PY{o}{=} \\PY{k+kc}{None}\n",
+ " \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}loop\\PYZus{}cont\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{k+kc}{True}\n",
+ " \\PY{k}{while} \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}loop\\PYZus{}cont\\PYZus{}\\PYZus{}}\\PY{p}{:}\n",
+ " \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}iter\\PYZus{}last\\PYZus{}1\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{n}{i}\n",
+ " \\PY{n}{i} \\PY{o}{=} \\PY{n+nb}{next}\\PY{p}{(}\\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}iterator\\PYZus{}1\\PYZus{}\\PYZus{}}\\PY{p}{,} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{\\PYZus{}\\PYZus{}scfg\\PYZus{}sentinel\\PYZus{}\\PYZus{}}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{)}\n",
+ " \\PY{k}{if} \\PY{n}{i} \\PY{o}{!=} \\PY{l+s+s1}{\\PYZsq{}}\\PY{l+s+s1}{\\PYZus{}\\PYZus{}scfg\\PYZus{}sentinel\\PYZus{}\\PYZus{}}\\PY{l+s+s1}{\\PYZsq{}}\\PY{p}{:}\n",
+ " \\PY{k}{if} \\PY{n}{i} \\PY{o}{==} \\PY{n}{x}\\PY{p}{:}\n",
+ " \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}exit\\PYZus{}var\\PYZus{}0\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{l+m+mi}{1}\n",
+ " \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}backedge\\PYZus{}var\\PYZus{}0\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{l+m+mi}{1}\n",
+ " \\PY{k}{elif} \\PY{n}{i} \\PY{o}{==} \\PY{n}{y}\\PY{p}{:}\n",
+ " \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}exit\\PYZus{}var\\PYZus{}0\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{l+m+mi}{2}\n",
+ " \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}backedge\\PYZus{}var\\PYZus{}0\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{l+m+mi}{1}\n",
+ " \\PY{k}{else}\\PY{p}{:}\n",
+ " \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}backedge\\PYZus{}var\\PYZus{}0\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{l+m+mi}{0}\n",
+ " \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}exit\\PYZus{}var\\PYZus{}0\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{o}{\\PYZhy{}}\\PY{l+m+mi}{1}\n",
+ " \\PY{k}{else}\\PY{p}{:}\n",
+ " \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}exit\\PYZus{}var\\PYZus{}0\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{l+m+mi}{0}\n",
+ " \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}backedge\\PYZus{}var\\PYZus{}0\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{l+m+mi}{1}\n",
+ " \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}loop\\PYZus{}cont\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{o+ow}{not} \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}backedge\\PYZus{}var\\PYZus{}0\\PYZus{}\\PYZus{}}\n",
+ " \\PY{k}{if} \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}exit\\PYZus{}var\\PYZus{}0\\PYZus{}\\PYZus{}} \\PY{o+ow}{in} \\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{,}\\PY{p}{)}\\PY{p}{:}\n",
+ " \\PY{n}{i} \\PY{o}{=} \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}iter\\PYZus{}last\\PYZus{}1\\PYZus{}\\PYZus{}}\n",
+ " \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}control\\PYZus{}var\\PYZus{}0\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{l+m+mi}{0}\n",
+ " \\PY{k}{elif} \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}exit\\PYZus{}var\\PYZus{}0\\PYZus{}\\PYZus{}} \\PY{o+ow}{in} \\PY{p}{(}\\PY{l+m+mi}{1}\\PY{p}{,}\\PY{p}{)}\\PY{p}{:}\n",
+ " \\PY{n}{i} \\PY{o}{=} \\PY{l+m+mi}{3}\n",
+ " \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}return\\PYZus{}value\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{n}{i} \\PY{o}{+} \\PY{l+m+mi}{100}\n",
+ " \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}control\\PYZus{}var\\PYZus{}0\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{l+m+mi}{1}\n",
+ " \\PY{k}{else}\\PY{p}{:}\n",
+ " \\PY{n}{i} \\PY{o}{=} \\PY{l+m+mi}{4}\n",
+ " \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}control\\PYZus{}var\\PYZus{}0\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{l+m+mi}{2}\n",
+ " \\PY{k}{if} \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}control\\PYZus{}var\\PYZus{}0\\PYZus{}\\PYZus{}} \\PY{o+ow}{in} \\PY{p}{(}\\PY{l+m+mi}{0}\\PY{p}{,} \\PY{l+m+mi}{2}\\PY{p}{)}\\PY{p}{:}\n",
+ " \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}return\\PYZus{}value\\PYZus{}\\PYZus{}} \\PY{o}{=} \\PY{n}{i}\n",
+ " \\PY{k}{else}\\PY{p}{:}\n",
+ " \\PY{k}{pass}\n",
+ " \\PY{k}{return} \\PY{n}{\\PYZus{}\\PYZus{}scfg\\PYZus{}return\\PYZus{}value\\PYZus{}\\PYZus{}}\n",
+ "\\end{Verbatim}\n"
+ ],
+ "text/plain": [
+ "def transformed_break_and_continue(x: int, y: int) -> int:\n",
+ " __scfg_iterator_1__ = iter(range(2))\n",
+ " i = None\n",
+ " __scfg_loop_cont__ = True\n",
+ " while __scfg_loop_cont__:\n",
+ " __scfg_iter_last_1__ = i\n",
+ " i = next(__scfg_iterator_1__, '__scfg_sentinel__')\n",
+ " if i != '__scfg_sentinel__':\n",
+ " if i == x:\n",
+ " __scfg_exit_var_0__ = 1\n",
+ " __scfg_backedge_var_0__ = 1\n",
+ " elif i == y:\n",
+ " __scfg_exit_var_0__ = 2\n",
+ " __scfg_backedge_var_0__ = 1\n",
+ " else:\n",
+ " __scfg_backedge_var_0__ = 0\n",
+ " __scfg_exit_var_0__ = -1\n",
+ " else:\n",
+ " __scfg_exit_var_0__ = 0\n",
+ " __scfg_backedge_var_0__ = 1\n",
+ " __scfg_loop_cont__ = not __scfg_backedge_var_0__\n",
+ " if __scfg_exit_var_0__ in (0,):\n",
+ " i = __scfg_iter_last_1__\n",
+ " __scfg_control_var_0__ = 0\n",
+ " elif __scfg_exit_var_0__ in (1,):\n",
+ " i = 3\n",
+ " __scfg_return_value__ = i + 100\n",
+ " __scfg_control_var_0__ = 1\n",
+ " else:\n",
+ " i = 4\n",
+ " __scfg_control_var_0__ = 2\n",
+ " if __scfg_control_var_0__ in (0, 2):\n",
+ " __scfg_return_value__ = i\n",
+ " else:\n",
+ " pass\n",
+ " return __scfg_return_value__"
+ ]
+ },
+ "execution_count": 38,
+ "metadata": {},
+ "output_type": "execute_result"
+ }
+ ],
+ "source": [
+ "original_ast = unparse_code(break_and_continue)[0]\n",
+ "transformed_ast = SCFG2ASTTransformer().transform(original=original_ast, scfg=scfg)\n",
+ "display_source(ast.unparse(transformed_ast))"
+ ]
+ },
+ {
+ "cell_type": "markdown",
+ "id": "9cec4807-fc8d-4b82-b96d-cce226f968bc",
+ "metadata": {},
+ "source": [
+ "TODO\n",
+ "\n",
"* nested loops"
]
}
@@ -3079,7 +3930,7 @@
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
- "version": "3.12.3"
+ "version": "3.12.4"
}
},
"nbformat": 4,