Introduction
Welcome to the official documentation for x++! This documentation will get you started in the development of your first x++ project or will help you learn more about x++ in general with in-depth explanations and tutorials.
Table of Contents
About
x++ (Pronounced "ex-plus-plus") is a high-level, interpreted language written in Python by iiPython with low-level syntax, similar to that of x86 Assembly (and additionally inspired by Batch).
x++ contains features such as:
- Automatic garbage collection
- Scoped/file/global variables
- Sectioning/function system
- Mature python integration
- Import/export/module system
- Object-oriented programming through the use of files
- ... much more!
Getting Started
Step 1: Installation
First and foremost, make sure you have Python (Python 3.10 is required, however we recommend 3.11+) installed on your device. You can check if you have Python installed by opening up a terminal and typing:
python3 -V
(on NT* platforms, replace python3
with py
)
It is highly recommended to have a text editor or Integrated Development Environment, such as Visual Studio Code, as its built-in development tools and add-ons will speed up and facilitate your development process. However, a simple text editor like notepad is sufficient.
Next, visit our github repository and download a clone of the repository by clicking on the green Code ▾
button and the Download ZIP
option. Optionally, if you have git installed on your device, you can also clone the repository by opening up a terminal and typing:
git clone https://github.com/iiPythonx/xpp
To install xpp system-wide, run the following:
pip install .
You will now have the xpp
command available for use.
If you are choosing Visual Studio Code as your Integrated Development Environment, you can also install the x++ extension on the marketplace to get syntax highlighting on your x++ files.
Step 2: Set-Up
Once you open up your x++ project, you should be able to find a file named main.xpp
. By default, this is your main entry file and is where you will be writing your x++ code. Within the file, you should see an example program similar to:
:: Main
prt "Hello, world!"
Any x++ files should always end in the .xpp
extension.
You can edit the main entry file by editing the configuration in .xconfig
. It is a JSON-like file that contains all the configurations for your x++ project. Within it, you should see:
{
"main": "main.xpp"
}
You can learn more about setting up your project in the tutorials.
Step 3: Execution
After you are done writing your x++ code, you can execute your x++ project immediately by opening up a terminal and typing:
python main.py .
Currently, you should see the terminal output:
"Hello, world!"
You can also compile your xpp code into Python using caffeine.
Frequently Asked Questions
Q: Why is it called x++?
The language originally started as the "X Programming Language" because the name sounded cool. As development went on, a second revision was published and the name was changed to x2
.
Starting on March 6th, 2023, x2 was deprecated in favor of x++ as the language was beginning to undergo major changes.
Q: Can I use x++ for data management, game design, or simply for fun?
Most of the things you could think of making are able to be created within x++. However, you can also supercharge xpp with the power of Python; see here.
Credits & Links
Contributors
- iiPython - Developer, Documentation
- DmmD Gaming - Original Documentation, Ideas, & Standard Library
Resources
Last Updated: December 2nd, 2023 by iiPython
x++ / Tutorials
Table of Contents
- Home
- Tutorials ▾
- Documents
- Python API
- Caffeine
- Standard Library
About
Welcome to the tutorials of the official x++ documentation. In this section, you will be learning all the basics within x++, including familiaring the syntax of x++ as well as creating your first x++ project!
If you are looking for information for a specific component of x++, check out the documents instead.
Tutorials
Last Updated: March 9th, 2024 by iiPython
x++ / Tutorials / 1. Hello, world!
Table of Contents
- Home
- Tutorials
- Table of Contents
- About
- Tutorials ▾
- 1. Hello, world! ▾
- 2. User Input
- 3. Branching
- 4. Calculator
- Documents
- Python API
- Caffeine
- Standard Library
Lesson
Welcome to the first lesson of the tutorials! In this lesson, you will be learning how to write your first x++ project, how to define and use a variable, and how to print a value into the terminal.
First, make sure you properly installed x++ to your device if you haven't done so already. You can follow the guide in the getting started section for additional help.
Once you are done, open up the main.xpp
file. Inside, you should find something like this:
:: main.xpp
prt "Hello world!"
This is the default template when you first installed x++. It is important for you to know what the code is doing. Let's break it down.
The first line in the file is a comment. A comment is a text that provides information to the developer, such as you. It is ignored by the interpreter as it is intended for only developers to read.
The second line prints out a string with the value "Hello, world!"
. A string is a series of characters wrapped around by double-quotes ("
). You can think of it like a character, word, phrase, or a sentence. The prt
is an operator, which means it takes arguments, processes them, and does a specific action based on what the arguments are. In the case, the prt
operator simply takes the arguments and prints them in the terminal.
Although indentations in x++ aren't necessary, it is a good practice to use indentation to group the statements, so you or other developers won't get confused.
Now that you understand what your code is doing, let's try it out. Using what you've learned, try printing out your name and age in the format My name is <name> and I am <age> years old
in the terminal.
Did you get something similar to this:
:: main.xpp
prt "My name is Bob and I am 20 years old"
You can also store the name and the age in separate variables so you can reference it later. The var
operator takes in two arguments, the variable
and the value
. To define a value, you can use the following:
var myInteger 5
Let's put that in your code!
:: main.xpp
var name "Bob"
var age 20
prt "My name is Bob and I am 20 years old."
Your can put your variables into your string using string interpolation
. String interpolation is the process of inserting another statement within a string. This is usually done so by wrapping them in $()
.
The statement you can wrap inside of $()
can be any valid x++ syntax, however it has another key feature: you can directly reference variables from inside this environment. This means you can do something like the following:
var x 5
prt "$(x) should be 5."
:: 5 should be 5.
Let's try it!
:: main.xpp
var name "Bob"
var age 20
prt "My name is $(name) and I am $(age) years old."
You did it! You made your first ever x++ project.
In the next lesson, you will learn how to get user input and manipulate strings or numbers.
Last Updated: March 9th, 2024 by iiPython
x++ / Tutorials / 2. User Input
Table of Contents
Lesson
In the previous lesson, you learned how to write your first x++ project, define and use a variable, and output a value into the terminal. In this lesson, you will learn how to get a user input and how to manipulate strings and numbers.
So far, you should've gotten this in your main.xpp
file:
:: main.xpp
var name "Bob"
var age 20
prt "My name is $(name) and I am $(age) years old."
What if you want to ask what the user's name is instead of yours? You can use the read
operator to get user input from the terminal. The read
operator takes in two arguments, the prompt
and the output
. The prompt is what the user will see when you get a user input. You can think of it as asking a question. The output is the answer from the user input.
Let's see it:
read "What is your favorite color? " ?favoriteColor
You can replace your var
operators and use the read
operators instead:
:: main.xpp
read "What is your name? " ?name
read "What is your age? " ?age
prt "Your name is $(name) and you are $(age) years old."
You can also make the name more standout from the rest of the string by making it all capitalized. You can uppercase all the letters in a string by using the upr
operator:
var myString "Hello, world!"
upr myString
prt myString :: Outputs: "HELLO, WORLD!"
Let's try it:
:: main.xpp
read "What is your name? " ?name
upr name
read "What is your age? " ?age
prt "Your name is $(name) and you are $(age) years old."
You can also use mathematical operators to calculate the user's birth year. By subtracting the user's age from the current year, you get their birth year. You can use the sub
operator for this purpose:
sub 5 10 ?output
prt output :: Outputs: -5
However, because the user input always gives us a string, you need a way to convert it into a number. You can use the int
operator for this:
var myInteger "5"
int myInteger
prt myInteger :: Outputs: 5
Let's give it a shot:
:: main.xpp
read "What is your name? " ?name
upr name
read "What is your age? " ?age
int age
sub 2024 age ?birthYear
prt "Your name is $(name) and you were born in $(birthYear)."
Now it will ask the user their name and age and output their name and birth year. Incredible isn't it?
In the next lesson, you will learn how to make branches using the if
operator.
Last Updated: March 9th, 2024 by iiPython
x++ / Tutorials / 3. Branches
Table of Contents
Lesson
In the previous lesson, you learned how to get a user input and modify them to get a certain result. In this lesson, you will be learning how to create a branch using the if
operator.
The if
operator takes 3 arguments, the expression
, the true
branch, and the else
branch. An expression is an equation that evaluates the two sides. An expression is made up of 3 parts, the source
, the comparator
, and the target
:
<source> <comparator> <target>
For example, the equal to
comparator looks like this:
var myInteger 5
myInteger == 5
If the expression is true, the if
operator will then trigger the true
branch, else the false
branch. Both branches must be a string and their contents must be a valid statement.
Because the branches are strings, if you want to use another (double-quoted) string within the branch, you have to escape it. This is done by appending a backslash (\
) right before the double-quote.
Now let's put it together:
var myAge 20
if (myAge == 20) { prt "I am 20 years old" } { prt "I am not 20 years old" }
When you run the code, you should see it outputs "I am 20 years old"
. Try changing the value of myAge
and see what happens.
The else
branch is optional. If you only want to check if the expression is true, you can just use one branch instead:
var myInteger 5
if (myInteger == 5) { prt "My integer is 5" }
With that knowledge, you can now output a special text if the user name matches yours:
:: main.xpp
read "What is your name? " ?name
read "What is your age? " ?age
:: Keep a copy of their original string
var ogName name
:: Calculate birth year by using the current year
int age :: Ensure it's an integer
sub 2024 age ?birthYear
:: Convert the name to lowercase (so we can check it)
if ((lwr name) == "bob") { prt "Welcome, Bob!" }
:: Show them their info
prt "Your name is $(ogName) and you were born in $(birthYear)."
There are many more comparators, such as the greater than
(>
) or not equal
(!=
). They work the same way as the equal to
comparator.
Now's your turn. Check if the user's age is equal to or above 16 and output "You can also drive a car"
after you output their name and their birth year if it is true.
Did you get something like this?
:: main.xpp
read "What is your name? " ?name
read "What is your age? " ?age
:: Keep a copy of their original string
var ogName name
:: Calculate birth year by using the current year
int age :: Ensure it's an integer
sub 2024 age ?birthYear
:: Convert the name to lowercase (so we can check it)
if ((lwr name) == "bob") { prt "Welcome, Bob!" }
:: Show them their info
prt "Your name is $(ogName) and you were born in $(birthYear)."
if (age >= 16) { prt "You can also drive a car." }
In the next lesson, you will be learning how to make a calculator using x++.
Last Updated: March 9th, 2024 by iiPython
x++ / Tutorials / 4. Calculator
Table of Contents
Lesson
From the last three lessons, you learned how to print values into the terminal, get user inputs, modify strings and numbers, and create branches. In this lesson, you will be using all of this knowledge to construct a calculator using x++. Even though it may seem difficult at first, it is just made up of simple components. Let's break it down.
Let's introduce the program and get some inputs from the user using the prt
and read
operators:
:: main.xpp
prt "Welcome to the x++ calculator!"
prt "-----"
read "Please enter your first number: " ?a
read "Please enter your second number: " ?b
prt "-----"
You can also use escape codes to format your texts, such as \t
to indent your text:
:: main.xpp
prt "Welcome to the x++ calculator!"
prt "-----"
read "Please enter your first number: " ?a
read "Please enter your second number: " ?b
prt "-----"
prt "Operators"
prt "\t[A] Addition"
prt "\t[S] Subtraction"
prt "\t[M] Multiplication"
prt "\t[D] Division"
read "Please enter your operator by typing the letter within the bracket: " ?o
prt "-----"
Currently, the numbers you got from the user are a string. You need to parse it into a number using the int
operator so you can use mathematical operators on it. You can also uppercase your operator using the upr
operator so you can allow both lowercase and uppercase answers:
:: main.xpp
prt "Welcome to the x++ calculator!"
prt "-----"
read "Please enter your first number: " ?a
read "Please enter your second number: " ?b
prt "-----"
prt "Operators"
prt "\t[A] Addition"
prt "\t[S] Subtraction"
prt "\t[M] Multiplication"
prt "\t[D] Division"
read "Please enter your operator by typing the letter within the bracket: " ?o
prt "-----"
int a
int b
upr o
Now we can use the if
operator to check what operator the user selected and act accordingly. Currently, there are four types of mathematical operators: add
, sub
, mul
, and div
. Let's use them:
:: main.xpp
prt "Welcome to the x++ calculator!"
prt "-----"
read "Please enter your first number: " ?a
read "Please enter your second number: " ?b
prt "-----"
prt "Operators"
prt "\t[A] Addition"
prt "\t[S] Subtraction"
prt "\t[M] Multiplication"
prt "\t[D] Division"
read "Please enter your operator by typing the letter within the bracket: " ?o
prt "-----"
int a
int b
upr o
if (o == "A") { add a b ?c } \
(o == "S") { sub a b ?c } \
(o == "M") { mul a b ?c } \
(o == "D") { div a b ?c }
Since you defined c
as the answer to the equation, you can simply output it to the terminal. Using string interpolation, you can also use variables within your strings:
:: main.xpp
prt "Welcome to the x++ calculator!"
prt "-----"
read "Please enter your first number: " ?a
read "Please enter your second number: " ?b
prt "-----"
prt "Operators"
prt "\t[A] Addition"
prt "\t[S] Subtraction"
prt "\t[M] Multiplication"
prt "\t[D] Division"
read "Please enter your operator by typing the letter within the bracket: " ?o
prt "-----"
int a
int b
upr o
if (o == "A") { add a b ?c } \
(o == "S") { sub a b ?c } \
(o == "M") { mul a b ?c } \
(o == "D") { div a b ?c }
prt "The answer to that equation is $(c)."
Tada! You got a working calculator. How cool is that?
Last Updated: March 9th, 2024 by iiPython
x++ / Documents
Table of Contents
- Home
- Tutorials
- Documents ▾
- Python API
- Caffeine
- Standard Library
About
Welcome to the documents page of the official x++ documentation. In this section, you will be learning about the individual components that make up x++.
If you are looking for a beginner's guide for x++, check out the tutorials instead.
Documents
Last Updated: March 9th, 2024 by iiPython
x++ / Documents / Comments
Table of Contents
About
Comments are a segment of code that is ignored by the interpreter. They provide reference information to you and the developers.
A comment always starts with two colons ::
and can be placed at the end of any line:
:: This is a comment
prt 5 :: This is an inline comment
Last Updated: March 9th, 2024 by iiPython
x++ / Documents / Comparators
Table of Contents
Catalog
E
F
G
I
L
N
About
Comparators are symbols or keywords that compare two different variables or values and trigger a branch in the x++ thread. Each comparator has its functionality.
Expressions are segments in the code that creates a branch in the x++ thread. They are always made up of three components: the source
, the comparator
, and the target
, and they are arranged like so:
<source> <comparator> <target>
For example:
5 == 5
Or:
"hello" in "hello world"
An expression cannot be used on its own, as it is not considered as an operator and thus not a valid statement. It is always accompanied by operators that take an expression as an argument. A classic example of this is the if
operator:
if (5 == 5) "prt 'true'"
Any operator that uses an expression creates a branch, with true
being the first branch and the second acts as an else
. For example, the if
operator creates a branch based on whether or not the expression is true:
if (5 == 10) "prt 'same'" "prt 'different'"
Documentation
Equal To
<source> == <target>
Checks if the two variables or values are equal to each other.
Parameter | Type | Description |
---|---|---|
Source | Any | The variable or value that is being compared against |
Target | Any | The variable or value being compared to |
Example:
if (5 == 5) "prt 'true'"
Not Equal To
<source> != <target>
Checks if the two variables or values are different from each other.
Parameter | Type | Description |
---|---|---|
Source | Any | The variable or value that is being compared against |
Target | Any | The variable or value being compared to |
Example:
if (5 != 10) "prt 'true'"
Less Than
<source> < <target>
Checks if the source is less than the target.
Parameter | Type | Description |
---|---|---|
Source | Float or Integer or String | The variable or value that is being compared against |
Target | Float or Integer or String | The variable or value being compared to |
Example:
if (5 < 10) "prt 'true'"
Less Than or Equal To
<source> <= <target>
Checks if the source is less than or equal to the target.
Parameter | Type | Description |
---|---|---|
Source | Float or Integer or String | The variable or value that is being compared against |
Target | Float or Integer or String | The variable or value being compared to |
Example:
if (5 <= 10) "prt 'true'"
Greater Than
<source> > <target>
Checks if the source is greater than the target.
Parameter | Type | Description |
---|---|---|
Source | Float or Integer or String | The variable or value that is being compared against |
Target | Float or Integer or String | The variable or value being compared to |
Example:
if (10 > 5) "prt 'true'"
Greater Than or Equal To
<source> >= <target>
Checks if the source is greater than or equal to the target.
Parameter | Type | Description |
---|---|---|
Source | Float or Integer or String | The variable or value that is being compared against |
Target | Float or Integer or String | The variable or value being compared to |
Example:
if (10 >= 5) "prt 'true'"
In
<source> in <target>
Checks if the source is in the target.
Parameter | Type | Description |
---|---|---|
Source | Any | The variable or value that is being compared against |
Target | Any | The variable or value being compared to |
Example:
if ("ello" in "Hello, world!") "prt 'true'"
Not In
<source> not in <target>
Checks if the source is not in the target.
Parameter | Type | Description |
---|---|---|
Source | Any | The variable or value that is being compared against |
Target | Any | The variable or value being compared to |
Example:
if ("bye" not in "Hello, world!") "prt 'true'"
Is
<source> is <target>
Checks if the source is a type of the target.
Parameter | Type | Description |
---|---|---|
Source | Any | The variable or value that is being compared against |
Target | String | The variable or value being compared to |
Example:
if (5 is "int") "prt 'true'"
Last Updated: March 9th, 2024 by iiPython
x++ / Documents / Configuration
Table of Contents
Catalog
M
About
The configuration file defines what the project would do on execution. It is always placed in the .xconfig
file and should be written as if it is within a *.json
file. If one is not found in the project, the default configuration is used internally instead:
{
"main": "main.xpp"
}
The configuration file can also contain non-essential information, such as the author, version, or description of your project:
{
"author": "my-name",
"contributors": [
"contributor A", "contributor B"
],
"description": "This is my x++ project",
"main": "main.xpp",
"name": "my-xpp-project",
"version": "1.0.0"
}
This is part of the official .xconfig specification. In fact,
xpp --show <module>
will use this spec.
Documentation
Main
{
"main": <path>
}
Defines the path of the main entry file.
Parameter | Type | Default | Description |
---|---|---|---|
Path | String<JSON> | "main.xpp" | Entrypoint relative to the current package (or cwd if it's a file) |
Last Updated: March 9th, 2024 by iiPython
x++ / Documents / Data Types
Table of Contents
Catalog
B
F
I
N
S
About
Data types are classifications of variables or values. Each data type can only store a specific type of value. For example, a string cannot contain an integer value, or a boolean cannot contain a string value.
Because x++ is a dynamic programming language, you can change the data type of a variable or a value during run-time.
x++ is also a weakly-typed programming language. You do not (and cannot) directly specify what the data type of a variable or value is. The interpreter will read the value and determine the data type during run-time.
Strongly-typed language, such as Java:
int myInteger = 5;
Weakly-typed language, such as JavaScript:
let myInteger = 5;
Similarly, in x++, you define a variable with a data type of an integer like so:
var myInteger 5
Documentation
Boolean
A boolean value represents either true
or false
.
Currently, it is impossible to get a boolean value within vanilla x++. Because of that, integers are used instead to represent a true or false value, where 1
represents true
and 0
represents false
.
You can however, use Python integration to create booleans on demand. The x++ interpreter supports this functionality natively.
Float
A float is a signed number value with decimal points:
5.0
-5.0
It can be compared using mathematical comparators or be modified using certain operators.
Unlike integers, a decimal point is required to define a float.
Because floats are not accurate representations of the values, inaccuracies can occur similar to other programming languages:
var a 0.1
var b 0.2
prt (a + b)
Integer
An integer is a signed number value with no decimal points:
5
-5
It can be compared using mathematical comparators or be modified using certain operators.
Unlike Python, integers do allow leading 0
s to exist:
var myInteger 05
prt myInteger :: 5
In vanilla x++, it can also be used as a boolean value, where 1
represents true
and 0
represents false
:
var hamburgerIsEaten 1
if (hamburgerIsEaten == 1) { prt "Someone ate my hamburger" }
Null
Null is a data type that represents nothing.
It cannot be defined normally in x++ and acts as the default value to undefined variables:
prt nonexistingVariable
It cannot be modified using any operators, and it cannot be used as a source or target within an expression:
:: This will throw a parsing exception
if (nonexistingVariable == anotherNonExistingVariable) { prt "true" }
String
A string is a combination of characters, numbers, spaces, and other symbols wrapped around by double-quotes ("
):
"string"
"Hello, world!"
"My favorite number is 5."
Some sets of characters, called escape codes or escape sequences, have special meanings within a string, and they always start with a backslash (\
):
"\t Indentation"
"\n New Line"
Below is a list of all the escape codes for reference:
Escape Code | Description | Example | Result | Widely-Supported |
---|---|---|---|---|
Normal | prt "Hello, world!" | Hello, world! | ✓ | |
\\ | Backslash character | prt "Hello,\\world!" | Hello,\world! | ✓ |
\' | Single-quote character | prt "\'Hello, world!\'" | 'Hello, world!' | ✓ |
\" | Double-quote character | prt "\"Hello, world!\"" | "Hello, world!" | ✓ |
\a | Triggers Notification Sound | prt "\a" | ||
\b | Backspace | prt "Hello,\bworld!" | Helloworld! | ✓ |
\f | Form Feed | prt "Hello,\fworld!" | Hello, world! | |
\n | Line Feed | prt "Hello,\nworld!" | Hello, world! | ✓ |
\r | Carriage Return | prt "Hello,\rworld!" | world! | ✓ |
\t | Horizontal Tab | prt "Hello,\tworld!" | Hello, world! | ✓ |
\v | Verticle Tab | prt "Hello,\vworld!" | Hello, world! | |
\ooo | Octal Value | prt "\110\145\154\154\157\54\40\167\157\162\154\144\41" | Hello, world! | ✓ |
\xhh | Hex Value | prt "\x48\x65\x6C\x6C\x6F\x2C\x20\x77\x6F\x72\x6C\x64\x21" | Hello, world! | ✓ |
\N{name} | Unicode Name | prt "Hello,\N{grinning face}world!" | Hello,😀world! | ✓ |
\uhhhh | 16-Bit Unicode Escape | prt "\u0048\u0065\u006c\u006c\u006f\u002c\u0020\u0077\u006f\u0072\u006c\u0064\u0021" | Hello, world! | ✓ |
\Uhhhhhhhh | 32-Bit Unicode Escape | prt "Hello,\U0001F600world!" | Hello,😀world! | ✓ |
\033[ | ANSI Escape | prt "\033[31mHello, world!\033[0m" | Hello, world! in red | ✓ |
You can also string interpolation within an x++ string. All non-string interpolations must be a valid x++ statement and be surrounded by ()
:
:: If you are interpolating two strings:
var secondString "world!"
prt ("Hello, " + secondString) :: "Hello, world!"
:: If you have other datatypes:
var myInteger 5
prt "My favorite integer:" (myInteger)
Any non-string data type within a string interpolation will require the use of ()
.
When being compared against using mathematical comparators, it is compared lexicographically:
if ("abc" < "cba") { prt "true" }
Last Updated: March 9th, 2024 by iiPython
x++ / Documents / Operators
Table of Contents
Catalog
A
C
D
E
F
G
I
J
L
M
N
P
R
S
T
U
V
W
About
Operators are keywords that process arguments.
A statement is a line of code that tells the interpreter what to do. They are always made up of two components: the operator
and the arguments
, and they are arranged like so:
<operator> [...arguments] [...?outputs]
For example:
prt "Hello, world!"
or:
add 1 2 ?sum
A statement can also be wrapped around parentheses (()
) to group them.
Some statements return values, which can be stored in a variable:
var sum (add 1 2)
Documentation
Add
add <addend A> <addend B> [?sum]
Adds two addends together or concatenates two strings together.
Parameter | Type | Optional | Description |
---|---|---|---|
Addend A | Float or Integer or String | The first addend | |
Addend B | Float or Integer or String | The second addend | |
Sum | Variable | ✓ | The sum of the two addend |
Returns: Float or Integer or String
Example:
add 5 10 ?sum
prt sum
Character
chr <string> <index> [stop] [?output]
Returns a substring of string
from index index
to stop
. If stop
is not provided, chr
will return the character at index
.
Parameter | Type | Optional | Description |
---|---|---|---|
String | String | The target string | |
Index | Integer | The index of the string | |
Stop | Integer | ✓ | The index of the string |
Output | Variable | ✓ | The resulting substring or character |
Returns: String
Example:
chr "Hello, world!" 3 5 ?output
chr "Hello, world!" 3 ?output2
prt output output2
:: "lo," "l"
Clear
cls
Clears the terminal.
Returns: Null
Example:
prt "Hello, world!"
cls
prt "Why hello there!"
Decrement
dec <value> <value_2> <...> [?output]
Decreases all given values by one.
If no output is given, the target value itself is decremented instead.
If output is specified, but multiple values are decremented. The result will be null.
Parameter | Type | Optional | Description |
---|---|---|---|
Value(s) | Float or Integer | The value that will be decremented | |
Output | Variable | ✓ | The decremented value |
Example:
var myInteger 5
dec myInteger
prt myInteger
:: 4
Divide
div <dividend> <divisor> <divisor_2> <...> [?quotient]
Divides the dividend by the divisor (in sequential order, if multiple given).
Parameter | Type | Optional | Description |
---|---|---|---|
Dividend | Float or Integer | The value that is being divided | |
Divisor(s) | Float or Integer | The value that is dividing the dividend | |
Quotient | Variable | ✓ | The quotient of the dividend and the divisor |
Example:
div 10 5 ?quotient
prt quotient
:: 2
Evaluate
evl <code>
Evaluate and execute Python code.
Parameter | Type | Optional | Description |
---|---|---|---|
Code | String | The Python code that is being evaluated |
Returns: Null
Example:
evl "print('Hello, world!')"
Exit
exit
Exits the process.
Returns: Null
Example:
prt "Hello, world!"
exit
prt "You'll never see me! Aha!"
Float
flt <string> <?output>
Converts a string into a float.
Output is not required, however the operator call will do nothing if no output is provided.
Parameter | Type | Optional | Description |
---|---|---|---|
String | String | The target string | |
Output | Variable | ✓ | The converted float value |
Returns: Float
Example:
flt "5" ?myFloat
prt myFloat
Get
get <object> <key> [?output]
Retrieves the specified key from the given object.
If object is a list, retrieve the value at index key
.
Parameter | Type | Optional | Description |
---|---|---|---|
Object | Dict | The source object | |
Key | Any | The key to retrieve | |
Output | Variable | ✓ | The retrieved value |
Returns: Any
Example:
flt "5" ?myFloat
prt myFloat
If
if <expr1> <branch1> [expr_n] [branch_n] [...] [else_branch]
Creates a branch based on whether or not the given expression(s) are true.
Parameter | Type | Optional | Description |
---|---|---|---|
Expression 1 | Expression | The first expression | |
Branch 1 | String | Statement to execute if first branch is true | |
Expression N | Expression | ✓ | The nth expression |
Branch N | String | ✓ | Statement to execute if nth branch is true |
Else Branch | String | ✓ | Statement to execute if all expressions were false |
Returns: Null
Example:
if (5 == 5) "jmp istrue" "jmp isfalse"
:istrue
prt "5 is equal to 5"
:isfalse
prt "5 is not equal to 5 somehow"
Import
imp <package/file/python file> [as <name>]
Imports a package, file, or Python script.
If no name is given, the package or file name is used instead. For example, imp "extras"
will require you to use jmp extras.section
; but imp "extras" as "hi"
will allow you to use jmp hi.section
instead.
If path
does not begin with ./
, the path will be assumed to be pkgs/<module>/<module>.xpp
if there isn't a .xconfig
file in the module directory stating another file to load.
Parameter | Type | Optional | Description |
---|---|---|---|
Package / File | String | The path of package or file you want to import | |
Name | String | ✓ | The name of the imported package of file |
Returns: Null
Example:
imp "myFile.xpp" as "myPackage"
Index
idx <string> <substring> [?output]
Converts a string into a float.
Parameter | Type | Optional | Description |
---|---|---|---|
String | String | The target string | |
Substring | String | The substring of the target string | |
Output | Variable | ✓ | The index of the substring in the target string |
Returns: Integer
Example:
idx "Hello, world!" "ello" ?output
prt output
:: 1
Increment
inc <value> <value_2> <...> [?output]
Increases all given values by one.
If no output is given, the target value itself is incremented instead.
If output is specified, but multiple values are incremented. The result will be null.
Parameter | Type | Optional | Description |
---|---|---|---|
Value(s) | Float or Integer | The value that will be incremented | |
Output | Variable | ✓ | The incremented value |
Example:
var myInteger 5
inc myInteger
prt myInteger
:: 6
Jump
jmp <section> [...arguments] [?output1] [?output_n] [?...]
Jumps to a section, provides it with arguments, and stores the output(s) in a variable (or multiple, depending on how many the section returns).
Parameter | Type | Optional | Description |
---|---|---|---|
Section | Section | The target section | |
...Arguments | ...Any | ✓ | The arguments passed to the target section |
...Outputs | Variable | ✓ | The output(s) of the section |
Returns: Any
Example:
:mySection a b
add a b ?sum
ret ?sum
jmp mySection 5 10 ?output
prt output
:: 15
Length
len <string> [?output]
Returns the length of the string.
Parameter | Type | Optional | Description |
---|---|---|---|
String | String | The target string | |
Output | Variable | ✓ | The length of the target string |
Returns: Integer
Example:
len "Hello, world!" ?output
prt output
:: 13
Load
load <path> <output>
Retrieves the content of a file.
Parameter | Type | Optional | Description |
---|---|---|---|
Path | String | The path of the file | |
Output | Variable | The content of the file |
Returns: String
Example:
In file.xpp
:
:mySection
prt "Hello, world!"
In main.xpp
:
load "file.xpp" ?output
prt output
:: :mySection
:: prt "Hello, world!"
Lowercase
lwr <string> [?output]
Lowercases all the characters in a string.
If no output is given, the target value itself is lowercased instead.
Returns: String
Example:
lwr "Hello, world!" ?output
prt output
:: hello, world!
Multiply
mul <factor_1> <factor_2> <factor_n> <...> [product]
Multiples all given factors together in sequential order.
Parameter | Type | Optional | Description |
---|---|---|---|
Factor 1 | Float or Integer or String | The first factor | |
Factor 2 | Float or Integer | The second factor | |
Factor N | Float or Integer | ✓ | The nth factor |
Product | Variable | ✓ | The product of the factors |
Returns: Float or Integer or String
Example:
mul 5 10 ?product
prt product
:: 50
New
new <type> [?output]
Creates a new object of the specified type, returning it.
Returns: List or Dict
Example:
new "list" ?list
prt list
:: []
Integer
int <string> [?output]
Converts a string into an integer.
If no output is given, the target string itself is converted instead.
Parameter | Type | Optional | Description |
---|---|---|---|
String | String | The target string | |
Output | Variable | ✓ | The converted number value |
Returns: Integer
Example:
int "5" ?myInteger
prt myInteger
:: 5
prt [...value]
Prints value(s) into the terminal.
Parameter | Type | Optional | Description |
---|---|---|---|
Value | Any | ✓ | The target value(s) |
Returns: Null
Example:
prt "Hello, world!"
Pop
pop <list> [?output]
Removes the last item from a list and returns it.
Parameter | Type | Optional | Description |
---|---|---|---|
List | List | The list to use | |
Output | Variable | ✓ | The last item |
Returns: Any
Example:
new "list" ?list
psh list 5
pop list ?result
prt result list
:: 5 []
Power
pow <exp_1> <exp_2> <exp_n> <...> [result]
Takes all given exponents and powers them together in sequential order.
Parameter | Type | Optional | Description |
---|---|---|---|
Exponent 1 | Float or Integer or String | The first exponent | |
Exponent 2 | Float or Integer | The second exponent | |
Exponent N | Float or Integer | ✓ | The nth exponent |
Result | Variable | ✓ | The result |
Example:
pow 2 2 ?result
prt result
:: 4
Push
psh <list> <value>
Pushes an item into a list's stack.
Parameter | Type | Optional | Description |
---|---|---|---|
List | List | The list to use | |
Value | Any | The item to push |
Returns: Null
Example:
new "list" ?list
psh list 5
prt list
:: [5]
Read
read [prompt] [?output]
Gets input from the user.
Parameter | Type | Optional | Description |
---|---|---|---|
Prompt | Any | ✓ | The prompt outputted in the terminal |
Output | Any | ✓ | The user input |
Returns: Null
Example:
read "What is your name: " ?name
prt name
Random Number Generator
rng <minimum> <maximum> [?output]
Generates a random integer within the range. Both the minimum and maximum values are inclusive.
Parameter | Type | Optional | Description |
---|---|---|---|
Minimum | Integer | The minimum range | |
Maximum | Integer | The maximum range | |
Output | Variable | ✓ | The randomized integer within the range |
Returns: Integer
Example:
rng 0 5 ?myInteger
prt myInteger
Remove
rem <variable>
Deletes a variable from memory.
Parameter | Type | Optional | Description |
---|---|---|---|
Variable | Variable | The target variable |
Returns: Null
Example:
var 5 myInteger
prt myInteger
rem myInteger
prt myInteger
Repeat
rep <amount> <statement>
Executes a statement a set amount of times.
Parameter | Type | Optional | Description |
---|---|---|---|
Amount | Integer | The amount of times the statement will be executed | |
Statement | String | The statement in string form that will be executed |
Returns: Null
Example:
rep 5 "prt 'Hello, world!'"
Return
ret [value_1] [value_2] [value_n] [...]
Returns a value within a section.
Parameter | Type | Optional | Description |
---|---|---|---|
Value | any | The return value |
Returns: Null
Example:
:mySection
ret 5
Round
rnd <number> [precision] [?output]
Rounds a number to a certain decimal point.
If no precision is given, it is rounded to the nearest whole number instead.
Parameter | Type | Optional | Description |
---|---|---|---|
Number | Float or Integer | The number to round | |
Precision | Integer | ✓ | The precision to round to |
Output | Integer | ✓ | The rounded number |
Example:
var myInteger 5.5
rnd myInteger
prt myInteger
:: 6
Save
save <path> <value> [encoding]
Writes the content into a file.
Parameter | Type | Optional | Description |
---|---|---|---|
Path | String | The path of the file | |
Value | String | The content of the file | |
Encoding | String | ✓ | The file encoding (utf8 is the default) |
Returns: Null
Example:
save "file.xpp" "Hello, world!" "utf8"
Set
set <dict> <key> <value>
Sets a key-value pair inside the given dictionary.
Parameter | Type | Optional | Description |
---|---|---|---|
Dict | Dict | The dict to update | |
Key | Any | The key to use | |
Value | Any | The value of the key |
Returns: Null
Example:
new "dict" ?dict
set dict "x" "Hello, world!"
prt (get dict "x")
:: Hello, world!
prt dict
:: { "x": "Hello, world!" }
String
str <value> [?output]
Converts a value into a string.
If no output is given, the target value itself is converted instead.
Parameter | Type | Optional | Description |
---|---|---|---|
Value | Any | The target string | |
Output | Variable | ✓ | The converted string value |
Returns: String
Example:
str 5 ?myString
prt myString
:: "5"
Subtract
sub <term_1> <term_2> <term_n> <...> [?result]
Subtracts all given terms from eachother in order.
Parameter | Type | Optional | Description |
---|---|---|---|
Term 1 | Float or Integer | The first value | |
Term 2 | Float or Integer | The second value | |
Term N | Float or Integer | ✓ | The nth value |
Result | Variable | ✓ | The difference of all given terms |
Example:
sub 10 5 ?difference
prt difference
:: 5
Throw
thrw [message]
Throws an error message and exits the process.
Parameter | Type | Optional | Description |
---|---|---|---|
Message | Any | ✓ | The message of the error |
Returns: Null
Example:
prt "Hello, world!"
thrw "Error message!"
prt "Haha! Can't see me!"
Try
try <statement> [error statement]
Executes the statement. If an error is thrown, the exception statement is executed instead.
Parameter | Type | Optional | Description |
---|---|---|---|
Statement | String | The statement in string form that will be executed | |
Error Statement | String | ✓ | The statement in string form that will be executed if an error is thrown |
Returns: Null
Example:
try "thrw 'Error message!'" "prt 'An error has occurred'"
:: An error has occured
Uppercase
upr <string> [?output]
Uppercases all the characters in a string.
If no output is given, the target value itself is uppercased instead.
Returns: String
Example:
upr "Hello, world!" ?output
prt output
Wait
wait <seconds>
Waits a certain number of seconds before executing the next statement.
Parameter | Type | Optional | Description |
---|---|---|---|
Seconds | Integer | The number of seconds to wait |
Returns: Null
Example:
prt "Hello, world!"
wait 5
prt "Hello, world!"
While
whl <expression> <statement>
Executes the statement until the expression is false.
Parameter | Type | Optional | Description |
---|---|---|---|
Expression | Expression | The target expression | |
Statement | String | The statement in string form that will be executed while the expression is true |
Returns: Null
Example:
:mySection a
out a
inc a
ret a
var myInteger 0
whl (myInteger < 5) "jmp mySection myInteger ?myInteger"
:: 0
:: 1
:: 2
:: 3
:: 4
Variable
var <value> <variable>
Defines a variable.
Parameter | Type | Optional | Description |
---|---|---|---|
Value | Any | The value that will be stored in the variable | |
Variable | Variable | The target variable |
Returns: Null
Example:
var 5 myInteger
prt myInteger
Last Updated: March 9th, 2024 by iiPython
x++ / Documents / Packages
Table of Contents
About
Packages are x++ files written by other people that can be imported to your x++ project using the imp
operator:
imp "examplePackage"
All packages are located in the pkgs/
folder. If one is not found, the interpreter will automatically create one. When attempting to import a package, the interpreter will look for the pkgs/<package>/main.xpp
file. If one is not found, an error is thrown.
Imported packages are only available in that one specific file. When attempting to use the package elsewhere, an error is thrown.
You can use an imported package by referencing the package name and then followed by a dot and the section name like so:
imp "examplePackage"
examplePackage.mySection
The same applies to importing files.
To import a file from the x++ project, the path must contain the .xpp
extension. The interpreter will then attempt to find the file from the current working directory. If one is not found, an error is thrown.
Currently, the standard library is built into the x++ interpreter. You can install more packages from GitHub.
Last Updated: March 9th, 2024 by iiPython
x++ / Documents / Sections
Table of Contents
About
A section is a set of statements that get executed when using the jmp
operator. They are always loaded first when the file is executed or imported.
Sections always start with a colon :
, and their name can only contain alphabetical letters:
:mySection
Statements that are not within a section are located in the global section predefined by the interpreter. The global section cannot be referenced, interacted with, or called, as it is deleted as soon as the file is executed or imported.
A section can also take arguments. Any variables separated by space and placed directly after the section name are considered arguments:
:myMethod argument0 argument1
All arguments of a method or a function must be passed. An error is thrown if an argument is missing.
Since the release of x2.3, only one type of section exists in x++.
A section that takes (or doesn't take) additional arguments and (may or may not) return a value is considered a function
and can be invoked using the jmp
operator.
jmp myFunction 1 2 ?output
prt output :: 3
:myFunction a b
add a b c
ret c
Last Updated: March 9th, 2024 by iiPython
x++ / Documents / Variables
Table of Contents
About
A variable is a label that stores a value that can be referenced and modified at any time.
Even though a variable can contain any character besides spaces, it is recommended to use only alphabetical letters. A variable is defined using the var
operator:
var myInteger 5
A variable can then be referenced using the variable name:
prt myInteger
By default, a variable is scoped, or local, which means it can only be referenced within the section it was defined in. Once the section is ended, the variables are garbage collected to save memory.
There are two other types of variables, file variable
and global variable
. A file variable can be referenced by any sections within the same file, while a global variable can be referenced anywhere in the project.
A file variable is defined by appending an at symbol (@
) in front of the variable name:
var @myInteger 5
A global variable is unable to be defined using x++ syntax. However, you can use Python Integration to do so.
Both local and file variables are automatically garbage collected, but they can also be manually deleted from RAM using the rem
operator:
:: Removes BOTH myInteger AND @myInteger
rem myInteger @myInteger
Last Updated: March 9th, 2024 by iiPython
x++ / Python API
Table of Contents
- Home
- Tutorials
- Documents
- Python API ▾
- Caffeine
- Standard Library
Introduction
Welcome to the x++ Python API documentation.
This page will cover how to integrate the Python programming language into your x++ projects.
Definitions
Before attempting to integrate Python with your x++ project, please ensure you never install (and especially don't import) untrusted or random Python modules. Code inside these modules will have unrestricted access to the host computer and can do everything from adding you to a botnet to completely destroying your PC.
With that being said, here's some loose terms that will be used throughout this document:
- Module
- A Python file that is being imported using the
imp
operator
- A Python file that is being imported using the
- Packages Folder
- This will normally be the
pkgs
folder inside your current working directory.
- This will normally be the
Inline statements
x++ comes with the built-in evl
operator, which will execute the given Python code with access to all internal classes and methods. This makes it easy to execute small amounts of Python code in an x++ program.
If you need custom operators, newlines, or large pieces of Python, please see Python modules.
The most basic syntax for an evaluation statement is as follows:
prt "the following statement will be executed by python:"
:: actually run our code
evl "print('hello, world! this is python')"
This "live" Python environment has access to the following globals:
mem
(see datastore.py)interpreter
(the x++ interpreter; see interpreter.py)vars
(all current variables; see datastore.py)version
(current x++ version)
These globals, in theory, should allow you to customize the x++ runtime as much as desired.
Python modules
The built-in imp
operator not only allows you to import x++ files, but also allows the importing of modules inside the packages folder. For example, if you have the following inside example.py
:
# example.py
print("Hello from example.py!")
Then you can do the following from inside x++:
imp "example.py"
:: example.py will of ran by now, so the terminal should say hello
However, this is a very bad usage of Python importing. For something this small, it is recommended to just use inline statements.
Now for the fun stuff.
Python modules imported via the imp
operator are loaded using the x++ operator loader. This means you have the ability to create custom operators at runtime and use them in your x++ code.
Take the following Python module:
# example.py
class XOperators:
def some_operator(mem, args):
print("Hello! some_operator is running!")
print(mem) # Contains cli_vals, variables, and other things
print(args) # List of Datastore() objects
You can now use some_operator
inside x++:
imp "example.py"
some_operator "some arguments" 1 2 3 4 5
Additionally, arguments can be processed via ctx.args
.
Python inside .xconfig
If your x++ module has a .xconfig
file (as it should), you can set the main
argument to a Python file and use it as your entrypoint. An example .xconfig
file is as follows:
{
"main": "example.py"
}
Assuming you had that .xconfig
file located at pkgs/example/.xconfig
and moved example.py
to pkgs/example/example.py
then you could do the following from within x++:
:: since .xconfig says to run example.py from inside pkgs/example
:: this will load any operators from inside the file
imp "example"
some_operator
:: it should of printed hello to the screen again
Last Updated: July 5th, 2023 by iiPython
x++ / Caffeine
Table of Contents
Introduction
Caffeine is a x++ to Python conversion module and CLI. It converts your existing code to Python for performance improvements or just general codebase migration.
It's included with x++ since version 3.1.2 and is available globally as the Python package caffeine
.
It implements all features available in xpp except for imports.
Basic Usage
If you had a file called main.xpp
and wanted to convert it to Python, you could do something like this:
caffeine main.xpp
This will give you a main.py
file in the same directory.
Another feature is auto minification of the resulting Python code via the -1
flag.
To convert main.xpp
to minified Python, you would run:
caffeine -o -1 main.xpp
Notice the -o
in there? That stands for overwrite
, so caffeine will write over the existing main.py
file (if it exists).
Lastly, Caffeine supports automatic building via pyinstaller.
To convert main.xpp
to an exe (or binary, depending on your OS) and then run it automatically, you can do something like this:
caffeine -o -r -b main.xpp
This will give you a main
file and will run it automatically after pyinstaller builds it.
However, this obviouslly requires that you have pyinstaller installed and added to system PATH.
Notice
Run caffeine --help
for more up to date and accurate information then these docs can provide.
Last Updated: March 9th, 2024 by iiPython
x++ / Standard Library
Table of Contents
- Home
- Tutorials
- Documents
- Python API
- Caffeine
- Standard Library ▾
Introduction
The x++ standard library is not currently finished, so no documentation is available yet.
Last Updated: March 9th, 2024 by iiPython