This feature is expected to be in PyFunge 0.6.x experimentally.

Funge compilation is very hard, as the language is designed to be against it. But it doesn't mean every Funge program cannot be compiled of course.

PyFunge tries to do static analysis on the Funge program, and if it fails or proves unfeasible switches to pseudo-compilation mode.

Example

Factorial

0&>:1-:v v *_$.@ 
  ^    _$>\:^

PyFunge extracts all possible code flows from this program. In this case extracted flow should look like this:

  1. executes 0, and jumps to 2
  2. reads one integer, and jumps to 3 if success or 9 if failed.
  3. executes :1-:, pops TOS and jumps to 3 if TOS is zero or 4 otherwise
  4. jumps to 3
  5. executes $, and jumps to 6
  6. executes \:, pops TOS and jumps to 7 if TOS is zero or 8 otherwise
  7. executes *, and jumps to 6
  8. executes $., and terminates.
  9. executes 0, and terminates.

Note that every instruction changes delta is ignored, or splitted into several cases. Each extracted flows can be represented to DAG directly.

We know how each instruction changes the stack. It's as follows: (before -- after, TOS is rightmost one)

  • 0: -- 0
  • 1: -- 1
  • :: a -- a a
  • $: a --
  • \: a b -- b a
  • -: a b -- a-b
  • *: a b -- a*b
  • .: a --
  • Reading one integer(&): -- UNDEF
  • Popping TOS(_, | etc): a --

So every code fragment can be rewritten in similar notation:

  1. -- 0
  2. -- UNDEF
  3. a -- a a-1 (with checking if a-1 is nonzero)
  4. --
  5. a --
  6. a b -- b a a
  7. a b -- a*b
  8. a b -- (with printing a as integer)
  9. -- 0

...TODO

changed April 14, 2009