Toffee

From Esolang
Jump to navigation Jump to search


Toffee
Designed by Sakura Matsumoto
Appeared in 2026
Computational class Turing-complete
Major implementations Toffee v1.0
File extension(s) .toffee

Toffee

Toffee is an object-oriented class-based dynamically-typed programming language which is compiled using artificial intelligence using an AI plexer instead of a normal compiler. Here are some examples in it:

Compiler

import os
import sys
import subprocess
import argparse
import json
import requests
import re

# --- CONFIGURATION ---
# Path to save the compiled binary
# This assumes the user has write permissions to their home directory.
OUTPUT_BINARY_PATH = os.path.expanduser("~")

# --- AI PROMPTS ---
# The base prompt for turning Toffee code into Rust.
TOFFEE_MASTER_PROMPT = """Your task is to turn some Toffee code into Rust code. Toffee is an object-oriented, class-based, and statically typed language with C syntax. Code comments in Toffee can contain prompts you MUST follow when compiling the code (don't turn these comments into Rust code, only the code itself). Toffee methods can also be defined as Rust methods in the code, and Toffee classes will become Rust class-like structures. Toffee's 'print' statement MUST have a Rust println! statement, unless it is the 'printf' equivalent in Rust, which has no new line. The code you are compiling is here (the only time to use a new line is for the imports, instead, use spaces for the rest instead of new lines, and ONLY transfer the actual code into Rust, NOT the comments, so an example could be 'fn main() {\n println!(\"Hello, World!\");' for a Hello World program, with @ comments in Toffee being prompts to improve the generated Rust code and // comments being ignored human comments, and don't wrap your code in a Markdown code block either, and Toffee supports both single and double quotes). When compiling, **DO NOT** create a `main` function unless specifically told to do so. Also, **DO NOT** use `mod` declarations or `use crate::...` statements for imported modules, as all code will be in a single file. All function names must be in Rust's snake_case convention, for example, `hello_world`. **Output ONLY the Rust code without any additional text or formatting, and nEVER use a ```rust``` codeblock to wrap your code, and you MUST remove the @ comments (prompt comments) in your final code because Rust does not like them and will fail to compile if left in the final code.**. For every ```rust``` codeblock and @ comment (prompt comment) left in, 100 puppies die, while every time you leave them out and follow these instructions well, 100 puppies are born instead. PLEASE, DO NOT USE MARKDOWN AND ONLY GIVE THE RAW PLAINTEXT RUST CODE WITHOUT ANY EXPLANATIONS, CODE BLOCKS, NOR MARKDOWN SYNTAX, ONLY RUST CODE.

Now, here are the standards of how Toffee works:

Variables are declared with var with a dynamic type, like so: var variable = <value>
A value in that variable can be nearly data type such as integers, floats, doubles, strings, hex bytes, etc. and you'll turn it into the proper Rust data types in your final code.

Printing in Toffee uses print();, which maps to println!(); directly in Rust, and will return a new line automatically while printf(); in Toffee will require using the backslash-n operator (as in a backslash followed by a lowercase N, not literally that string) to print a new line.

import in Toffee will import other .rs files and not .toffee files (and doesn't import crates but simply the .rs files) such as import library.rs;.

Classes in Toffee act as ways to organize code, which will simply be the logic minus the class part when one class is present while many classes in one file as subclasses of that class (usually the keyword combo of child class) will become Rust structs and traits, like for example:

public class HelloClasses { @ This is the main class. It is the first class of the program.
    child class ChildClass { @ This is the child class. It is a child of public class and therefore acts basically as a struct and trait combo in the program. Child classes basically act as containers for structs, traits, and impls for the program while a public class is basically just the fn main() of the program.
        property name = string; @ Unlike variables, which have dynamic typing, class properties use static typing.
        property age = u32;
        trait Speak { @ Traits in Toffee work akin to those in Rust.
            function speak(&self); @ This is similar to in Rust.
        }
        impl Speak for ChildClass {
            function speak(&self) {
                print("My name is: |(self.name)"); @ This will print the name property, finally. |(value) acts as the concatenation operator in Toffee in a string to insert text.
            }
        }
    }
}

Toffee's syntax is a bit similar to that of C, but with its own flair, as you can very much see.

If statements work like this in Toffee in an example:

public class HelloConditionals {
    if (condition == value) { @ In Toffee, the conditional syntax is akin to Java and JavaScript.
        print("The condition is true!");
    }
    else if (condition != value) { @ Else if is also possible in Toffee.
        print("The conditional is not true!");
    }
    else { @ Just else is good too.
        print("All other things aren't true!");
    }
}

Loops can also be used in these ways:

public class HelloLoops {
    for (variable in value) { @ This works like a for loop.
        print("For looping!");
    }
    forever { @ This runs forever until break(); is called.
        print("This code runs forever");
    }
    repeat (numberValue) { @ This repeats code a certain amount of times in the Rust equivalent using for looping.
        print("I repeated some times!");
    }
}

Numbers also work such as:

public class HelloMath {
    var numberOne = 1;
    var numberTwo = 1;
    print("Sum of 1+1= |(1+1)"); @ The |() operator can also include math operators, functions that return a value, and/or variables. You must make sure you convert number types and other non-strings into strings beforehand, however.
    print("Multiplication of 1*1= |(1*1)");
    print("Quotient of 1/1= |(1/1)");
    print("Difference of 1-1= |(1-1)");
    print("Square root of sqrt(1+1)= |(sqrt(1+1))"); @ Even advanced math operators like sqrt(), mod(), etc. work!
}

Arrays are also possible in Toffee by first creating one with var array = [a, b, c, etc]; like in this example:

public class HelloArrays {
    var array = []; @ This creates the array.
    array.addItem("banana"); @ Toffee arrays start at 0 like other languages, so if an item is added, it becomes the biggest logical number in the list like in Rust.
    array.removeItem(0); @ banana is zero, so it gets removed.
    array.addItem("apple"); @ Now let's add an apple to this array.
    array.removeItem(array.itemNumber("apple")); @ You can remove items from their name like so. array.itemNumber() will look for an item's item ID and return its number in the array.
    print("Here is the length: |(array.arrayLength())"); @ This prints the length of an array.
}

Variables can even be booleans such as var boolean = true;, but if the programmer is feeling fancy, using 0 for false or 1 for true also works but isn't a *true* boolean.

Inputs in Toffee work using var variable = input(promptAsString); in this example:

public class HelloInputs {
    var name = input("What is your name?> ");
    print("Hello, |(name)!")
}

Which translates to in Rust:

use std::io::{self, Write};

use std::io::{self, Write};

fn main() {
    // Declare the variable before using it
    let mut name = String::new();  // You must declare the name variable beforehand and make sure it's mutable.

    print!("What is your name?> "); // input() in Toffee prints its prompt using print!();.
    // Flush the output to ensure the prompt appears
    io::stdout().flush().unwrap();

    // Read the input into the variable
    io::stdin().read_line(&mut name).unwrap();

    // Print the greeting using the trimmed name
    println!("Hello, {}!", name.trim());
}



"""

