x2
Table of Contents
About
x2 is a miniminalistic, open-source language created by iiPython, inspired by x86 assembly and batch. It is a high-level programming language with low-level, easy-to-remember syntaxes, similar to x86 assembly.
An x2 file can have any name and should end with the extension .xt
. It uses a Python interpreter to execute the x2 code.
Check out how to install x2 and the basics to get started with x2.
Installation
To get started, you must have an installation of Python. Python 3.10 or above is recommended, but the minimal requirement is Python 3.9.1.
You can check the version of your Python installation by opening up a terminal and type:
python -V
Next, go to the x2 repository and clone it onto your device.
Optionally, if you have git installed on your device, you can type the following into your terminal instead:
git clone https://github.com/ii-Python/x2
If you are using Visual Studio Code as your text editor, you can also install the x2 syntax highlighter extension.
Basics
Once you finish installing the x2 interpreter, you should be able to find a file named main.xt
. This is your default entry point in your project. You can edit the entry point by following the configuration guide.
Inside the main.xt
is the Hello World example of the x2 language.
:: Imports
imp "pkg/stdlib/arr"
imp "pkg/stdlib/dict"
imp "pkg/stdlib/system"
:: Entry
:main
out "Hello World"
You can begin editing the main.xt
file to start programming in x2.
Once you are done editing the file, open up a terminal in the folder and execute the main.py
interpreter by typing:
python main.py
In the example above, you should see the following output when executing the interpreter
Hello World
Configurations
Inside the x2 interpreter, you should also find a file called config.json
. Inside are your configurations for the x2 interpreter. Below is the default configurations of the x2 interpreter:
{
"entrypoint": "main.xt",
"operators_file": "x2/operators.py"
}
The entrypoint
field is the default entry point when executing the main.py
file. The path is relative to the current working directory of your terminal.
Optionally, you can also type the following to ignore the default entry point:
python main.py
.xt
For example:
python main.py test.xt
The operators_file
field is the directory in where all the operators are located. It is suggested to leave it as is unless you wish to rename or move the files elsewhere.
Syntaxes
The syntaxes of the x2 language is fairly simple. Below you can find a list of all the operators and techniques with examples attached.
Table of Contents
Operators
An operator defines an action in which the x2 interpreter would execute. The operator always comes at the beginning of the line. It is then followed by its arguments.
- add
The add
operator adds two numbers together and appends two strings together.
Syntax:
Example:
:main
psh 5 a
psh 10 b
add a b output
out output
:: 15
:main
psh "Hello " a
psh "World" b
add a b output
out output
:: "Hello World"
- call
The call
operator calls and passes arguments to a section. It is usually used with the operator ret
.
See sections in the sections guide for more information.
Syntax:
call
<_a1> <_a2> <_a...>
Example:
:main
call appendString "Hello " "World" output
out output
:: "Hello World"
:appendString
add _a1 _a2 result
ret result
- cls
The cls
operator clears the screen.
Syntax:
cls
Example:
:main
out "Hello World"
cls
out "Oh no! I am alone!"
- dec
The dec
operator decreases a value or number by 1.
Syntax:
dec
Example:
:main
psh 5 number
dec number
out number
:: 4
- div
The div
operator divides a number from another numbers.
Syntax:
Example:
:main
div 6 2 output
out output
:: 3
- evl
The evl
operator compares two variables and executes a branch.
See expressions in the expressions guide for more information.
Syntax:
evl
[branch false]
Example:
:main
psh 5 a
psh 10 b
evl a == b "jmp true" "jmp false"
:: "The values are different!"
:true
out "The values are equal!"
:false
out "The values are different!"
- ext
The ext
operator ends and exits the x2 interpreter.
Syntax:
ext
Example:
:main
out "Hello World"
ext
out "What about me??? :C"
- inc
The inc
operator increases a variable or a number by 1.
Syntax:
inc
Example:
:main
psh 5 number
inc number
out number
:: 6
- inm
The inm
operator checks if a variable is a number and outputs a 1 if it is true or 0 if it is not.
See data types in the data types guide for more information.
Syntax:
inm
<0|1>
Example:
:main
psh "Hello World" number
inm number output
evl output == 1 "out \"It is a number!\"" "out \"It is NOT a number!\""
:: "It is NOT a number!"
- inms
The inms
operator is similar to the inm
operator. It checks if a variable or a string is a number and outputs a 1 if it is true or 0 if it is not.
See data types in the data types guide for more information.
Syntax:
inms
<0|1>
Example:
:main
psh "5" number
inms number output
evl output == 1 "out \"It is a number!\"" "out \"It is NOT a number!\""
:: "It is a number"
- imp
The imp
operator imports another x2 file to the current workspace.
See importing packages from another file in the packages guide for more information.
Syntax:
imp
Example:
imp "pkg/stdlib/system"
:main
out "Hello World"
- jmp
The jmp
operator allows the x2 interpreter to jump to another section.
See sections in the sections guide for more information.
Syntax:
jmp
Example:
:main
jmp print
:: "Hello World"
:print
out "Hello World"
- lwr
The lwr
operator turns the string into all lowercase letters.
Syntax:
lwr
Example:
:main
psh "Hello World" string
lwr string
out string
:: "hello world"
- mul
The mul
operator multiplies two numbers together.
Syntax:
Example:
:main
psh 5 a
psh 10 b
mul a b output
out output
:: 50
- num
The num
operator turns the variable into a number.
See data types in the data types guide for more information.
Syntax:
num
Example:
:main
psh "5" number
num number
out number
:: 5
- out
The out
operator prints a variable or a string into the terminal.
Syntax:
out
Example:
:main
out "Hello World"
:: "Hello World"
- pause
The pause
operator pauses the x2 interpreter until an [ENTER]
key is pressed.
Syntax:
pause
Example:
:main
out "Hello "
pause
out "World"
- pop
The pop
operator pops a value from a variable. This is especially useful when used inside a string template literal.
Syntax:
pop
[output]
Example:
:main
psh "Hello World" string
out "$(pop string)"
:: "Hello World"
- psh
The psh
operator stores a value as a variable.
Syntax:
psh
Example:
:main
psh "Hello World" variable
- read
The read
operator waits for an input and stores it as a variable.
Syntax:
read
Example:
:main
out "What is your name?"
read "> " name
out "Your name is $(name)"
:: "Your name is
"
- rem
The rem
operator removes a variable from the memory.
Syntax:
rem
Example:
:main
psh "Hello World" string
out string
:: "Hello World"
rem string
out string
:: None
- rep
The rep
operator repeats a section.
See sections from the sections guide for more information.
Syntax:
rep
Example:
:main
rep 5 print
:: "Hello World"
:: "Hello World"
:: "Hello World"
:: "Hello World"
:: "Hello World"
:print
out "Hello World"
- ret
The ret
operator returns a value. It is usually used with the call
operator.
See sections in the sections guide for more information.
Syntax:
ret
Example:
:main
call appendString "Hello " "World" output
out output
:: "Hello World"
:appendString
add _a1 _a2 result
ret result
- rnd
The rnd
operator rounds a number to the nearest whole number.
Syntax:
rnd
[precision]
Example:
:main
psh 5.5 number
rnd number
out number
:: 6
- rng
The rng
operator picks a random whole number from a range.
Syntax:
Example:
:main
rng 0 5 number
out number
:: 3 (Any number from 0 - 5)
- sub
The sub
operator subtracts a number from another.
Syntax:
Example:
:main
psh 5 a
psh 10 b
sub a b output
out output
:: -5
- tstr
The tstr
operator turns a variable into a string.
See data types in the data types guide for more information.
Syntax:
tstr
Example:
:main
psh 5 number
tstr number
out number
:: "5"
- upr
The upr
operator turns the string into all uppercase letters.
Syntax:
upr
Example:
:main
psh "Hello World" string
upr string
out string
:: "HELLO WORLD"
- whl
The whl
operator would continuously call a section until the expression is false.
See expressions in the expressions guide for more information. See sections in the sections guide for more information.
Syntax:
whl
Example:
:main
psh 0 number
whl number != 5 print
:: "Hello World"
:: "Hello World"
:: "Hello World"
:: "Hello World"
:: "Hello World"
:: "Hello World"
:print
out "Hello World"
inc number
Sections
A section defines a chunk of code where it can then be executed separately multiple times.
To define a section, simply append a colon (:
) at the beginning of the section name:
:
For example:
:print
The entry section is always called main
and is necessary in all entry points.
It is a good practice to always put your main
section at the top with any user-defined sections at the bottom:
:main
jmp print
:print
out "Hello World"
A section may be blank:
:main
:print
out "Hello World"
If a section is merged with another section, only the first one would be valid. The other sections would be ignored and not defined in the memory.
:main :print
out "Hello World"
In the example above, only main
would be defined properly. Even though the section print
is also present in the code, it is ignored by the interpreter, thus does not exist when attempting to jump into the section.
A section may take arguments when it is used with the call-ret
pair. It then returns a value and stores it in the last argument.
A proper call
operator should look like this:
call
<_a1> <_a2> <_a...>
And a proper ret
operator should look like this:
ret
Note that a ret
operator is not always necessary in a call-ret
pair if the section does not return a value. However, a return variable is still manditory in that situation.
Arguments in a section are defined as _a
with _a1
being the first argument. Note that arguments are modified when using a nested call-ret
section. Therefore it is a good practice to first define the arguments in a separate variable.
Below is an example of a proper call-ret
section.
:main
call addExclamationMark "Hello World" output
out output
:: "Hello World!"
:addExclamationMark
psh _a1 string
ret "$(pop string)!"
Data Types
There are a total of 3 data types in the x2 language.
- str
The str
data type is a string value that can represent a character, a word, a phrase, or a sentence. It is always wrapped around with double quotes ("
):
"
"
For example:
"Hello World"
Strings can be compared using the following comparators:
==
!=
in
xin
See expressions in the expressions guide for more information.
Some characters have special meanings, that means if you want to use these characters as a literal form in a string, you need to escape them. This is done by adding a back-slash \
immediately in front of the character:
"\
"
For example:
"\t"
"\r"
"\n"
"\\"
"\""
"\033["
"\"Hello World\""
You can also use what is called a string template literal
to wrap other variables inside a string:
"$(
)"
Inside a string template literal
, you can insert another instruction or variable inside. For example:
"$(pop number)"
Note that a nested string template literal
is not allowed. See how to get values from variable names in the technieques guide for more information.
- int
The int
data type is an number that can represent any integers. It, however, cannot store any decimal points. An integer can be positive or negative, and is not wrapped around double quotes ("
):
-
For example:
5
-5
All numbers, including integers, can be increased or decreased using mathematical operators:
inc 5
dec 5
add 5 10 output
sub 5 10 output
mul 5 10 output
div 5 10 output
See operators in the operators guide for more information.
Integers can also be used a booleans, where 0 represents a false value and 1 represents a true value.
All numbers, including integers, can also use the following comparators:
==
<
<=
>
=>
!=
See expressions in the expressions guide for more information.
- float
The float
data type is an number that can represent any decimal numbers. It must have a decimal place, or it will be considered as an integer otherwise. A floating point number can be positive or negative, and is not wrapped around double quotes ("
):
-
For example:
5.0
-5.0
All numbers, including floating point numbers, can be increased or decreased using mathematical operators:
inc 5.0
dec 5.0
add 5.0 10.0 output
sub 5.0 10.0 output
mul 5.0 10.0 output
div 5.0 10.0 output
It can also be rounded to an integer:
rnd 5.0
See operators in the operators guide for more information.
All numbers, including floating point numbers, can also use the following comparators:
==
<
<=
>
=>
!=
See expressions in the expressions guide for more information.
Expressions
An expression compares two values and returns a boolean. It cannot be used on its own and must be paired with operators that accepts expressions:
An expression takes 3 arguments:
The expression takes the two values on the side, a
and b
, and compares them with the comparator provided in the middle.
For example:
"foo" != "bar"
5.5 == 5.5
5 <= 10
There are 9 different comparators in the x2 language.
- ==
The ==
comparator checks if the two values are equal. It can take any data type on each side. When comparing, it checks if the two sides have the same data type and have the same value. The comparator returns true if both sides are equal or false if they are not.
Syntax:
Example:
5 == 10
:: false
- <
The <
comparator checks if the value on the left side is less than the value on the right side. It can take any data type, but both data type must be the same. When both sides are numbers, it compares if the number on the left side is less than the number on the right side. When both sides are strings, it is compared lexicographically. The comparator returns true of the value on the left side is less than the value on the right side or false if they are not.
Syntax:
Example:
5 < 10
:: true
- <=
The <
comparator checks if the value on the left side is less than or equal to the value on the right side. It can take any data type, but both data type must be the same. When both sides are numbers, it compares if the number on the left side is less than or equal to the number on the right side. When both sides are strings, it is compared lexicographically. The comparator returns true of the value on the left side is less than or equal the value on the right side or false if they are not.
Syntax:
Example:
5 <= 10
:: true
- >
The >
comparator checks if the value on the left side is greater than the value on the right side. It can take any data type, but both data type must be the same. When both sides are numbers, it compares if the number on the left side is greater than the number on the right side. When both sides are strings, it is compared lexicographically. The comparator returns true of the value on the left side is greater than the value on the right side or false if they are not.
Syntax:
Example:
5 > 10
:: false
- >=
The >=
comparator checks if the value on the left side is greater than or equal to the value on the right side. It can take any data type, but both data type must be the same. When both sides are numbers, it compares if the number on the left side is greater than or equal to the number on the right side. When both sides are strings, it is compared lexicographically. The comparator returns true of the value on the left side is greater than or equal the value on the right side or false if they are not.
Syntax:
Example:
5 >= 10
:: false
- !=
The !=
comparator checks if the two values are not equal. It can take any data type on each side. When comparing, it checks if the two sides have different data type or have different values. The comparator returns true if both sides are different or false if they are the same.
Syntax:
Example:
5 != 10
:: true
- in
The in
comparator checks if a string exists in another string. It can only take the string data type on both sides. When comparing, it checks if the string on the left is included in the string on the right, whether it is equal to the string on the right side or it is only a part of the string on the right side. The comparator returns true if the string on the left side appears in the string on the right side.
Syntax:
Example:
"Hello" in "Hello World"
:: true
- xin
The xin
comparator checks if a string doesn't exist in another string. It can only take the string data type on both sides. When comparing, it checks if the string on the left is not included in the string on the right. The comparator returns true if the string on the left side doesn't appear in the string on the right side.
Syntax:
Example:
"Hello" xin "Hello World"
:: false
- is
The is
comparator checks if a value is a certain data type. It can take in any data type on the left side, but it can only take the string data type on the right side. When comparing, the data type of value on the left side is checked against the string on the right side. The comparator returns true if the data type of the value on the left side matched the data type on the right side.
Syntax:
is
Example:
"Hello World" is "str"
:: true
Other
Here are some techniques and other core features of the x2 language.
- Comments
You can define a comment by adding two colons (::
) in front of any sentences:
::
For example:
:: Hello World
Currently, it is not possible to have an in-line comment or a block comment.
- Getting Values From Variable Names
Because it is impossible to have nested string template literals, it may seem challenging to obtain a value from a variable name. However, this can be done by having a separate pop
operator:
pop
output
For example:
psh 5 number
psh 10 number5Times2
pop "number$(pop number)Times2" output
out output
:: 10
The string template literal within the string grabs the 5
from the variable number
. It then appends it with the rest of the string. The combined variable name is then popped out and stored in the variable output
.
This method can be useful when you have an unknown variable in your variable name.
Packages
You can import packages from other files. This allows you to use other people's code within your own workspace. Only files ending with the extension .xt
can be imported correctly.
You can import a package by typing the following at the top of your files:
imp
For example:
imp "pkg/stdlib/system"
Note that the extensions is unnecessary when importing another file.
It is a common practice to have a separate folder called pkg/
. When first initializing your x2 interpreter, a pkg/
folder should already be created with a stdlib/
folder within it. These packages inside the stdlib/
folder are the stardard libraries of the x2 language. They are pre-made packages created by the developers of the x2 language. Documentations of these standard libraries can be found on the official website of x2.
Additional packages can be downloaded from the x2 stores.
Links
Here are some useful links for x2
- Github - iiPython's Github Profile
- Syntax Highlighter - Syntax Highlighter for x2 on Visual Studio Code
- Syntax Highlighter Extension - Syntax Highlighter Extension on Visual Studio Code
- Repository - Repository for x2
- Website - Official Website of x2