- We think that there are 7 sins of modern programming languages:
- Not being able to represent transcendental numbers.
- Having function parameters.
- Function being able to return values.
- Local variables.
- Control flow that is not a loop.
- Non-circular arrays.
- Having any type that's not circular.
Hence, we design this brand-new programming language that is perfect in every way:
Circle lang is homoiconic, which means circle lang code and circle lang data have the same representation. A circle lang program a single circle lang array expression. When a circle lang array gets executed, it acts like a while loop where the first element is treated as the condition and the rest are treated as the body of the loop.
Each circle lang expression is also a circle lang object:
-
Numbers are
$x \times \pi$ . The literal9will be translated to$9 \times \pi$ .- Numbers literal can also take on the form of a sequence of characters
that only contains
A-Z,a-z,_and0-9. It will be translated into a number by rotating it to the lexicographically smallest rotation, and then map it to a$256 \pi$ based number where the ASCII value of each character are a digit.
- Numbers literal can also take on the form of a sequence of characters
that only contains
-
Assignment.
- They are in the form of
<lvalue> := <rvalue>. - Their execution leads to
<rvalue>being evaluated and copied intolvalue>. - Note that if
<lvalue> := <rvalue>is in a sub-expression, it will evaluate to itself. -
:=is right associative and have the lowest precedence.
- They are in the form of
-
Arrays are circular, and the indices are continuous.
- Arrays can be created by
((e1; e2; e3)). Whitespace doesn't matter.;is used as separator.- The last element in the array can be optionally followed by a
;.
- The last element in the array can be optionally followed by a
- Array has a length of multiple of
$\pi$ . An array such as((e1; e2; e3))has a length of$3 \pi$ .
- Arrays can be created by
-
Index
- Array can be indexed by the
()operator. For example((e1; e2; e3))(2) = e3. Zero indexing are used here. - Indexing the array with an uninitialized index will return 1.
- Array indexing will wrap around after its length.
-
((e1; e2; e3))(<index>) = ((e1; e2; e3))(<index> + <any integer> * 3). (Note that while the array have a length of$3\pi$ , the literal3will be translated into$3\pi$ ).
-
- Array can be indexed by the
-
Operator expression.
- There are operators:
+-*/&&||=!=<><=>=!. - They do exactly what you'd expect.
- Precedence:
!-
*/ -
+- -
=!=<><=>= -
&&||
- There are operators:
Note: Since all expressions are also objects, they can be passed around without being evaluated.
- Evaluation have no side effect and will never mutate anything.
- Assignment statement evaluate to themselves.
- Array evaluate to themselves.
- Operators evaluate as you'd expect.
-
(3 * 3 + 3) / (2 * 2 + 2)evaluate to the fractional polynomial:$(3\pi \times 9\pi^2)/(2\pi \times 4\pi^2)$ . - Boolean operator treats zero as truthy and non-zero value (including non
numbers) as falsy.
- All boolean operators:
!=!=<><=>=&&||evaluate to either0or1(reminder that1$= 1\pi$ )
- All boolean operators:
-
- When assignment statement in the form of
<lvalue> := <rvalue>are executed,<rvalue>will be evaluated, copied and assigned to<lvalue>. - When array are executed, it will go through each of its elements whose index
is a multiple of
$\pi$ in order. Each element at the index that is a multiple of the array's length will be evaluated and if that element evaluates to 0, the array will stop executing. Each element that's not at the index that is a multiple of the array's length will be executed.
- There are no local variable, because that implies call stack, which is not circular.
- There are one global variable, which is a big global circular array.
- The circular array is
$256 \pi$ long. - To index into this global variable, simply index with nothing in front of
the
().
- The circular array is
-
(std_input)- Put one user input's ASCII value into
(std_input_char)and times it by$\pi$ .
- Put one user input's ASCII value into
-
(std_output)- Divide
(std_output_char)by$\pi$ and print it out as an ASCII character. -
(std_output_char) := 10; (std_output);will print\n.
- Divide
-
(std_decompose)- Transform store the coefficients of
(std_decompose_number)in(std_decompose_numerator)and(std_decompose_denominator)respectively. - E.g.: if
(std_decompose_number)=$(1 + 2 \times \pi)/(3 + 4 \times \pi)$ , then after running(std_decompose),(std_decompose_numerator)will be((1 / 1; 2 / 1))and(std_decompose_denominator)will be((3 / 1; 4 / 1)).
- Transform store the coefficients of
The source file are implicitly wrapped in a (()), turning it into an array
which are then executed when the source file is interpreted.
Anything not defined in this document is undefined behavior.