lLvlN++

From Esolang
Jump to navigation Jump to search

LLvlN++ or Low-Level Nonsense Plus Plus is an esoteric programming language created in 2025 as an extension of LLvlN. It adds support for functions, procedures, object-oriented programming, and asynchronous programming to the base LLvlN language, allowing for more structured and modern programming while maintaining the culinary-themed absurdity of the original.

Overview

LLvlN++ extends LLvlN by introducing:

  • Function and procedure definitions
  • Parameter passing mechanisms
  • Return values
  • Call stack management
  • Local variable scoping (using the same food-themed registers)
  • Recursive function calls
  • Object-oriented programming with "KITCHEN" classes
  • Asynchronous programming with "MICROWAVE" and "TIMER" keywords

The language maintains full backward compatibility with LLvlN programs, meaning any valid LLvlN program is also a valid LLvlN++ program. The additions use cooking-themed terminology consistent with the base language: functions are "RECIPES" (distinct from the program start marker), procedures are called with "ORDER", returns use "PLATE", classes are "KITCHEN", and async operations use "MICROWAVE" and "TIMER".

Language Specification

New Instructions

Function Definition

  • MENU <name> - Begins a function definition with the given name
  • DISH <name> - Alternative to MENU (procedure with no return value)
  • PLATED - Ends a function/procedure definition
  • PLATE <register> - Returns from function with value in register
  • PLATE - Returns from procedure (no return value)

Function Invocation

  • ORDER <function> - Calls a function or procedure
  • PREP <function> - Calls function and stores return value in register

Parameter Passing

  • INGREDIENT <register> - Declares that a register is a parameter (inside function definition)
  • WITH <register> - Pushes register value as argument before ORDER/PREP

Object-Oriented Programming

  • KITCHEN <name> - Begins a class definition
  • CLOSED - Ends a class definition
  • CHEF <register> - Declares a member variable
  • COOKBOOK <name> - Defines a method within a class
  • NEW <class> <register> - Creates an instance of a class
  • CALL <instance>.<method> - Invokes a method on an object
  • GET <instance>.<field> <register> - Accesses a member variable
  • SET <instance>.<field> <register> - Sets a member variable

Asynchronous Programming

  • MICROWAVE <function> - Starts an asynchronous function call
  • TIMER <register> - Waits for async operation to complete, stores result
  • READY <async_id> - Checks if async operation is complete (non-blocking)
  • CANCEL <async_id> - Cancels a pending async operation

