Smellcode

From Esolang
Jump to navigation Jump to search

Smellcode is like FALSE, but smellier. The name is a play on the phrase "code smell".

Virtual machine state

The following item describes a mental model for a running Smellcode program.

  • Integer variables A-Z
    • zero-initialized
    • there are only these 26 predefined variables
    • letter case is used to distinguish between storing to the variable vs fetching its value
  • Code stack
    • Is initially empty
    • Holds addresses for function entry points
  • Data stack
    • Is initially empty
    • Holds integers
  • Return stack
    • Is initially empty
    • Holds return addresses
    • This is only accessible indirectly and holds return addresses for function calls (from the @ operator)

Operators

These are the language's built-in operations. The set of operators is deliberately lacking because these can be composed to achieve the effect of other "basic" operations.

  • 0-9... :: push the denoted (non-negative) integer to the data stack
  • ` :: push the next character as a literal to the data stack
  • - :: negate the top integer on the data stack
  • + :: pop and add the top 2 integers of the data stack and push the result
  • * :: pop and multiply the top 2 integers of the data stack and push the result
  • / :: pop and divide the top 2 integers of the data stack and push the dividend and the remainder to the data stack
  • = :: pop the top 2 items from the data stack and push 1 if they are equal but push 0 otherwise
  • > :: pop the top 2 items from the data stack and push 1 if the top item is greater than the other item but push 0 otherwise
  • $ :: swap the top 2 items on the data stack
  • # :: pick value from stack (0 is top, 1 is next, etc...), a.k.a dup the N-deep element of the stack
  • { ... } :: create and push a lambda onto the code stack
  • & :: push current lambda/entry address onto the code stack
    • This allows a lambda to refer to call itself recursively
    • When this operator is not within a lambda, it pushes the code address of the entry point, which is the first operator in the top-level
  • @ :: pop the top item off of the data stack and call the top value of code stack as function if the top data value was not 0
  • \ :: pop the top item off of the data stack and jump to the top value of code stack as function if the top data value was not 0
  • [  :: pop the top item off of the data stack and push it to the code stack
  • ] :: pop the top item off of the code stack and push it to the data stack
  • . :: (dot), pop and print the top data stack item as a character
  • , :: (comma), read an input character and push it to the data stack
  • a :: push value of variable "a" to data stack
    • letter case is used to distinguish between storing to the variable vs fetching its value
  • A :: pop item from data stack and store value in the variable "a"
    • letter case is used to distinguish between storing to the variable vs fetching its value

Idioms

Here is a list of common sequences of operations to achieve one thing:

  • 9- :: the minus sign comes after a number (9 in this case) and makes it negative
  • 0+ :: drop the top item of the data stack
  • 0# :: dup, duplicates the top of data stack
  • ]0#[[ :: dup the top item of the code stack
  • 1# :: over, duplicate the 2nd item on the data stack
  • $0+ :: nip, removes the 2nd item on the data stack
  • 1@ :: call code unconditionally
  • /$0+ :: modulus, get just the remainder from division
  • /0+ :: quotient, get just the quotient from division
  • $> :: less than, checks if the top data stack item is less than the next one
  • 1#1# :: 2dup, duplicates the top 2 items of the data stack
  • &1@ :: recurse, lambda recursively calls itself
  • { true }0#@ 0={ false }@ :: if/else assuming there are no data stack items added in the true lambda
  • { code &1@}1@ :: forever loop / infinite recursion
  • { code }]0#[[1@1@ :: run the code twice
  • aB :: copy value of variable "a" to variable "b"
  • ab$AB :: swap values of variables "a" and "b"
  • { code }]A :: store the function in a variable (in this case, the variable "a")
  • a[1@ :: call the function stored in the variable "a"

Example programs

Hello world

`h.`e.`l.`l.`o.` .`w.`o.`r.`l.`d.