ONE WAY

From Esolang
Jump to navigation Jump to search
The title of this article is incorrect because of technical limitations. The correct title is Oneway.png.

ONE WAY is an esoteric programming language created by User:DigitalDetective47 based on one‐way movement of data across stacks.

Error vs. exception

In this article, an error refers to a problem with the program's formatting and/or structure, and will prevent the program from running, whereas an exception refers to an issue that occurs during the program's execution, and will not prevent the program from starting.

Data

Data can be stored in two stacks, the primary stack and the secondary stack. Data can be moved from the primary stack to the secondary stack, but not from the secondary stack to the primary stack. Stack operations affect the primary stack by default.

Data types

bool

Either true or false. A bool is specified as true or false.

num

A rational number with an unbounded numerator and denominator. A num can be specified as an integer (ex. 10), a fraction (ex. 9/7) or as a decimal (ex. 0.1). When a decimal is parsed, its exact value is stored.

str

A sequence of Unicode characters. A str is specified by an expression starting with a quotation mark. The str extends to the end of the line. A newline within a string can be specified by the escape sequence \n, and a literal backslash can be represented as \\. Any other backslash sequence will cause an error.

type

The type of a value. Is specified as bool, num, str, or type.

Commands

There are two main types of commands: inline commands and block commands. Inline commands are on a single line, whereas block statements may be followed by a block of commands indented by two spaces. A command that receives a value of an unexpected type will cause an exception, as will a command that attempts to pop from an empty stack. Empty lines are ignored, and a line that is neither empty nor a valid command will cause an error.

Inline commands
Command Effect
add POP num→a; POP num→b; PUSH a + b;
and POP bool→a; POP bool→b; PUSH a ∧ b;
chr Pop a num and push a 1‐charactetr str with the Unicode character corresponding to the num. Cause an exception if the value is <0, >1114111, or not an integer.
concat POP str→a; POP str→b; PUSH a + b;
divide POP num→a; POP num→b; PUSH a ÷ b;
Cause an exception if b = 0.
drop Remove the top value of the stack.
dupe Duplicate the top value of the stack.
equal Pop two values and push whether they are equal. Two values of different types are never equal.
eval Pop a str and push the literal that it contains. Cause an exception if the str is not a valid literal.
flip Pop an element from the primary stack and push it to the secondary stack.
greater POP num→a; POP num→b; PUSH a > b;
input Read a line of input and push it as a str.
len Pop a str and push its length.
less POP num→a; POP num→b; PUSH a < b;
multiply POP num→a; POP num→b; PUSH a × b;
not POP bool→a; PUSH ¬a;
or POP bool→a; POP bool→b; PUSH a ∨ b;
ord Pop a str of length 1 and push the Unicode value of its character as a num. Cause an exception if the str does not have exactly 1 character.
print Pop a str and print it to the terminal.
push <value> Push the given literal. Cause an error if the proceeding value is not a valid literal.
random Pop nums , and push for a random integer such that . Cause an exception if .
repr Pop a value and return a string containing a literal representation of the value popped. A num is an integer (if the num represents an integer), otherwise it is a fraction in simplest form.
split Pop a str and push its characters in order, with the first character on the top.
subtract POP num→a; POP num→b; PUSH a − b;
typeof Pop a value and push its type.
Block commands
Command Effect
if Pop a bool. If it is true, run this statement's block.
else Auxiliary to the if block, runs if the popped value was false.
second All stack access within this block uses the secondary stack instead of the primary stack. Causes an error if nested.
while Pop a bool. If it is true, run this statement's block and then run this block again. If it is false, jump past this block. Note that while pops on each iteration.

Examples

Mandatory test cases

push 0.1
push 0.2
add
push 0.3
equal
repr
print

should output

true

push "Hello, world!"
print

should output

Hello, world!"

push 3
push 1
divide
repr
print

should output

1/3

Hello, world!

push "Hello, world!
print

Infinite loop

push true
while
  push true

Truth-machine

input
push "0
equal
if
  push "0
  print
else
  push true
  while
    push "1
    print
    push true

Binary to unary conversion

push 1
input
dupe
flip
second
  split
len
subtract
dupe
push 0
equal
not
while
  dupe
  second
    eval
  dupe
  push 0
  equal
  not
  while
    push -1
    add
    second
      push 2
      multiply
    dupe
    push 0
    equal
    not
  drop
  push -1
  add
  second
    dupe
    push 0
    equal
    not
    while
      push "*
      print
      push -1
      add
      dupe
      push 0
      equal
      not
    drop
  dupe
  push 0
  equal
  not

Cat program

input
print

Reverse cat

push type
second
  push type
input
split
dupe
push type
equal
not
while
  flip
  dupe
  push type
  equal
  not
second
  dupe
  push type
  equal
  not
  while
    print
    dupe
    push type
    equal
    not

99 bottles of beer

push 99
dupe
push 2
equal
not
while
  dupe
  repr
  dupe
  print
  push " bottles of beer on the wall,\n
  print
  print
  push " bottles of beer.\nTake one down, pass it around,\n
  print
  push -1
  add
  dupe
  repr
  print
  push " bottles of beer on the wall.\n\n
  print
  dupe
  push 2
  equal
  not
push "2 bottles of beer on the wall,\n2 bottles of beer.\nTake one down, pass it around,\n1 bottle of beer on the wall.\n\n1 bottle of beer on the wall,\n1 bottle of beer.\nTake one down, pass it around,\nNo bottles of beer on the wall.\n\nNo bottles of beer on the wall,\nNo bottles of beer.\nGo to the store, buy some more,\n99 bottles of beer on the wall.
print

Deadfish

This implementation supports multiple commands per line, and suppports the h command, which also exits the shell.

second
  push 0
push true
push type
push true
while
  push ">> 
  print
  input
  split
  dupe
  push type
  equal
  not
  while
    dupe
    push "h
    equal
    if
      drop
      push true
      while
        push type
        equal
        not
      push false
    else
      dupe
      push "d
      equal
      if
        second
          dupe
          push 0
          equal
          not
          if
            dupe
            push 257
            equal
            if
              drop
              push 0
            else
              push -1
              add
      else
        dupe
        push "i
        equal
        if
          second
            dupe
            push 255
            equal
            if
              drop
              push 0
            else
              push 1
              add
        else
          dupe
          push "o
          equal
          if
            second
              dupe
              repr
              print
              push "\n
              print
          else
            second
              dupe
              push 16
              equal
              if
                drop
                push 0
              else
                dupe
                multiply
      drop
      dupe
      push type
      equal
      not
  dupe
  push type
  equal

Implementations