xpp


an interpreted, minimalistic programming language

License Downloads Last commit Repo size Stars

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

↑ Go To Top

x++ / Tutorials

Table of Contents

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

↑ Go To Top

x++ / Tutorials / 1. Hello, world!

Table of Contents

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

↑ Go To Top

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

↑ Go To Top

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

↑ Go To Top

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

↑ Go To Top

x++ / Documents

Table of Contents

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

↑ Go To Top

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

↑ Go To Top

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.

ParameterTypeDescription
SourceAnyThe variable or value that is being compared against
TargetAnyThe 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.

ParameterTypeDescription
SourceAnyThe variable or value that is being compared against
TargetAnyThe 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.

ParameterTypeDescription
SourceFloat or Integer or StringThe variable or value that is being compared against
TargetFloat or Integer or StringThe 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.

ParameterTypeDescription
SourceFloat or Integer or StringThe variable or value that is being compared against
TargetFloat or Integer or StringThe 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.

ParameterTypeDescription
SourceFloat or Integer or StringThe variable or value that is being compared against
TargetFloat or Integer or StringThe 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.

ParameterTypeDescription
SourceFloat or Integer or StringThe variable or value that is being compared against
TargetFloat or Integer or StringThe variable or value being compared to

Example:

if (10 >= 5) "prt 'true'"

In

<source> in <target>

Checks if the source is in the target.

ParameterTypeDescription
SourceAnyThe variable or value that is being compared against
TargetAnyThe 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.

ParameterTypeDescription
SourceAnyThe variable or value that is being compared against
TargetAnyThe 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.

ParameterTypeDescription
SourceAnyThe variable or value that is being compared against
TargetStringThe variable or value being compared to

Example:

if (5 is "int") "prt 'true'"

Last Updated: March 9th, 2024 by iiPython

↑ Go To Top

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.

ParameterTypeDefaultDescription
PathString<JSON>"main.xpp"Entrypoint relative to the current package (or cwd if it's a file)

Last Updated: March 9th, 2024 by iiPython

↑ Go To Top

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 0s 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 CodeDescriptionExampleResultWidely-Supported
Normalprt "Hello, world!"Hello, world!
\\Backslash characterprt "Hello,\\world!"Hello,\world!
\'Single-quote characterprt "\'Hello, world!\'"'Hello, world!'
\"Double-quote characterprt "\"Hello, world!\"""Hello, world!"
\aTriggers Notification Soundprt "\a"
\bBackspaceprt "Hello,\bworld!"Helloworld!
\fForm Feedprt "Hello,\fworld!"Hello,
world!
\nLine Feedprt "Hello,\nworld!"Hello,
world!
\rCarriage Returnprt "Hello,\rworld!"world!
\tHorizontal Tabprt "Hello,\tworld!"Hello,  world!
\vVerticle Tabprt "Hello,\vworld!"Hello,
world!
\oooOctal Valueprt "\110\145\154\154\157\54\40\167\157\162\154\144\41"Hello, world!
\xhhHex Valueprt "\x48\x65\x6C\x6C\x6F\x2C\x20\x77\x6F\x72\x6C\x64\x21"Hello, world!
\N{name}Unicode Nameprt "Hello,\N{grinning face}world!"Hello,😀world!
\uhhhh16-Bit Unicode Escapeprt "\u0048\u0065\u006c\u006c\u006f\u002c\u0020\u0077\u006f\u0072\u006c\u0064\u0021"Hello, world!
\Uhhhhhhhh32-Bit Unicode Escapeprt "Hello,\U0001F600world!"Hello,😀world!
\033[ANSI Escapeprt "\033[31mHello, world!\033[0m"Hello, world! in red

Source: Python DS - Python 3 Escape Sequences

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

↑ Go To Top

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.

ParameterTypeOptionalDescription
Addend AFloat or Integer or StringThe first addend
Addend BFloat or Integer or StringThe second addend
SumVariableThe 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.

ParameterTypeOptionalDescription
StringStringThe target string
IndexIntegerThe index of the string
StopIntegerThe index of the string
OutputVariableThe 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.

ParameterTypeOptionalDescription
Value(s)Float or IntegerThe value that will be decremented
OutputVariableThe decremented value

Returns: Float or Integer

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).

ParameterTypeOptionalDescription
DividendFloat or IntegerThe value that is being divided
Divisor(s)Float or IntegerThe value that is dividing the dividend
QuotientVariableThe quotient of the dividend and the divisor

Returns: Float or Integer

Example:

div 10 5 ?quotient
prt quotient
:: 2

Evaluate

evl <code>

Evaluate and execute Python code.

ParameterTypeOptionalDescription
CodeStringThe 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.

ParameterTypeOptionalDescription
StringStringThe target string
OutputVariableThe 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.

ParameterTypeOptionalDescription
ObjectDictThe source object
KeyAnyThe key to retrieve
OutputVariableThe 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.

ParameterTypeOptionalDescription
Expression 1ExpressionThe first expression
Branch 1StringStatement to execute if first branch is true
Expression NExpressionThe nth expression
Branch NStringStatement to execute if nth branch is true
Else BranchStringStatement 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.

ParameterTypeOptionalDescription
Package / FileStringThe path of package or file you want to import
NameStringThe 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.

ParameterTypeOptionalDescription
StringStringThe target string
SubstringStringThe substring of the target string
OutputVariableThe 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.

ParameterTypeOptionalDescription
Value(s)Float or IntegerThe value that will be incremented
OutputVariableThe incremented value

Returns: Float or Integer

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).