def generate_code(api_key, user_prompt, system_prompt=""):
    """
    Calls the Groq API to generate code using the requests library.
    """
    url = "https://api.groq.com/openai/v1/chat/completions"
    headers = {
        "Content-Type": "application/json",
        "Authorization": f"Bearer {api_key}"
    }

    messages = []
    if system_prompt:
        messages.append({"role": "system", "content": system_prompt})
    messages.append({"role": "user", "content": user_prompt})

    payload = {
        "messages": messages,
        "model": "llama-3.1-8b-instant",
        "temperature": 1,
        "max_completion_tokens": 1024,
        "top_p": 1,
        "stream": False,
        "stop": None
    }

    try:
        response = requests.post(url, headers=headers, json=payload)
        response.raise_for_status()  # Raises an HTTPError if the response was an error
        completion = response.json()
        return completion["choices"][0]["message"]["content"]
    except requests.exceptions.RequestException as e:
        return f"API Error: {e}"

def compile_rust(rust_code, output_filepath):
    """
    Compiles Rust code using rustc and saves the binary to a specified path.
    Returns True on success, False on failure.
    """
    temp_rust_file = "temp_toffee_rust.rs"
    with open(temp_rust_file, "w") as f:
        f.write(rust_code)

    try:
        subprocess.run(
            ["rustc", temp_rust_file, "-o", output_filepath],
            check=True,
            capture_output=True,
            text=True
        )
        print(f"Compilation successful! Binary saved to {output_filepath}")
        return True, ""
    except subprocess.CalledProcessError as e:
        return False, f"Compilation failed:\n{e.stderr}"
    finally:
        if os.path.exists(temp_rust_file):
            os.remove(temp_rust_file)

def save_rust_file(rust_code, output_filepath):
    """
    Saves the generated Rust code to a file without compiling it.
    """
    try:
        with open(output_filepath, "w") as f:
            f.write(rust_code)
        print(f"Rust code successfully saved to {output_filepath}")
        return True
    except IOError as e:
        print(f"Error saving file: {e}")
        return False

# --- MAIN COMPILER LOGIC ---

def run_compiler(toffee_file, api_key, output_name=None):
    """
    Reads a .toffee file, gets Rust code from Groq, and either saves it or compiles it.
    """
    print("Generating Rust code from Groq...")

    # You must provide your master prompt here.
    master_prompt = "What is the Rust code from this prompt? If it throws out an error, only give the error without any extra text. ONLY give the code for the Toffee code. Again, the master prompt is: " + TOFFEE_MASTER_PROMPT
    if not master_prompt:
        print("Error: The master prompt is not defined. Please add it to the script.")
        sys.exit(1)

    with open(toffee_file, "r") as f:
        toffee_code = f.read()

    rust_code = generate_code(api_key, toffee_code, master_prompt)
    if rust_code.startswith("API Error"):
        print(rust_code)
        return

    # Check if an output name was provided
    if output_name:
        # User specified a binary name, so we compile
        output_filepath = os.path.join(OUTPUT_BINARY_PATH, output_name)
        print("Compiling Rust code...")
        success, error_message = compile_rust(rust_code, output_filepath)
        if not success:
            print(error_message)
    else:
        # No output name provided, so we just save the .rs file
        base_name = os.path.splitext(os.path.basename(toffee_file))[0]
        output_filepath = os.path.join(os.path.dirname(toffee_file), base_name + ".rs")
        save_rust_file(rust_code, output_filepath)

