Pepper

A custom interpreted programming language with stack-based execution, strong typing, and a robust standard library for rapid scripting and educational use.

Programming LanguageInterpreterStack-BasedRPNEducationCustom Language
Pepper Logo
Click to enlarge

Tech Stack

  • Python 3.13
  • Custom Lexer/Parser
  • Standard Library System
  • Markdown-based Documentation
  • GitHub Pages

Timeline

12 weeks (February 2025 - April 2025)

My Role

Language Designer and Core Developer

Project Overview

Pepper is a minimalist, expressive programming language designed with a clean stack-based runtime, optional type declarations, and a powerful built-in standard library. It was created to be both beginner-friendly and semantically rich, making it ideal for scripting, algorithm learning, or building small domain-specific systems.

Key Language Features

  • Stack-based evaluation model with postfix expressions (RPN-style)
  • Optional but enforceable type declarations (e.g., LET x: int)
  • Scoped variables, lexical environments, and block structure
  • Rich conditionals with IF, ELSE, WHILE, FOR, GOTO, and LBL
  • Functions with strict type-checked parameters and return types
  • Full support for user-defined modules
  • Interactive REPL for live debugging and experimentation

Standard Library Highlights

  • Math & Logic: Arithmetic, floor division, exponentiation, comparisons, booleans
  • String Tools: Concatenation, case manipulation, splitting, substring, length
  • List Operations: Map/filter/reduce (planned), indexing, slicing, membership checks
  • Input/Output: INPT, SHOW, random choice and number generation
  • System & Meta: Type introspection, coercion, built-in functions for debugging and state inspection

Test Suite

Pepper features a highly granular test runner written in Python that compares interpreter output to .expected files and offers both line-based and hunk-style diffing. It includes:

  • Runner timeouts, stderr checks, and return code validation
  • Wildcard diffing using ??? as expected value wildcards
  • Command-line options for filtering, verbosity, and diff strategy

Documentation

Pepper has a full documentation site including:

The docs are designed to feel like modern developer tooling: collapsible sections, syntax highlighting, copy buttons, and clear examples.

Example Code Snippet


determineWinner::(p1:string, p2:string) ->
  LET options: list = ["rock", "paper", "scissors"]
  LET i1: int = options [f] p1
  LET i2: int = options [f] p2
  RETURN i1 i2 - 3 + 3 %
<- int

Why It Exists

Pepper was built as both a creative outlet and a practical tool. It lets users explore fundamental programming ideas without boilerplate or syntax noise, while also supporting modular design and type safety. It strikes a balance between scripting convenience and academic rigor.

Key Features

  • Custom interpreter with stack-based execution
  • Strict but optional type declarations and inference
  • Control flow via IF, WHILE, FOR, GOTO, and LBL
  • User-defined functions with return type enforcement
  • REPL for fast interactive testing
  • Detailed test runner with diffing and wildcards
  • Standard library with math, string, list, and IO utilities
  • Modular program structure with imports
  • Minimalist syntax with semantic expressiveness

Challenges & Solutions

Designing a parsing strategy that supports postfix logic while remaining readable. Implementing a robust type system that supports coercion and enforcement. Building a REPL that balances error clarity with minimal internal state leakage. Ensuring standard library extensibility without runtime bloat.

What I Learned

Deeper understanding of interpreter design, especially evaluation semantics and type handling. Improved skills in testing language behavior across edge cases. Learned how to build a full language ecosystem, from parser and runtime to docs and test suite.