ParameterTypeOptionalDescription
SectionSectionThe target section
...Arguments...AnyThe arguments passed to the target section
...OutputsVariableThe 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.

ParameterTypeOptionalDescription
StringStringThe target string
OutputVariableThe 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.

ParameterTypeOptionalDescription
PathStringThe path of the file
OutputVariableThe 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.

ParameterTypeOptionalDescription
StringStringThe target string
OutputVariableThe lowercased string

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.

ParameterTypeOptionalDescription
Factor 1Float or Integer or StringThe first factor
Factor 2Float or IntegerThe second factor
Factor NFloat or IntegerThe nth factor
ProductVariableThe 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.

ParameterTypeOptionalDescription
TypeString'list' or 'dict'
OutputVariableThe new object

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.

ParameterTypeOptionalDescription
StringStringThe target string
OutputVariableThe converted number value

Returns: Integer

Example:

int "5" ?myInteger
prt myInteger
:: 5

Print

prt [...value]

Prints value(s) into the terminal.

ParameterTypeOptionalDescription
ValueAnyThe target value(s)

Returns: Null

Example:

prt "Hello, world!"

Pop

pop <list> [?output]

Removes the last item from a list and returns it.

ParameterTypeOptionalDescription
ListListThe list to use
OutputVariableThe 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.

ParameterTypeOptionalDescription
Exponent 1Float or Integer or StringThe first exponent
Exponent 2Float or IntegerThe second exponent
Exponent NFloat or IntegerThe nth exponent
ResultVariableThe result

Returns: Float or Integer

Example:

pow 2 2 ?result
prt result
:: 4

Push

psh <list> <value>

Pushes an item into a list's stack.

ParameterTypeOptionalDescription
ListListThe list to use
ValueAnyThe item to push

Returns: Null

Example:

new "list" ?list
psh list 5
prt list
:: [5]

Read

read [prompt] [?output]

Gets input from the user.

ParameterTypeOptionalDescription
PromptAnyThe prompt outputted in the terminal
OutputAnyThe 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.

ParameterTypeOptionalDescription
MinimumIntegerThe minimum range
MaximumIntegerThe maximum range
OutputVariableThe randomized integer within the range

Returns: Integer

Example:

rng 0 5 ?myInteger
prt myInteger

Remove

rem <variable>

Deletes a variable from memory.

ParameterTypeOptionalDescription
VariableVariableThe 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.

ParameterTypeOptionalDescription
AmountIntegerThe amount of times the statement will be executed
StatementStringThe 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.

ParameterTypeOptionalDescription
ValueanyThe 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.

ParameterTypeOptionalDescription
NumberFloat or IntegerThe number to round
PrecisionIntegerThe precision to round to
OutputIntegerThe rounded number

Returns: Float or Integer

Example:

var myInteger 5.5
rnd myInteger
prt myInteger
:: 6

Save

save <path> <value> [encoding]

Writes the content into a file.

ParameterTypeOptionalDescription
PathStringThe path of the file
ValueStringThe content of the file
EncodingStringThe 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.

ParameterTypeOptionalDescription
DictDictThe dict to update
KeyAnyThe key to use
ValueAnyThe 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.

ParameterTypeOptionalDescription
ValueAnyThe target string
OutputVariableThe 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.

ParameterTypeOptionalDescription
Term 1Float or IntegerThe first value
Term 2Float or IntegerThe second value
Term NFloat or IntegerThe nth value
ResultVariableThe difference of all given terms

Returns: Float or Integer

Example:

sub 10 5 ?difference
prt difference
:: 5

Throw

thrw [message]

Throws an error message and exits the process.

ParameterTypeOptionalDescription
MessageAnyThe 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.

ParameterTypeOptionalDescription
StatementStringThe statement in string form that will be executed
Error StatementStringThe 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.

ParameterTypeOptionalDescription
StringStringThe target string
OutputVariableThe uppercased string

Returns: String

Example:

upr "Hello, world!" ?output
prt output

Wait

wait <seconds>

Waits a certain number of seconds before executing the next statement.

ParameterTypeOptionalDescription
SecondsIntegerThe 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.

ParameterTypeOptionalDescription
ExpressionExpressionThe target expression
StatementStringThe 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.

ParameterTypeOptionalDescription
ValueAnyThe value that will be stored in the variable
VariableVariableThe target variable

Returns: Null

Example:

var 5 myInteger
prt myInteger

Last Updated: March 9th, 2024 by iiPython

↑ Go To Top

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

↑ Go To Top

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

↑ Go To Top

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

↑ Go To Top

x++ / Python API

Table of Contents

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
  • Packages Folder
    • This will normally be the pkgs folder inside your current working directory.

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:

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

↑ Go To Top

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

↑ Go To Top

x++ / Standard Library

Table of Contents

Introduction

The x++ standard library is not currently finished, so no documentation is available yet.


Last Updated: March 9th, 2024 by iiPython

↑ Go To Top