Pointing

From Esolang
Jump to navigation Jump to search
Pointing
Paradigm(s) functional,imperative
Designed by User:Calculus is fun
Appeared in 2025
Computational class Turing-Complete
Major implementations JavaScript
Influenced by C++
A blue capital p, an asterisk, and an arrow on a red background
Logo for Pointing
This is a work in progress, expect more soon.

Pointing is a silly language made by Calculus is fun (talk), The basic idea came to me when learning C++ in 2023, what if pointers where the main show?

Memory

The memory of Pointing is an array of arbitrarily sized signed integers, the memory is divide as such:

[<orphaned pointers>, ROZ, <empty × ∞>]

The read only zero (ROZ) is indexed as 0, and indices increase to the right. the memory is "sparse", and can have missing entries. When writing code, the ROZ behaves like the null pointer of other languages, since it can not have any data stored there, while the ROZ is equivalent to 0, It is to clarify a ROZ pointer check from a normal zero check

Instructions

Notation/Function Description
allocate(size) Finds a contiguous empty patch of the given size, fills the patch with 0s, and returns an orphaned pointer pointing at the first slot, if given 0 or a negative, returns a pointer pointing to the ROZ
free(pointer, size) sets size number of slots on and after the pointer to empty then deletes pointer, if size is 0 or negative, it only deletes the pointer.
inputInt(pointer) pulls an integer from stdin, if a valid number is found, pointer = <input>;, otherwise does the assignment pointer = empty
inputStr(pointer) pulls a string from stdin stopping at and including the newline character, and preforms the following @pointer = allocate(len(<input>)) before assigning the memory values their corresponding character
outputInt(value) sends the characters representing <value> when written in decimal to stdout.
outputChar(value) send the character corresponding to value to a buffer.
foo An identifier for an orphaned pointer (AKA a pointer to a variable).
@foo The memory location of foo
$ read memory location
+, -, _, *, /, % Addition, subtraction, negation, multiplication, floored division, and modulus, respectively.
¬, ∧, ∨, ⊻ Boolean not, and, or, & xor, respectively. and & or short-circuit.
0, empty → false, non-0 → true.
~, &, |, ^ Bitwise not, and, or, & xor. and & or short-circuit.
empty → 0
==, <, >, <=, >= equality, less than, greater than, less than or equal to, greater than or equal to, respectively
? ternary conditional operator

Expressions

Expressions are of the following form:

<expression> := <number> | <global constant> | ["@"] <identifier> | <unary expression> | <binary expression> | <ternary expression> | <function call>
<number> := ("0" | "1" | "2" | "3" | "4" | "5" | "6" | "7" | "8" | "9")+
<global constant> := "true" | "false" | "empty" | "ROZ"
<unary expression> := ("$" | "_" | "¬" | "~")<expression>
<binary expression> := ("+" | "-" | "*" | "/" | "%" | "==" | "<" | ">" | "<=" | ">= | "∧" | "∨" | "⊻" | "&" | "|" | "^")<expression><expression> 
<ternary expression> := "?"<expression><expression><expression>
<function call> := <function name> "(" <expression>* ")"
If 2 conflicting parts are back to back, separated them with a comma.

Please notice that expressions are written in Polish notation, this is to decrease the work the compiler/interpreter has to do.

Statements

Expressions are good and all, but they don't affect anything. that's where statements come in:

<statement> := <assignment> | <if> | <while> | <other statements>
<block> := "{" <statement>+ "}"
<identifierCreation> := "@" <identifier> "=" <expression>
<assignment> := <expression> "=" <expression>
<if> := "if (" <expression> ")" <block>[<else>]
<else> := "else" (<if> | <block>)
<while> := "while(" <expression> ")" <block>
<other statements> = (<expression> | "break"† | "continue"† | "return " (<expression> | ";")‡)
† only valid in a while's block
‡ only valid in a function

Boolean values are nominally -1 and 0 for true and false (taken from FALSE). but for courtesy, any non-zero integer is coerced to -1 when in the <expression> of an <if>, <while>; both arguments of the boolean operators; or the first argument of ?

Functions

Functions are labeled blocks of code, allowing for more sophisticated structures.

<function> := "function" <identifier> "(" <parameter identifiers>* ")" <block>

Examples

Pointer manipulation

@i = allocate(1) [creates a pointer to a 0]
@p = allocate(0) [create a pointer to ROZ]
i = 5 [sets value at pointer to 5]
p = 1 [silently does nothing]
@p = @i [p is pointing at i]
outputInt($$p) [5 (see line 3)]

Hello world

outputChar(72) [H] 
outputChar(101) [e]
outputChar(108) [l]
outputChar(108) [l]
outputChar(111) [o]
outputChar(44) [,]
outputChar(32) [ ]
outputChar(119) [w]
outputChar(111) [o]
outputChar(114) [r]
outputChar(108) [l]
outputChar(100) [d]
outputChar(33) [!]

Cat

@s=allocate(0)
while (true) {
  inputStr(@s)
  [if the string immediately ends]
  if (== $s 10) {
    free(s 1)
    break
  }
  [for each character, output it until you hit a line break]
  while (¬ == $s 10) {
    outputChar($s)
    s = empty
    @s = + s 1
  }
  [output newline]
  outputChar(10)
  [clean up newline]
  free(s 1)
}

Linked List

function length(listStart) {
  [$$listStart could contain metadata about the list]
  @len=allocate(1)
  while (¬==$+$listStart 1 ROZ) {
    len=+$len1
    listStart=$+$listStart 1
  }
  free(@listStart 1)
  return len
}

function pointerToIndex(listStart, index) {
  index=+$index1
  while (∧>$index0¬==$+$listStart 1 ROZ) {
    index=-$index1
    listStart=$+$listStart 1
  }
  if (==$index0) {
    free(@index 1)
    return listStart
  }
  free(@index 1)
  free(@listStart 1)
  return ROZ
}

function insertedElement(listStart, index) {
  @prev=pointerToIndex($listStart, -$index1)
  free(@index 1)
  @insert=allocate(2)
  +insert1=$+$prev1
  +$prev1=insert
  free(@prev 1)
  return insert
}

[use G affix so Pointing makes local variables in a function instead of overwriting global ones]
@listG=allocate(2)
[setup 1-element list]
+listG1=allocate(2)
$+listG1=72
[create a new element in index 1 of the list]
@secondG=insertedElement(listG 1)
[we now have a list of 2 elements, and we could repeat this indefinitely]
secondG=3
outputInt($secondG)

With these functions, a brainfuck interpreter is easily writable

Implementations

JS interpreter by Calculus is fun (talk)