Skip to content

Instantly share code, notes, and snippets.

@profound7
Created June 18, 2016 16:59
Show Gist options
  • Save profound7/0408725cc82068a3019ad1a3b7beacf6 to your computer and use it in GitHub Desktop.
Save profound7/0408725cc82068a3019ad1a3b7beacf6 to your computer and use it in GitHub Desktop.
Transforming a function into a generator function
// original function
function fib():Iterator<Int> {
var a = 0;
var b = 1;
while (true) {
@yield a;
b = a + b;
@yield b;
a = a + b;
};
}
// add label 0 (start state) and label -1 (end state)
function fib():Iterator<Int> {
@section start;
{
var a = 0;
var b = 1;
while (true) {
@yield a;
b = a + b;
@yield b;
a = a + b;
};
};
@section end;
return;
}
// transform var statements
function fib():Iterator<Int> {
@section start;
{
{
__var_a_1 = 0;
};
{
__var_b_2 = 1;
};
while (true) {
@yield __var_a_1;
__var_b_2 = __var_a_1 + __var_b_2;
@yield __var_b_2;
__var_a_1 = __var_a_1 + __var_b_2;
};
};
@section end;
return;
}
// transforming control structures
function fib():Iterator<Int> {
@section start;
{
{
__var_a_1 = 0;
};
{
__var_b_2 = 1;
};
{
@label start_loop;
@set cond = true;
if (!@get cond) @goto end_loop;
{
{
__current = __var_a_1;
@state next;
return;
@label next;
@void if (false) null;
};
__var_b_2 = __var_a_1 + __var_b_2;
{
__current = __var_b_2;
@state next;
return;
@label next;
@void if (false) null;
};
__var_a_1 = __var_a_1 + __var_b_2;
};
@goto start_loop;
@label end_loop;
@void if (false) null;
};
};
@section end;
{
@state -1;
return;
};
}
// renaming labels and vars
function fib():Iterator<Int> {
@label start_1;
{
{
__var_a_1 = 0;
};
{
__var_b_2 = 1;
};
{
@label start_loop_3;
__cond_3 = true;
if (!__cond_3) @goto end_loop_4;
{
{
__current = __var_a_1;
@state next_5;
return;
@label next_5;
@void if (false) null;
};
__var_b_2 = __var_a_1 + __var_b_2;
{
__current = __var_b_2;
@state next_6;
return;
@label next_6;
@void if (false) null;
};
__var_a_1 = __var_a_1 + __var_b_2;
};
@goto start_loop_3;
@label end_loop_4;
@void if (false) null;
};
};
@label end_2;
{
__state = -1;
return;
};
}
// merging blocks to flatten the code
function fib():Iterator<Int> {
@label start_1;
__var_a_1 = 0;
__var_b_2 = 1;
@label start_loop_3;
__cond_3 = true;
if (!__cond_3) @goto end_loop_4;
__current = __var_a_1;
@state next_5;
return;
@label next_5;
@void if (false) null;
__var_b_2 = __var_a_1 + __var_b_2;
__current = __var_b_2;
@state next_6;
return;
@label next_6;
@void if (false) null;
__var_a_1 = __var_a_1 + __var_b_2;
@goto start_loop_3;
@label end_loop_4;
@void if (false) null;
@label end_2;
__state = -1;
return;
}
// replace label/goto names to integers
function fib():Iterator<Int> {
@label 0;
__var_a_1 = 0;
__var_b_2 = 1;
@label 1;
__cond_3 = true;
if (!__cond_3) {
__state = 4;
continue;
};
__current = __var_a_1;
__state = 2;
return;
@label 2;
__var_b_2 = __var_a_1 + __var_b_2;
__current = __var_b_2;
__state = 3;
return;
@label 3;
__var_a_1 = __var_a_1 + __var_b_2;
{
__state = 1;
continue;
};
@label 4;
@label 5;
__state = -1;
return;
}
// wrapping with a switch
function fib():Iterator<Int> while (true) {
switch (__state) {
case -1:{
throw moon.core.Async.AsyncException.FunctionEnded;
};
case 0:{
__var_a_1 = 0;
__var_b_2 = 1;
};
case 1:{
__cond_3 = true;
if (!__cond_3) {
__state = 4;
continue;
};
__current = __var_a_1;
__state = 2;
return;
};
case 2:{
__var_b_2 = __var_a_1 + __var_b_2;
__current = __var_b_2;
__state = 3;
return;
};
case 3:{
__var_a_1 = __var_a_1 + __var_b_2;
{
__state = 1;
continue;
};
};
case 4:{ };
case 5:{
__state = -1;
return;
};
default:{
throw moon.core.Async.AsyncException.InvalidState(__state);
};
};
++__state;
}
// final pass
function fib():Iterator<Int> {
var __started:Bool = false;
var __state:Int = 0;
var __current:StdTypes.Int = 0;
var __generator:Iterator<StdTypes.Int> = null;
var __var_a_1 = null;
var __var_b_2 = null;
var __cond_3 = null;
function __run():Void while (true) {
switch (__state) {
case -1:{
throw moon.core.Async.AsyncException.FunctionEnded;
};
case 0:{
__var_a_1 = 0;
__var_b_2 = 1;
};
case 1:{
__cond_3 = true;
if (!__cond_3) {
__state = 4;
continue;
};
__current = __var_a_1;
__state = 2;
return;
};
case 2:{
__var_b_2 = __var_a_1 + __var_b_2;
__current = __var_b_2;
__state = 3;
return;
};
case 3:{
__var_a_1 = __var_a_1 + __var_b_2;
{
__state = 1;
continue;
};
};
case 4:{ };
case 5:{
__state = -1;
return;
};
default:{
throw moon.core.Async.AsyncException.InvalidState(__state);
};
};
++__state;
};
function __hasNext() {
return __state >= 0;
};
function __next() {
if (__started) {
var tmp = __current;
__run();
return tmp;
} else {
__started = true;
__run();
return __next();
};
};
__generator = { hasNext : __hasNext, next : __next };
return __generator;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment