FlipScript: A Python-like language for the Flipper Zero

FlipScript: A Python-like language for the Flipper Zero

FlipScript: Rapid Prototyping for Flipper Zero in a Python-like Language

Full code available on Github

The Flipper Zero is a phenomenal piece of hardware, a multitool for geeks that has captured the imagination of hackers, developers, and hobbyists worldwide. Developing custom applications (FAPs) for it, however, typically requires diving into the world of C programming, Makefiles, and the Flipper's specific C API. While powerful, this can present a steep learning curve for those who want to quickly build and test an idea.

Enter FlipScript, a high-level, compiled language designed to bridge this gap. FlipScript offers a clean, Python-like syntax that dramatically simplifies the process of creating applications for the Flipper Zero. It's a tool built for rapid prototyping, allowing you to focus on your application's logic rather than the boilerplate C code.


What is FlipScript?

At its core, FlipScript is a transpiler: a source-to-source compiler. It takes a single script file, written in a custom .fs format with Python-inspired syntax, and translates it directly into a complete, self-contained Flipper Zero application source file in C (.c).

This means you can write code that looks like this:

# A simple FlipScript app
import gui

# Define the state of our application
class AppState:
    message = "Hello, Flipper!"

# Define how the screen should be drawn
def render(canvas, app):
    display_clear(canvas)
    display_draw_str(canvas, 10, 10, app.message)

# Define how to handle button presses
def input(key, type, app):
    if key == InputKeyOk:
        app.message = "Button Pressed!"

And the FlipScript compiler will transform it into a fully-functional output.c file, complete with the necessary headers, app_main entry point, render/input callbacks, and event loop required by the Flipper operating system. You can then take this single C file and build it into a .fap file using the standard Flipper build tools (ufbt).


How Does It Work? The Compiler Pipeline

FlipScript achieves this magic through a classic compiler pipeline, a fascinating process that turns human-readable text into structured, functional code. Let's break down how it works, based on its C source code.

1. The Lexer (lexer.c) - From Raw Text to Tokens

The very first step is Lexical Analysis. The lexer reads your .fs source code file character by character. Its job is to group these characters into a sequence of "tokens." A token is a small unit of meaning, like a number, a string, a keyword, or an operator.

For example, the line counter = 10 is broken down into three tokens:

TOKEN_IDENTIFIER with the value counter

TOKEN_ASSIGN with the value =

TOKEN_NUMBER with the value 10

The lexer is also smart enough to understand Python's significant whitespace, generating TOKEN_INDENT and TOKEN_DEDENT tokens when the indentation level changes. This is crucial for understanding code blocks without needing curly braces.

2. The Parser (parser.c) - From Tokens to a Syntax Tree

Once the lexer has produced a flat stream of tokens, the Parser takes over. The parser's job is to perform Syntax Analysis, which means it checks if the sequence of tokens follows the grammatical rules of the FlipScript language.

If the syntax is valid, the parser builds an Abstract Syntax Tree (AST). The AST is a hierarchical, tree-like data structure that represents the logical structure of your code. For example, an if statement would be a node in the tree with branches for its condition, the "if block," and any "else" or "elif" blocks.

A key feature of the FlipScript parser is its handling of the import statement. When it sees a line like import gui, it looks up a predefined list of Flipper SDK functions associated with that module (like canvas_clear and canvas_draw_str) and injects the necessary C function bindings directly into the AST. This makes the native Flipper functions available to your script without any extra configuration.

3. The Code Generator (codegen.c) - From the AST to C Code

This is where the real "transpilation" happens. The Code Generator walks through the Abstract Syntax Tree, node by node, and generates the equivalent C code for each part.

Application Template: The first thing it does is print out a standard Flipper Zero application template. This includes all the necessary #include headers, the app_main entry point, the event loop (while(running)), and the callback setup for rendering and input.

State Management: When it finds an AppState class definition in the AST, it translates this into a C struct AppState. It then generates an initialize_app_state function that correctly allocates and initializes this struct, using memset to zero out the memory and then assigning any initial values you defined (like counter = 0).

Function Generation: When it encounters a user-defined function in the AST (like render, input, or your own helper functions), it generates a corresponding C function. Crucially, it translates the generic parameters into their correct C types, like Canvas* canvas and AppState* app, allowing you to use them safely.

Expression Translation: It recursively translates expressions, turning app.counter into app->counter and converting Python-style True and False into their C true and false equivalents.

Memory Management: For operations that require temporary strings, like drawing a variable's value to the screen, the code generator now produces safe C code that allocates memory for the string, uses it, and immediately frees it, preventing the memory leaks that can crash Flipper applications.

The final result is a single, clean, and compilable .c file that represents your entire FlipScript application, ready to be built and run on your Flipper Zero.


Future Development

FlipScript is an active and evolving project. While it currently provides a solid foundation for creating GUI applications, the roadmap includes plans to expose more of the Flipper Zero's powerful hardware capabilities. Future releases aim to add support for:

  • GPIO Control: Directly manipulate the Flipper's GPIO pins for custom hardware projects.

  • Sub-GHz Radio: Interact with the radio module to send and receive signals.

  • NFC & Infrared: Add bindings to simplify working with NFC tags and infrared communication.

  • And more...: As the language matures, more of the Flipper's core APIs will be integrated.

The goal is to make FlipScript a comprehensive tool for a wide range of Flipper Zero development tasks, from simple animations to complex hardware interactions.


How to Compile and Run Your FlipScript App

Here is the complete workflow for turning your .fs file into a running Flipper Zero application.

Step 1: Write Your FlipScript (.fs) File

Create a file, for example my_app.fs, and write your application logic using the Python-like syntax.

Step 2: Compile FlipScript to C

Use your flipscript compiler to transpile the .fs file into a C source file. The -c flag enables C code generation, and -o specifies the output file name.

./flipscript -c -o output.c my_app.fs

After running this command, you will have a new file named output.c in your directory. This file contains the complete, self-contained Flipper application code.

Step 3: Configure the Flipper Build

For the Flipper build system (ufbt) to know which file to compile for your application, you must specify it in the application.fam file. This is a critical step. If you don't do this, ufbt will try to compile all .c files in your project, which will cause errors.

Your application.fam should look like this:

# Flipper Application Manifest
App(
    # The App ID is a unique name for your application.
    appid="my_flipscript_app",

    # The entry point for your app's main function.
    entry_point="app_main",

    # List of all C source files that make up your Flipper application.
    # By specifying only "output.c", you are telling the build system
    # to ignore all other .c files in the directory.
    sources=[
        "output.c",
    ],

    # The category under which your app will appear on the Flipper.
    fap_category="Misc",
)

Step 4: Build and Launch on Flipper

With your output.c and application.fam files in place, you can now use the Flipper build tool (ufbt) to build the application and launch it on your device.

ufbt launch

This command will compile output.c into a .fap file and automatically deploy and run it on your connected Flipper Zero. You should now see your FlipScript application running on the device!

You can find the full source code for this project on GitHub: Full code available on Github

← Back to Blog