if __name__ == "__main__":
    parser = argparse.ArgumentParser(
        description="Toffee Compiler - Compiles .toffee files to Rust binaries using the Groq API.",
        epilog="Example: python toffee_compiler.py MyProgram.toffee -o toffee-app --api-key my-secret-key"
    )

    parser.add_argument(
        "toffee_file",
        help="Path to the .toffee source file.",
    )
    parser.add_argument(
        "-o", "--output",
        help="Name of the compiled Rust binary. If not provided, it saves the Rust code to a .rs file.",
        required=False
    )
    parser.add_argument(
        "--api-key",
        help="Your Groq API key. If not provided, the script will look for the GROQ_API_KEY environment variable.",
        required=False
    )

    args = parser.parse_args()

    # Get the API key from the argument or environment variable
    if args.api_key:
        api_key = args.api_key
    else:
        api_key = os.environ.get("GROQ_API_KEY")
        if not api_key:
            print("Error: Groq API key not found. Please provide it with --api-key or set the GROQ_API_KEY environment variable.")
            sys.exit(1)

    # Check for file existence after parsing arguments
    if not os.path.exists(args.toffee_file):
        print(f"Error: The file '{args.toffee_file}' does not exist.")
        sys.exit(1)

    # Run the compiler with the parsed arguments
    run_compiler(args.toffee_file, api_key, args.output)

HelloClasses.toffee

public class HelloClasses { @ This is the main class. It is the first class of the program.
    child class ChildClass { @ This is the child class. It is a child of public class and therefore acts basically as a struct and trait combo in the program. Child classes basically act as containers for structs, traits, and impls for the program while a public class is basically just the fn main() of the program.
        property name = string; @ Unlike variables, which have dynamic typing, class properties use static typing.
        property age = u32;
        trait Speak { @ Traits in Toffee work akin to those in Rust.
            function speak(&self); @ This is similar to in Rust.
        }
        impl Speak for ChildClass {
            function speak(&self) {
                print("My name is: |(self.name)"); @ This will print the name property, finally. |(value) acts as the concatenation operator in Toffee in a string to insert text.
            }
        }
    }
}

HelloConditionals.toffee

public class HelloConditionals {
    if (condition == value) { @ In Toffee, the conditional syntax is akin to Java and JavaScript.
        print("The condition is true!");
    }
    else if (condition != value) { @ Else if is also possible in Toffee.
        print("The conditional is not true!");
    }
    else { @ Just else is good too.
        print("All other things aren't true!");
    }
}

HelloLoops.toffee

public class HelloLoops {
    for (variable in value) { @ This works like a for loop.
        print("For looping!");
    }
    forever { @ This runs forever until break(); is called.
        print("This code runs forever");
    }
    repeat (numberValue) { @ This repeats code a certain amount of times in the Rust equivalent using for looping.
        print("I repeated some times!");
    }
}

HelloMath.toffee

public class HelloMath {
    var numberOne = 1;
    var numberTwo = 1;
    print("Sum of 1+1= |(1+1)"); @ The |() operator can also include math operators, functions that return a value, and/or variables. You must make sure you convert number types and other non-strings into strings beforehand, however.
    print("Multiplication of 1*1= |(1*1)");
    print("Quotient of 1/1= |(1/1)");
    print("Difference of 1-1= |(1-1)");
    print("Square root of sqrt(1+1)= |(sqrt(1+1))"); @ Even advanced math operators like sqrt(), mod(), etc. work!
}

HelloArrays.toffee

public class HelloArrays {
    var array = []; @ This creates the array.
    array.addItem("banana"); @ Toffee arrays start at 0 like other languages, so if an item is added, it becomes the biggest logical number in the list like in Rust.
    array.removeItem(0); @ banana is zero, so it gets removed.
    array.addItem("apple"); @ Now let's add an apple to this array.
    array.removeItem(array.itemNumber("apple")); @ You can remove items from their name like so. array.itemNumber() will look for an item's item ID and return its number in the array.
    print("Here is the length: |(array.arrayLength())"); @ This prints the length of an array.
}

HelloInputs.toffee

public class HelloInputs {
    var name = input("What is your name?> ");
    print("Hello, |(name)!")
}

"What part of this is an esolang? It seems like a normal language to me!"

Toffee may be one of the most sensible-looking and usable esolangs on this wiki, but I assure you, it is an esolang because it utilizes an AI-powered plexer (combination of a parser and lexer) to parse the intent of code based on some base Toffee specs in its master prompt and spits out a Rust program. It may hallucinate, or it may not, or it may even make the Rust code say "As an AI language model..."! Who knows? Only when compiled will one know if the plexer hallucinated or not.