Mascarpone

From Esolang
Jump to navigationJump to search

Mascarpone is a stack-based, self-redefining programming language designed byChris Pressey in 2007 as a successor toEmmental. In Mascarpone, meta-circular interpreters are first-class values; the interpreter currently being used to interpret the program may be pushed onto the stack ("reified") and manipulated, and an interpreter on the stack may be popped and used as the interpreter for the following part of the program ("deified").

While the author has never really been sure of the extent to which Mascarpone "counts" as anesoteric programming language, from a typical programmer's point of view, it is not obvious how to program in it, and programs in it are borderline-unreadable strings of symbols.

Contents

Execution

Meta-circular interpreter

In Mascarpone, an interpreter is a map that takes symbols to operations, and an operation is a sequence of symbols that is given meaning by some interpreter.

There is a special interpreter in Mascarpone called "null". It is an error to try to interpret anything with this interpreter.

Every interpreter (except for null) is linked to a "parent" interpreter (which may be null.) No interpreter can be its own ancestor; the parent-child relationships between interpreters form a directed, acyclic graph (or DAG.)

There is, at any given time in a Mascarpone, a current interpreter: this is the interpreter that is in force, that is being used to interpret symbols. The parent interpreter of the current interpreter is generally the interpreter that was used to execute the current operation (that is, the operation currently being interpreted; it consists of a string of symbols is interpreted by the current interpreter.)

The current interpreter when any top-level Mascarpone program begins is the initial Mascarpone interpreter.

Stacks

Mascarpone has a stack, that can contain symbols, operators, and interpreters.Strings are popped from the stack beginning with popping a "[" symbol and ending with popping a "]" symbol. Strings can be nested.

By using a parent-child relationship between interpreters, Mascarpone can emulate second stack.By getting the current interpreter, modifying it, setting it's parent to be the current interpreter, and setting it as the current interpreter (in Mascarpone:v...v}^), we "push" something onto it; by getting the current interpreter, getting its parent, and setting that as the current interpreter (v{^), we "pop".

Actually, even if there was no explicit parent-child relationship between interpreters, we'd still be able to store a stack of interpreters, because each operation in an interpreter has its own interpreter that gives meaning to the symbols in that operation, and that interpreter can contain operations that can contain interpreters, etc., etc., ad infinitum.

Initial Mascarpone interpreter

CommandNameDescription
vReifypushes the current interpreter onto the stack.
^Deifypops an interpreter from the stack and installs it as the current interpreter.
>Extractpops a symbol from the stack, then pops an interpreter. It pushes onto the stack the operation associated with that symbol in that interpreter.
<Installpops a symbol from the stack, then an operation, then an interpreter. It pushes onto the stack a new interpreter which is the same as the given interpreter, except that in it, the given symbol is associated with the given operation.
{Get parentpops an interpreter from the stack and pushes it's parent interpreter onto the stack.
}Set parentpops an interpreter i from the stack, then pops an interpreter j. It pushes a new interpreter which is the same as i, except that it's parent interpreter is j.
*Createpops an interpreter from the stack, then a string. It creates a new operation defined by how that interpreter would interpret that string of symbols, and pushes that operation onto the stack.
@Expandpops an operation from the stack and pushes a program string, then pushes an interpreter, such that the semantics of running the program string with the interpreter is identical to the semantics of executing the operation. (Note that the program need not be the one that the operation was defined with, only equivalent to it, under the given interpreter; this allows one to sensibly expand "intrinsic" operations like those in the initial Mascarpone interpreter.)
!Performpops an operation from the stack and executes it.
0Nullpushes the null interpreter onto the stack.
1Uniformpops an operation from the stack and pushes back an interpreter where all symbols are associated with that operation.
[Deepquotepushes "[" and enters deepquote mode, which pushes symbols to the stack until "]"(can be nested).
'Quotesympushes to the stack the symbol after it.
.Outputpops a symbol off the stack and sends it to the standard output.
,Inputwaits for a symbol to arrive on standard input, and pushes it onto the stack.
:Duplicateduplicates the top element of the stack.
$Poppops the top element of the stack and discards it.
/Swapswaps to the top two elements of the stack.

Examples

Hello world

[!dlrow olleH]$............$

Truth machine

'[,']['0.]v*1['1.[1]v{*!]v*'1<*!

It works using uniform interpreter with operation that prints 0 and installing operation that prints 1 and executes itself.

Checks if length of the string is even

[1][(enter any string)][[[1]]v*1[ [0] ]v*'1<*!]v*1*!$.$

External resources

Retrieved from "https://esolangs.org/w/index.php?title=Mascarpone&oldid=123948"
Categories: