#programming-language #stack #pancake #esoteric #interpreter #parser

pancakestack

Rust implementation of the Pancake Stack esoteric programming language

12 unstable releases (5 breaking)

0.6.0 Jul 31, 2023
0.5.0 Jun 8, 2023
0.4.1 Feb 12, 2021
0.4.0 Jan 30, 2021
0.1.4 May 14, 2020

#407 in Parser implementations

MIT license

44KB
566 lines

Pancake Stack

crates.io Documentation dependency status MIT

This is a Rust implementation of the Pancake Stack esoteric programming language. This crate includes a parser and an interpreter.

Pancake Stack is a stack-based esoteric programming language created by User JWinslow23 in 2013, in which programs require you to manipulate a stack of pancakes.

Usage

To use pancakestack, first include this in your Cargo.toml:

[dependencies]
"pancakestack" = "0.5"

Crate Examples

Basic Usage

A program can be parsed with pancakestack::parse_program_str and run with pancakestack::run_program.

// load program from file
let mut file = File::open("example.pancake").unwrap();
let mut program_str = String::new();
file.read_to_string(&mut program_str).unwrap();

// parse the program
let program = pancakestack::parse_program_str(&program_str);

// run the program
pancakestack::run_program(&program, std::io::stdin(), std::io::stdout()).unwrap();

Alternatively you can run a program from a str or a Read with pancakestack::run_program_str and pancakestack::run_program_from_read respectively.

// load script file
let mut file = File::open("example.pancake").unwrap();

// write program into string
let mut program = String::new();
file.read_to_string(&mut program).unwrap();

pancakestack::run_program_str(&program, std::io::stdin(), std::io::stdout()).unwrap();
// open script file
let mut file = File::open("example.pancake").unwrap();

// run the script directly from the file
pancakestack::run_program_from_read(file, std::io::stdin(), std::io::stdout()).unwrap();

All pancakestack::run_*methods accept a Read as the input of the script and a Write as the output.

The examples until now used stdin() and stdout(), but it is possible to use anything implementing Read and Write respectively. The following example shows the use of strings as input and output:

let file = File::open("example.pancake").unwrap();
let input = b"some input";
let mut output_buf = Vec::new();
pancakestack::run_program_from_read(file, &input[..], &mut output_buf).unwrap();
let output = std::str::from_utf8(&output_buf).unwrap();

Construct programs

A program can be parsed from a str with pancakestack::parse_program_str. A single line (=command) can be parsed with BorrowedCommand::from_line.

Parsed programs are slices of BorrowedCommands and can be run with pancakestack::run_program.

use pancakestack::BorrowedCommand;

let program = [
    BorrowedCommand::PutThisPancakeOnTop("test"),
    BorrowedCommand::ShowMeAPancake,
    BorrowedCommand::EatAllOfThePancakes
];
pancakestack::run_program(&program, std::io::stdin(), std::io::stdout()).unwrap();

Language Syntax

The pancake stack starts out as empty.

Code Meaning
Put this X pancake on top! Push the word length of X on top of the stack, i.e. "wonderful" would push 9.
Eat the pancake on top! Pop the top value off of the stack, and discard it.
Put the top pancakes together! Pop off the top two values, add them, and push the result.
Give me a pancake! Input a number value and push it on the stack.
How about a hotcake? Input an ASCII value and push it on the stack.
Show me a pancake! Output the top value on the stack as an ASCII character, but don't pop it.
Take from the top pancakes! Pop off the top two values, subtract the second one from the first one, and push the result.
Flip the pancakes on top! Pop off the top two values, swap them, and push them back.
Put another pancake on top! Pop off the top value and push it twice.
[label] Defines a label to go back to (Can also define a comment, if needed). When you go back to the label, it goes to the line number (1 indexed) of the top value of the stack when the label was defined.
If the pancake isn't tasty, go over to "label". Go to label [label] if the top value is 0.
If the pancake is tasty, go over to "label". Same as above, except go if the top value is not 0.
Put syrup on the pancakes! Increment all stack values.
Put butter on the pancakes! Increment only the top stack value.
Take off the syrup! Decrement all stack values.
Take off the butter! Decrement only the top stack value.
Eat all of the pancakes! Terminate the program.

Implementation Notes:

  • How about a hotcake? pushes 0 when there is no input left.
  • [label] overrides an existing label with the same name.
  • Over- and underflowing u32 will lead to an error (not a panic).

Language Examples

Hello World!

Put this heavenly pancake on top!
Put another pancake on top!
Put another pancake on top!
Put another pancake on top!
Put another pancake on top!
Put another pancake on top!
Put another pancake on top!
Put another pancake on top!
Put syrup on the pancakes!
Put the top pancakes together!
Put the top pancakes together!
Put the top pancakes together!
Put the top pancakes together!
Put the top pancakes together!
Put the top pancakes together!
Put the top pancakes together!
Show me a pancake!
Put this appetizing pancake on top!
Put this delectable pancake on top!
Put this delicious pancake on top!
Put the top pancakes together!
Put the top pancakes together!
Put the top pancakes together!
Show me a pancake!
Put this wonderful pancake on top!
Take off the syrup!
Put the top pancakes together!
Show me a pancake!
Show me a pancake!
Put this rich pancake on top!
Take off the butter!
Put the top pancakes together!
Show me a pancake!
Put this delightful pancake on top!
Put this dainty pancake on top!
Put the top pancakes together!
Put another pancake on top!
Put the top pancakes together!
Show me a pancake!
Put this tasty pancake on top!
Put another pancake on top!
Put another pancake on top!
Put another pancake on top!
Put another pancake on top!
Put another pancake on top!
Put another pancake on top!
Put another pancake on top!
Put another pancake on top!
Put another pancake on top!
Put another pancake on top!
Put the top pancakes together!
Put the top pancakes together!
Put the top pancakes together!
Put the top pancakes together!
Put the top pancakes together!
Put the top pancakes together!
Put the top pancakes together!
Put the top pancakes together!
Put the top pancakes together!
Put the top pancakes together!
Put the top pancakes together!
Show me a pancake!
Eat the pancake on top!
Show me a pancake!
Put this good pancake on top!
Take off the butter!
Put the top pancakes together!
Show me a pancake!
Put this divine pancake on top!
Flip the pancakes on top!
Take from the top pancakes!
Show me a pancake!
Put this pleasant pancake on top!
Flip the pancakes on top!
Take from the top pancakes!
Show me a pancake!
Put this mouthwatering pancake on top!
Put this scrumptious pancake on top!
Put this enjoyable pancake on top!
Put the top pancakes together!
Put the top pancakes together!
Show me a pancake!
Eat all of the pancakes!

Cat

Put this old pancake on top!
[CAT]
Eat the pancake on top!
How about a hotcake?
Show me a pancake!
If the pancake is tasty, go over to "CAT".
Eat all of the pancakes!

Other examples can be found in the examples directory.

License

Licensed under MIT license (LICENSE or http://opensource.org/licenses/MIT)

Dependencies

~3–4.5MB
~80K SLoC