Parameters are passed by value. When a function is called: 1. Arguments are pushed onto the argument stack using WITH 2. The function is invoked with ORDER or PREP 3. Inside the function, INGREDIENT declarations pop arguments in order 4. Registers not declared as INGREDIENT maintain their values from the caller (but changes don't propagate back)

Call Stack

LLvlN++ maintains a separate call stack from the data stack:

  • Each function call creates a new stack frame
  • Registers are saved and restored automatically
  • The data stack (used by BAKE, CHOP, etc.) is shared across all frames
  • Maximum recursion depth is implementation-defined (recommended minimum: 1000)

Object System

Classes in LLvlN++ follow the cooking metaphor:

  • Classes are "KITCHEN" environments where methods ("COOKBOOK" recipes) operate
  • Member variables are "CHEF" ingredients that persist across method calls
  • Object instances represent individual kitchen setups
  • Inheritance is supported through "APPRENTICE" relationships

Asynchronous Model

Asynchronous operations use kitchen timing metaphors:

  • "MICROWAVE" starts non-blocking operations
  • "TIMER" blocks until completion
  • "READY" checks completion status
  • Multiple async operations can run concurrently

Syntax Changes

The main program must still start with RECIPE and end with DONE. Function and class definitions can appear:

  • Before RECIPE (recommended)
  • After DONE
  • Between RECIPE and DONE (execution skips over them)

Function and class names follow the same rules as labels but cannot conflict with each other.

Example Syntax

KITCHEN Counter
    CHEF ingredients
    COOKBOOK increment
        INGREDIENT amount
        ADD ingredients amount
        PLATE ingredients
    PLATED
CLOSED

MENU DOUBLE
    INGREDIENT SOUP    # SOUP is the parameter
    ADD SOUP SOUP      # Double it
    PLATE SOUP         # Return the value
PLATED

RECIPE
    NEW Counter MEAT
    SET CAKE 5
    WITH CAKE
    CALL MEAT.increment
    
    WITH CAKE          # Pass CAKE as argument
    MICROWAVE DOUBLE   # Start async call
    TIMER FISH         # Wait for result in FISH
    SERVE FISH         # Output: 10
DONE

Computational Class

LLvlN++ remains Turing complete, as it includes all capabilities of the base LLvlN language. The addition of functions, procedures, objects, and async operations does not increase the computational power but provides better abstraction, code organization, and modern programming paradigms.

Examples

Factorial (Recursive)

MENU FACTORIAL
    INGREDIENT SOUP           # n is the parameter
    SET CAKE 1
    CMP SOUP CAKE
    BLAND BEAN BASE_CASE      # If n <= 1, return 1
    
    # Recursive case: n * factorial(n-1)
    COPY MEAT SOUP            # Save n
    SET CAKE 1
    SUB SOUP CAKE             # n-1
    WITH SOUP                 # Pass n-1 as argument
    PREP SOUP FACTORIAL       # factorial(n-1)
    MUL SOUP MEAT             # n * factorial(n-1)
    PLATE SOUP
    
BASE_CASE:
    SET SOUP 1
    PLATE SOUP
PLATED

RECIPE
    TASTE RICE                # Read number
    WITH RICE
    PREP MEAT FACTORIAL
    SERVE MEAT                # Output factorial
DONE

Counter Class (OOP Example)

KITCHEN Counter
    CHEF value               # Member variable
    
    COOKBOOK init
        INGREDIENT start_val
        SET value start_val
        PLATE
    PLATED
    
    COOKBOOK increment
        INGREDIENT amount
        ADD value amount
        PLATE value
    PLATED
    
    COOKBOOK get_value
        PLATE value
    PLATED
CLOSED

RECIPE
    NEW Counter SOUP         # Create counter instance
    SET CAKE 10
    WITH CAKE
    CALL SOUP.init           # Initialize with 10
    
    SET MEAT 5
    WITH MEAT
    CALL SOUP.increment      # Increment by 5
    
    CALL SOUP.get_value
    SERVE SOUP               # Output: 15
DONE

Async File Processing

MENU PROCESS_FILE
    INGREDIENT filename
    # Simulate file processing
    SET SOUP 1000
    SALT DELAY_LOOP
    PLATE filename
    
DELAY_LOOP:
    SUB SOUP 1
    BLAND SOUP DONE
    SALT DELAY_LOOP
DONE:
    PLATE filename
PLATED

RECIPE
    SET CAKE 1               # file1.txt
    SET MEAT 2               # file2.txt
    SET FISH 3               # file3.txt
    
    # Start async processing
    WITH CAKE
    MICROWAVE PROCESS_FILE   # Returns async_id in CAKE
    
    WITH MEAT
    MICROWAVE PROCESS_FILE   # Returns async_id in MEAT
    
    WITH FISH
    MICROWAVE PROCESS_FILE   # Returns async_id in FISH
    
    # Wait for all to complete
    TIMER CAKE               # Wait for first
    TIMER MEAT               # Wait for second
    TIMER FISH               # Wait for third
    
    SERVE CAKE
    SERVE MEAT
    SERVE FISH
DONE

Print Array (Procedure Example)

DISH PRINT_ARRAY
    INGREDIENT SOUP           # Array length (on stack below)
    
PRINT_LOOP:
    BLAND SOUP PRINT_END      # If length == 0, done
    CHOP CAKE                 # Pop value from stack
    SERVE CAKE                # Print it
    SET MEAT 10
    SERVE MEAT CHAR           # Print newline
    SET MEAT 1
    SUB SOUP MEAT             # Decrement length
    SALT PRINT_LOOP
    
PRINT_END:
    PLATE                     # Return (no value)
PLATED

RECIPE
    # Push some values
    SET SOUP 10
    BAKE SOUP
    SET SOUP 20
    BAKE SOUP
    SET SOUP 30
    BAKE SOUP
    
    SET CAKE 3                # Array length
    WITH CAKE
    ORDER PRINT_ARRAY         # Call procedure
DONE

Power Function

MENU POWER
    INGREDIENT SOUP           # base
    INGREDIENT CAKE           # exponent
    
    BLAND CAKE POW_ZERO       # If exponent == 0
    
    SET MEAT 1                # result = 1
    
POW_LOOP:
    BLAND CAKE POW_DONE       # If exponent == 0, done
    MUL MEAT SOUP             # result *= base
    SET FISH 1
    SUB CAKE FISH             # exponent--
    SALT POW_LOOP
    
POW_DONE:
    PLATE MEAT                # Return result
    
POW_ZERO:
    SET SOUP 1
    PLATE SOUP
PLATED

RECIPE
    TASTE SOUP                # Read base
    TASTE CAKE                # Read exponent
    WITH SOUP
    WITH CAKE
    PREP MEAT POWER
    SERVE MEAT
DONE

Implementation Notes

Call Stack Management

An implementation must maintain:

  • A call stack with frames containing:
    • Return address (instruction pointer)
    • Saved register values
    • Function/procedure name (for debugging)
  • An argument stack (separate from data stack) for parameter passing
  • A return value register (implementation detail)

Object System Implementation

The object system requires:

  • Object heap for instance storage
  • Method dispatch tables for each class
  • Member variable access tracking
  • Garbage collection (recommended)

Asynchronous System Implementation

Async operations require:

  • Thread pool or event loop
  • Async operation tracking
  • Result storage and retrieval
  • Timeout handling

Register Scoping

When a function is called: 1. All 8 registers are saved to the call stack 2. Arguments are popped from argument stack into registers as specified by INGREDIENT 3. Other registers start with undefined values (recommended: 0) 4. On return, all registers are restored to their pre-call values 5. If PREP was used, the return value overwrites the specified register after restoration

Optimization Opportunities

  • Tail call optimization for recursive functions
  • Inline expansion of small functions
  • Register allocation across function boundaries
  • Argument passing via registers instead of argument stack
  • Method inlining for objects
  • Async operation batching

Error Conditions

Implementations should detect:

  • Stack overflow (too many nested calls)
  • Calling undefined functions or methods
  • Argument count mismatch (recommended, not required)
  • PLATE outside of function context
  • INGREDIENT outside of function definition
  • Duplicate function/class names
  • Invalid object access
  • Async operation timeouts

Differences from LLvlN

Feature LLvlN LLvlN++
Functions Not supported MENU/DISH definitions
Procedures Not supported DISH definitions
Parameter passing Not supported WITH/INGREDIENT
Return values Not supported PLATE
Call stack Only data stack Separate call stack with frames
Recursion Not supported Fully supported
Code organization Linear with labels Modular with functions
Register scoping Global only Local to function calls
Object-oriented Not supported KITCHEN classes with methods
Asynchronous Not supported MICROWAVE/TIMER async operations
Backward compatibility N/A All LLvlN programs valid

See Also

  • LLvlN - The base language
  • Chef - Another cooking-themed esoteric language
  • FALSE - Stack-based language with procedures
  • Assembly language - The structural inspiration
  • Subleq - Minimalist instruction set with function-like behavior
  • Smalltalk - Object-oriented programming inspiration
  • Erlang - Asynchronous programming model inspiration

External Resources

  • Contributions welcome on the Esolang wiki