README
This is the introduction to ApLang, a tool designed to help you excel in your AP Computer Science Principles class and score higher on your AP test.
The purpose of this guide is not to replace your teacher but to get you acquainted with ApLang and serve as a reference while you are programming. It assumes you have some very basic knowledge of programming but are still a beginner.
Back in the early days of personal computing, computers often came with a manual that was absolutely indispensable. It was difficult to accomplish much without that manual. Let this guide be your modern equivalent—your go-to resource for learning ApLang.
Some of ApLangs syntax is garbage. Sorry about that...I did not design it. It was designed lovingly by committee at Collage Board head quarters.
Standard Library Documentation
This book also contains the documentation for the standard library. Documentation explains how each standard library module's functions work.
About
ApLang was created using the programming language Rust. Rust was chosen primarily for its ability to "run anywhere" (thanks to LLVM <3) and its excellent package manager, Cargo. ApLang is an interpreted language, meaning it is executed without being compiled first, making it easy to use and accessible to as many people as possible.
Links
- Website (You are here)
- ApLang Repo
- ApLang Book Repo
- ApLang VSCode Plugin Repo
Installation
This section will guide you through the process of setting up aplang
.
Troubleshooting
If you encounter any issues during the installation process, here are a few troubleshooting tips:
-
If you have trouble installing Visual Studio Code, please refer to the official documentation
-
Command not found: If you see a "command not found" error when running
cargo
oraplang
, ensure that your terminal’sPATH
environment variable includes the directory where Cargo installs binaries. This is usually$HOME/.cargo/bin
on Unix-like systems or%USERPROFILE%\.cargo\bin
on Windows. You may need to add this directory to yourPATH
manually. -
Rust or Cargo not installed: If Cargo is not installed, double-check that you followed the installation steps correctly. Make sure you have a stable internet connection and that you followed all prompts during installation.
-
Permissions issues: If you encounter permissions issues, try running the command with
sudo
(on Unix-like systems) or as an administrator (on Windows). However, be cautious with usingsudo
and only use it when necessary.
Install ApLang
With Cargo (All Platforms)
Step 1: Install Rust and Cargo
Before you can install aplang
, you need to have Rust and Cargo installed on your computer. Cargo is the package manager and build system for the Rust programming language, and it comes bundled with Rust.
1.1 Install Rust and Cargo
-
Visit the Rust installation page: Open your web browser and go to https://rustup.rs.
-
Follow the installation instructions: The Rust installation page will automatically detect your operating system and provide you with detailed instructions on how to install Rust and Cargo. Follow the instructions provided for your specific operating system (Linux, macOS, or Windows).
-
Complete the installation: The installer will guide you through the installation process. Make sure to follow all the steps, including any prompts to modify your system’s
PATH
environment variable. This will ensure that Cargo commands are available in your terminal or command prompt. -
Restart your terminal or command prompt: After installation, restart your terminal (Linux or macOS) or command prompt (Windows) to make sure the changes take effect.
1.2 Verify the Installation
To confirm that Rust and Cargo are installed correctly, open your terminal (Linux or macOS) or Command Prompt/PowerShell (Windows) and run:
cargo --version
If the installation was successful, this command will display the version of Cargo installed, such as cargo 1.65.0 (0e8d5a6 2022-09-27)
.
Step 2: Install the aplang
Binary
Now that you have Cargo installed, you can install the aplang
binary.
2.1 Install aplang
Using Cargo
-
Open your terminal or Command Prompt: Make sure your terminal (Linux/macOS) or Command Prompt/PowerShell (Windows) is open.
-
Run the installation command: Type the following command and press Enter:
cargo install aplang
Cargo will fetch the
aplang
package from the online registry, compile it, and install it on your system. This process may take a few minutes, depending on your internet speed and system performance. -
Wait for the installation to complete: Cargo will display messages as it compiles and installs the binary. Once the process is complete, you should see a message indicating that
aplang
has been installed successfully.
Step 3: Verify the Installation of aplang
After installation, you should verify that aplang
is correctly installed and can be used as a standalone program.
3.1 Check the Installation
-
Run the
aplang
command: In your terminal or Command Prompt, type the following command and press Enter:aplang --version
If installed correctly, this command will display the version of
aplang
that you installed, confirming that the installation was successful.
Step 4: Use aplang
as a Standalone Program
Now that aplang
is installed, you can use it as a standalone program.
4.1 Running aplang
To run aplang
, simply type aplang
followed by any arguments or options you want to use. For example:
aplang --help
This command will display the help information for aplang
, showing you the available commands and options.
Troubleshooting
Configure Your Development Environment
To start working on aplang projects, it is recommended to use Visual Studio Code (VS Code). Git is not strictly required, but it is highly recommended for version control.
Step 1: Install GitHub Desktop and Git VCS
Install GitHub Desktop
-
Download GitHub Desktop:
- Go to the GitHub Desktop website.
- Download the installer for your operating system.
-
Install GitHub Desktop:
- Windows/macOS: Run the installer and follow the prompts to complete the installation.
- Linux: See your individual distributions documentation for installation information.
- Git version control should automatically be installed by GitHub Desktop.
Step 2: Install Visual Studio Code (VS Code)
Install VS Code on Windows
-
Visit the VS Code download page: VS Code Download.
-
Download the installer for Windows: Click on the "Windows" download link.
-
Run the installer: Double-click the installer file (
VSCodeSetup-x64-<version>.exe
). -
**Follow the on-screen installation prompts.
- Make sure to check "Add to PATH"
- Also check "Register code as an editor for supported file types"
- OPTIONAL: "Add to context menu"
Install VS Code on Linux
- Install VSCode with your distro's package manager
- If you need help, refer to the installation documentation
Install VS Code on macOS
-
Visit the VS Code download page: VS Code Download.
-
Download the installer for macOS: Click on the "macOS" download link to download a
.zip
file. -
Install VS Code:
- Open the
.zip
file to extract the contents. - Drag the extracted
Visual Studio Code.app
file to your "Applications" folder.
- Open the
Step 3: Set Up a Project Directory
Create a GitHub Repository with GitHub Desktop
-
Open GitHub Desktop: Launch the GitHub Desktop application.
-
Create a New Repository:
- Click on "File" > "New Repository."
- Fill in the repository name and choose the local path where you want to create the repository.
- We recommend using the default path.
- Click "Create Repository."
Open the Project Directory in VS Code
Using GitHub Desktop:
- In GitHub Desktop, make sure your repository is selected.
- Click on the "Repository" menu, then select "Open in Visual Studio Code." This will open the repository in VS Code.
Alternative Method:
- If the "Open in Visual Studio Code" button is not available, click on the "Show in Explorer" (Windows) or "Show in Finder" (macOS) button to open the repository folder in your file explorer.
- Right-click the folder and select "Open with Code" (if this option is available) or open VS Code, click on "File" > "Open Folder..." and navigate to your repository directory.
Create the main.ap
File
-
Open VS Code: Launch Visual Studio Code.
-
Create a New File: Click on "File" > "New File" or press
Ctrl + N
(Cmd + N
on macOS). -
Add Code: Enter the following code into your file
DISPLAY("Hello World!")
-
Save the File: Click on "File" > "Save As..." or press
Ctrl + S
(Cmd + S
on macOS). Name the filemain.ap
and save it in your project directory. -
(Recommended): Also Enable autosave from from the "File" context menu.
Step 4: Install the VSCode Extension
-
Find the Extension in the Visual Studio Marketplace: It is available here
- Alternatively, search for ApLang in the "Extensions" tab in Visual Studio Code
-
Install the Extension: Press the install
Install
button.
Step 5: Run the main.ap
File with the aplang
Binary
-
Open Integrated Terminal in VS Code:
- Go to "View" > "Terminal" or press
Ctrl + `
.
- Go to "View" > "Terminal" or press
-
Run the File: In the terminal, navigate to the directory containing
main.ap
and run the file using theaplang
binary. You should see the outputHello World!
in your console.
Conclusion
Congratulations! You have successfully setup an aplang
project. You can now begin to develop more complex programs using aplang
. You are ready to begin following along with the rest of this book.
Troubleshooting
Basics
Congratulations! You have successfully installed ApLang and configured your development environment! If you haven't done that yet, please see the Installation section.
Introducing the .ap
file! For legal reasons, .ap
doesn't stand for Advanced Placement; it stands for something else... uh... Apple Pie! Yep!
Disclaimer: The term ".ap" is a proprietary file extension of ApLang, hereinafter referred to as "Apple Pie." Any resemblance to actual file extensions, past or present, is purely coincidental. By using the ".ap" file extension, you agree to bake, metaphorically or otherwise, a delicious apple pie, and hereby release ApLang and all affiliates from any claims, demands, or disputes arising from or in connection with your pie-making activities. All rights reserved. Terms and conditions apply. Batteries not included. Consult your local baker for details.
The main.ap
file is where you place your code. If you have not created it yet please do so now. It does not have to be called main.ap
but that is the conventional name. It must end with a .ap
file extension. When you are ready to run your code, you will call the interpreter that you just installed. Run the following command in your console to execute your code:
aplang main.ap
aplang
will then execute your file. Watch your console for any output your code may produce.
Hello World
Welcome to your first ApLang program! We'll start with the classic "Hello, World!" example, a simple program that displays text on the screen. This program introduces the DISPLAY
procedure, which you can use to print text.
// This is a comment.
// Comments are ignored by the interpreter.
// Display text on the console
DISPLAY("Hello, World!")
// ^^^^^^^^^^^^^^^^
// String Literal
Let's break this down:
DISPLAY
: This procedure (sometimes called a function) outputs the text you provide to the console."Hello, World!"
: The text inside the quotation marks is called a "String Literal." A string is a sequence of characters. In this case, "Hello, World!" is the string we want to display.
Comments
Comments are an essential part of programming. They help you and others understand your code by providing explanations or notes. In ApLang, comments are not executed as part of your program; They are completely ignored by the interpreter.
There are two types of comments in ApLang:
Line Comments
Line comments start with //
and continue until the end of the line.
// This is a line comment. It explains the code below.
DISPLAY("Hello, World!")
Block Comments
Block comments start with /*
and end with */
. Everything between these markers is ignored by the interpreter.
/*
This is a block comment.
It can span multiple lines.
*/
DISPLAY("Hello, World!")
Commenting Guidelines
Writing good comments is an important skill for making your code more readable and maintainable. Here are some guidelines for writing effective comments:
- DO: Use comments to explain complex or non-obvious sections of code.
- DO: Use comments to provide context on why certain decisions were made.
- DO: Document design decisions, especially any trade-offs or compromises.
- DON'T: Use comments as a substitute for clear and descriptive variable or function names.
- DON'T: Write comments that simply restate what the code does; focus on the "why."
Example of Effective Comments
Let's look at an example of how to use comments effectively:
// Poor Commenting:
// Increment the margin by 2
margin <- margin + 2
// Better Commenting:
// Increase margin to account for the 2-pixel border of the render box
margin <- margin + 2
// Best Comment:
// Account for 2-px border of render box
margin <- margin + 2
In the first example, the comment just restates what the code does, which is redundant. The improved version explains why the margin is increased, providing valuable context.
Types
ApLang, like many programming languages, uses various types to represent different kinds of data. Understanding these types is fundamental to writing effective programs.
Values
In ApLang, a value is a piece of data that has a type. The main types of values you will encounter are:
- Number: Represents floating-point numbers.
- String: Represents text.
- Boolean: Represents a truth value, either
TRUE
orFALSE
. - List: Represents a series of values.
Numbers
Numbers in ApLang are similar to numbers in mathematics. They can be whole numbers (integers) or have a decimal point (floating-point numbers). In ApLang, all numbers are represented as f64
, which means they are 64-bit floating-point numbers. This allows for a wide range of values, both large and small, with high precision.
DISPLAY(42) // This is a number.
DISPLAY(3.1415) // This is also a number, with a decimal point.
Strings
A string is a sequence of characters, used to represent text. Strings are created by placing text inside quotation marks ("
).
DISPLAY("Hello, ApLang!") // This is a string.
Strings can contain letters, numbers, symbols, and spaces. They are very useful for storing and manipulating text data.
Example: Creating and Displaying Strings
// Create a string variable
my_text <- "This is a string."
// Display the string
DISPLAY(my_text)
In the example above, my_text
is a variable that stores the string "This is a string."
. The DISPLAY
procedure outputs the value of my_text
to the console.
Booleans
A Boolean is a type that can have one of two values: TRUE
or FALSE
. Booleans are often used in conditional statements to control the flow of a program based on certain conditions.
DISPLAY(TRUE) // This is a boolean value.
DISPLAY(FALSE) // This is another boolean value.
Booleans are essential for making decisions in your programs. For example, you can use them to check if a condition is met and then execute different code based on the result.
Example: Using Booleans in Conditional Statements
is_ready <- TRUE
// Check if is_ready is TRUE
IF (is_ready) {
DISPLAY("Ready to go!")
} ELSE {
DISPLAY("Not ready yet.")
}
In this example, the program checks the value of is_ready
. If it is TRUE
, it displays "Ready to go!" Otherwise, it displays "Not ready yet."
Lists
A list is a collection of values. Lists in ApLang are versatile and can hold multiple values of different types, but they are unique in that they are the only type passed by reference rather than by value. This means when you pass a list to a function or assign it to another variable, you are referencing the same list in memory, not copying it.
Creating a List
Lists are created using square brackets ([]
) with values separated by commas:
my_list <- ["a", "b", "c", "d"]
DISPLAY(my_list)
This list contains four string elements: "a"
, "b"
, "c"
, and "d"
.
Understanding Lists as References
Since lists are passed by reference, modifying a list in one place affects all references to that list.
numbers <- [1, 2, 3]
more_numbers <- numbers
// Modify the list through more_numbers
APPEND(more_numbers, 4)
DISPLAY(numbers) // Output: [1, 2, 3, 4]
DISPLAY(more_numbers) // Output: [1, 2, 3, 4]
In this example, numbers
and more_numbers
both refer to the same list in memory. When we append 4
to more_numbers
, numbers
is also affected because they reference the same data.
Example: Using Lists
// Create a list of numbers
my_numbers <- [10, 20, 30, 40]
// Accessing elements
DISPLAY(my_numbers[1]) // Output: 10
DISPLAY(my_numbers[3]) // Output: 30
// Modifying elements
my_numbers[2] <- 25
DISPLAY(my_numbers) // Output: [10, 25, 30, 40]
In the example above, my_numbers
is a list of numbers. We can access elements using an index (starting at 1) and modify elements by assigning a new value to a specific index.
Expressions
Expressions are a core concept in ApLang. They represent values or computations that produce values. In ApLang, you can use expressions to perform arithmetic operations, manipulate strings and lists, call functions, and evaluate logical conditions. This chapter will introduce you to the different types of expressions available in ApLang and how to use them effectively.
Arithmetic Expressions
Arithmetic expressions in ApLang allow you to perform basic mathematical operations. ApLang supports the following arithmetic operators:
+
(addition)-
(subtraction)*
(multiplication)/
(division)MOD
(modulo)
Example: Arithmetic Operations
// Addition
sum <- 5 + 3
DISPLAY(sum) // Output: 8
// Subtraction
difference <- 10 - 4
DISPLAY(difference) // Output: 6
// Multiplication
product <- 7 * 2
DISPLAY(product) // Output: 14
// Division
quotient <- 8 / 2
DISPLAY(quotient) // Output: 4
// Modulo (remainder of division)
remainder <- 9 MOD 4
DISPLAY(remainder) // Output: 1
In these examples, each expression calculates a result using arithmetic operators and assigns the result to a variable.
String and List Concatenation
ApLang supports string and list concatenation using the +
operator. Concatenation combines two strings or two lists into one.
Example: String Concatenation
greeting <- "Hello, "
name <- "World!"
full_greeting <- greeting + name
DISPLAY(full_greeting) // Output: "Hello, World!"
Example: List Concatenation
list1 <- [1, 2, 3]
list2 <- [4, 5, 6]
combined_list <- list1 + list2
DISPLAY(combined_list) // Output: [1, 2, 3, 4, 5, 6]
These examples show how the +
operator can be used to concatenate strings and lists, creating a new string or list that combines the contents of both operands.
Function Calls as Expressions
Function calls in ApLang are expressions that evaluate to the return value of the function. You can use function calls wherever expressions are allowed.
Example: Using Function Calls
PROCEDURE square(x) {
RETURN x * x
}
result <- square(4)
DISPLAY(result) // Output: 16
In this example, square(4)
is an expression that calls the square
function with the argument 4
and returns the result.
Logical Expressions
Logical expressions evaluate to boolean values (TRUE
or FALSE
) and are used to make decisions in your programs. ApLang supports several logical operators:
NOT
(logical negation)AND
(logical conjunction)OR
(logical disjunction)
Example: Logical Operations
a <- TRUE
b <- FALSE
// Logical NOT
not_a <- NOT a
DISPLAY(not_a) // Output: FALSE
// Logical AND
and_result <- a AND b
DISPLAY(and_result) // Output: FALSE
// Logical OR
or_result <- a OR b
DISPLAY(or_result) // Output: TRUE
Logical expressions are crucial for controlling the flow of your program using conditional statements.
Comparison Expressions
Comparison expressions are used to compare values and produce boolean results. ApLang supports the following comparison operators:
==
(equal to)!=
(not equal to)>
(greater than)<
(less than)>=
(greater than or equal to)<=
(less than or equal to)
Example: Comparison Operations
x <- 5
y <- 10
DISPLAY(x == y) // Output: FALSE
DISPLAY(x != y) // Output: TRUE
DISPLAY(x > y) // Output: FALSE
DISPLAY(x < y) // Output: TRUE
DISPLAY(x >= y) // Output: FALSE
DISPLAY(x <= y) // Output: TRUE
These expressions evaluate to TRUE
or FALSE
based on the comparison of x
and y
.
Combined Expressions
Expressions in ApLang can be combined to perform more complex calculations or evaluations. By using parentheses ()
to group expressions, you can control the order of operations.
Example: Combining Expressions
a <- 2
b <- 3
c <- 4
result <- (a + b) * c // Parentheses change the order of operations
DISPLAY(result) // Output: 20
In this example, the expression (a + b)
is evaluated first, followed by multiplication by c
, resulting in 20
.
Conclusion
Expressions are a powerful tool in ApLang, enabling you to perform a wide range of operations and calculations. By mastering arithmetic, string, list, logical, and comparison expressions, you can create more dynamic and efficient programs. Remember to use parentheses to control the order of operations to ensure your expressions evaluate as intended.
Variables
Variables in ApLang are used to store and manage data. By assigning values to variables, you can reference and manipulate them throughout your program. This chapter will introduce you to the basics of variables, including how to create them, assign values, and use them effectively.
Creating Variables
To create a variable in ApLang, you use the assignment operator <-
. This operator assigns the value on the right-hand side to the variable on the left-hand side.
// Create a variable named 'x' and assign it the value 10
x <- 10
DISPLAY(x) // Output: 10
In the example above, the variable x
is created and assigned the value 10
. You can think of x
as a label that points to the value 10
.
Variable Naming
Variable names in ApLang can contain letters, digits, and underscores (_
). However, they must start with a letter. Good variable names are descriptive and make your code easier to understand.
// Create a variable with a descriptive name
apples_in_basket <- 5
DISPLAY(apples_in_basket) // Output: 5
Reassigning Variables
Variables in ApLang are mutable, meaning their values can be changed after they are created. To change the value of a variable, simply use the assignment operator <-
again with a new value.
// Create a variable and assign a value
count <- 1
DISPLAY(count) // Output: 1
// Reassign the variable with a new value
count <- 2
DISPLAY(count) // Output: 2
In this example, the variable count
is initially set to 1
and then changed to 2
.
Using Variables in Expressions
Variables can be used in expressions just like literal values. You can perform operations with variables and assign the result to another variable or even back to the same variable.
// Create variables
a <- 5
b <- 3
// Use variables in expressions
sum <- a + b
DISPLAY(sum) // Output: 8
// Update variable value using itself
a <- a + 1
DISPLAY(a) // Output: 6
Here, sum
is assigned the result of adding a
and b
. The variable a
is then updated by adding 1
to its current value.
Variable Scope
The scope of a variable is the region of your program where the variable is accessible. In ApLang, variables have a local scope, which means that a variable defined in a function (or procedure in ApLang's case) is accessible only within that function. Contrary to many programming languages, ApLang does not have global variables.
x <- 10
y <- 5
z <- 4 // 'z' defined here is NOT accessible in max()
PRODECURE max(x, y) {
IF (x >= y) {
a <- x // 'a' is not accessible outside of max()
} ELSE {
a <- y // 'a' is also not accessible outside of max()
}
// Trying to access 'z' here would result in an error
// DISPLAY(z) // Error: 'z' is not defined
RETURN a
}
// Trying to access 'a' here would result in an error
// DISPLAY(a) // Error: 'a' is not defined
In this example, the variable a
is defined inside the PROCEDURE
block and cannot be accessed outside of it. In the same way, z
is defined outside of the PROCEDURE
block and cannot be accessed inside of it.
Conclusion
Variables are fundamental to programming in ApLang. They allow you to store, modify, and use data dynamically. By understanding how to create variables, reassign values, and use variables within their scope, you will be able to write more flexible and powerful programs.
Control Flow
Control flow refers to the mechanisms that determine the order in which statements and instructions are executed in a program. In ApLang, control flow structures allow you to make decisions and repeat tasks based on specific conditions, making your code more dynamic and responsive to different situations.
Think of control flow like navigating a city using a map. Just as you might choose different routes based on traffic, weather, or your destination, control flow in programming lets your code choose different paths based on the data it receives and the conditions it encounters.
Control flow includes:
- Making Decisions: Similar to deciding whether to take an umbrella based on the weather forecast, your program can execute certain blocks of code only when specific conditions are met.
- Repeating Tasks: Just as you might wash each dish in a sink full of dirty dishes until they’re all clean, loops in programming allow your program to repeat operations multiple times without having to write the same code repeatedly.
- Branching Execution: This is like choosing a detour if a road is blocked. Your program can direct its execution to different parts of the code based on logical conditions, ensuring it behaves correctly under various circumstances.
In this chapter, we will explore the various control flow structures available in ApLang, including conditionals and loops, which allow you to guide the execution path of your code effectively, just like making decisions and finding the best route on a journey.
IF Statements
IF
statements are a fundamental control flow structure in ApLang. They allow your program to make decisions and execute specific blocks of code based on certain conditions. Using IF
, ELSE IF
, and ELSE
, you can create flexible programs that respond dynamically to different inputs and scenarios.
IF
The IF
statement checks a condition and executes a block of code if the condition evaluates to TRUE
. It’s the most basic form of decision-making in your program.
Syntax
IF (condition) {
// Code to execute if the condition is TRUE
}
Example: Basic IF Statement
x <- 10
IF (x > 5) {
DISPLAY("x is greater than 5")
}
// Output: "x is greater than 5"
In this example, the condition (x > 5)
is TRUE
, so the code inside the IF
block is executed, displaying "x is greater than 5."
ELSE
The ELSE
statement is used to execute a block of code if the condition in the preceding IF
statement evaluates to FALSE
. It provides an alternative path of execution.
Syntax
IF (condition) {
// Code to execute if the condition is TRUE
} ELSE {
// Code to execute if the condition is FALSE
}
Example: IF-ELSE Statement
x <- 3
IF (x > 5) {
DISPLAY("x is greater than 5")
} ELSE {
DISPLAY("x is not greater than 5")
}
// Output: "x is not greater than 5"
Here, the condition (x > 5)
is FALSE
, so the code inside the ELSE
block is executed, displaying "x is not greater than 5."
ELSE IF
The ELSE IF
statement allows you to check multiple conditions sequentially. If the initial IF
condition is FALSE
, the program checks the ELSE IF
condition. You can chain multiple ELSE IF
statements together to handle various scenarios.
Syntax
IF (condition1) {
// Code to execute if condition1 is TRUE
} ELSE IF (condition2) {
// Code to execute if condition1 is FALSE and condition2 is TRUE
} ELSE {
// Code to execute if none of the above conditions are TRUE
}
Example: IF-ELSE IF-ELSE Statement
x <- 5
IF (x > 5) {
DISPLAY("x is greater than 5")
} ELSE IF (x == 5) {
DISPLAY("x is equal to 5")
} ELSE {
DISPLAY("x is less than 5")
}
// Output: "x is equal to 5"
In this example, the program first checks if x
is greater than 5
. Since this is FALSE
, it moves to the ELSE IF
condition (x == 5)
, which is TRUE
. The code inside the ELSE IF
block is executed, displaying "x is equal to 5."
Nesting IF Statements
You can nest IF
statements within each other to create more complex decision-making structures. This is useful for checking multiple conditions in a hierarchical manner.
Example: Nested IF Statements
x <- 10
y <- 20
IF (x > 5) {
IF (y > 15) {
DISPLAY("x is greater than 5 and y is greater than 15")
} ELSE {
DISPLAY("x is greater than 5 but y is not greater than 15")
}
} ELSE {
DISPLAY("x is not greater than 5")
}
// Output: "x is greater than 5 and y is greater than 15"
In this example, the first IF
statement checks if x
is greater than 5
. Since it is TRUE
, the program moves inside this IF
block and checks the next IF
statement to see if y
is greater than 15
. Since both conditions are TRUE
, it displays "x is greater than 5 and y is greater than 15."
Conclusion
IF
, ELSE IF
, and ELSE
statements are powerful tools in ApLang, allowing you to control the flow of your program based on conditions. By mastering these constructs, you can write programs that respond dynamically to a wide range of inputs and situations, making your code more flexible and adaptable.
Loops
Loops are fundamental control flow structures in ApLang that allow you to repeat a block of code multiple times. Loops are particularly useful when you want to perform a repetitive task or iterate over a collection of items without writing the same code multiple times. In ApLang, there are two main types of loops: REPEAT TIMES
and REPEAT UNTIL
.
REPEAT TIMES
The REPEAT TIMES
loop allows you to execute a block of code a specified number of times. This type of loop is useful when you know in advance how many times you want to repeat an operation.
Syntax
REPEAT n TIMES {
// Code to repeat
}
Here, n
is the number of times the code block should be executed.
Example: REPEAT TIMES Loop
// Display "Hello, World!" 3 times
REPEAT 3 TIMES {
DISPLAY("Hello, World!")
}
// Output:
// Hello, World!
// Hello, World!
// Hello, World!
In this example, the REPEAT TIMES
loop runs the code inside the block three times, each time displaying "Hello, World!".
Example: Using a Counter
// Initialize counter
counter <- 0
// Repeat 5 times, incrementing the counter each time
REPEAT 5 TIMES {
counter <- counter + 1
DISPLAY(counter)
}
// Output:
// 1
// 2
// 3
// 4
// 5
In this example, the loop repeats five times, incrementing the counter
by 1 on each iteration and displaying its value.
REPEAT UNTIL
The REPEAT UNTIL
loop executes a block of code repeatedly until a specified condition becomes TRUE
. This type of loop is useful when you want to repeat an operation until a certain condition is met, but you don't know in advance how many iterations it will take.
Syntax
REPEAT UNTIL (condition) {
// Code to repeat
}
The loop continues to execute as long as the condition
is FALSE
. Once the condition evaluates to TRUE
, the loop stops.
Example: REPEAT UNTIL Loop
// Initialize variable
count <- 0
// Repeat until count is equal to 5
REPEAT UNTIL (count == 5) {
count <- count + 1
DISPLAY(count)
}
// Output:
// 1
// 2
// 3
// 4
// 5
In this example, the loop runs until count
equals 5
. With each iteration, count
is incremented by 1 and displayed. When count
reaches 5
, the loop stops.
Example: Using a Condition
// Initialize variables
balance <- 100
goal <- 200
// Double the balance until it reaches the goal
REPEAT UNTIL (balance >= goal) {
balance <- balance * 2
DISPLAY(balance)
}
// Output:
// 200
In this example, the loop doubles the balance
on each iteration and displays it. The loop continues until balance
is greater than or equal to the goal
of 200.
Conclusion
Loops are an essential tool for automating repetitive tasks in ApLang. The REPEAT TIMES
loop is ideal when you know how many times you need to repeat an operation, while the REPEAT UNTIL
loop is perfect for scenarios where the number of iterations depends on a condition. By mastering these looping constructs, you can create more efficient and dynamic programs.
FOR EACH Loop
The FOR EACH
loop in ApLang is used to iterate over the elements of a list. This type of loop is ideal when you want to perform an operation on each element of a list without manually managing loop counters or indices. The FOR EACH
loop simplifies code that processes each item in a collection, making your programs easier to read and maintain.
Syntax
FOR EACH item IN list {
// Code to execute for each item
}
item
represents the current element in the list for each iteration of the loop.list
is the collection of elements you want to iterate over.
Example: Basic FOR EACH Loop
// Define a list of numbers
numbers <- [1, 2, 3, 4, 5]
// Iterate over each number in the list and display it
FOR EACH number IN numbers {
DISPLAY(number)
}
// Output:
// 1
// 2
// 3
// 4
// 5
In this example, the FOR EACH
loop iterates over each element in the numbers
list and displays it. The loop executes once for each element in the list.
Example: Performing Operations on List Elements
// Define a list of words
words <- ["apple", "banana", "cherry"]
// Iterate over each word in the list and display it in uppercase
FOR EACH word IN words {
DISPLAY(word + " in uppercase is " + TO_UPPER(word) + "!")
}
// Output:
// apple in uppercase is APPLE!
// banana in uppercase is BANANA!
// cherry in uppercase is CHERRY!
In this example, the FOR EACH
loop iterates over the words
list and displays each word, demonstrating how to concatenate strings within the loop.
Example: Modifying Elements Within the Loop
// Define a list of numbers
numbers <- [1, 2, 3, 4, 5]
// Initialize an empty list to hold doubled values
doubled_numbers <- []
// Iterate over each number in the list, double it, and add it to the new list
FOR EACH number IN numbers {
doubled_numbers <- doubled_numbers + [number * 2]
}
DISPLAY(doubled_numbers)
// Output: [2, 4, 6, 8, 10]
In this example, the FOR EACH
loop doubles each number in the numbers
list and appends the result to a new list called doubled_numbers
. The loop efficiently processes each element and builds a new list of doubled values.
Nesting FOR EACH Loops
You can nest FOR EACH
loops to iterate over multiple lists or to perform more complex operations on lists of lists.
// Define a list of lists
matrix <- [[1, 2], [3, 4], [5, 6]]
// Iterate over each row in the matrix
FOR EACH row IN matrix {
// Iterate over each element in the current row
FOR EACH element IN row {
DISPLAY(element)
}
}
// Output:
// 1
// 2
// 3
// 4
// 5
// 6
In this example, the outer FOR EACH
loop iterates over each row of the matrix
, and the inner FOR EACH
loop iterates over each element in the current row, displaying all elements in the matrix.
Conclusion
The FOR EACH
loop is a powerful and versatile tool in ApLang, allowing you to iterate over lists and perform operations on each element with ease. By using FOR EACH
loops, you can write cleaner and more efficient code, especially when working with collections of data. Mastering this loop will enable you to handle a wide range of programming tasks involving lists in ApLang.
BREAK and CONTINUE in Loops
In ApLang, loops like REPEAT
, REPEAT UNTIL
, and FOR EACH
give you the ability to control the flow of the loop execution using the BREAK
and CONTINUE
keywords.
BREAK
The BREAK
keyword allows you to exit a loop entirely before it naturally finishes. Once the BREAK
statement is encountered, the program will immediately stop executing the current loop and move to the next statement after the loop.
Here's an example of using BREAK
in a loop:
REPEAT 10 TIMES {
IF (i == 5) {
BREAK
}
DISPLAY(i)
}
// This will display numbers from 1 to 4 and then stop
In this example, the loop will terminate when the value of i
reaches 5, and no further iterations will be performed.
CONTINUE
The CONTINUE
keyword is used to skip the current iteration of a loop and move to the next one without breaking out of the loop completely. Once the CONTINUE
statement is encountered, the program will stop the current iteration and start the next iteration of the loop immediately.
Here's an example of using CONTINUE
:
REPEAT 10 TIMES {
IF (i == 5) {
CONTINUE
}
DISPLAY(i)
}
// This will display numbers from 1 to 4 and 6 to 10, skipping 5
In this case, when the value of i
is 5, the CONTINUE
statement will skip displaying i
and jump to the next iteration, so 5 will not be printed.
Using BREAK and CONTINUE in FOR EACH
Both BREAK
and CONTINUE
can also be used in FOR EACH
loops to manage the flow of list iteration. Here's an example:
FOR EACH item IN myList {
IF (item == "skipThis") {
CONTINUE
}
IF (item == "stopHere") {
BREAK
}
DISPLAY(item)
}
In this example, the CONTINUE
statement skips the iteration where item
equals "skipThis"
, and the BREAK
statement stops the loop entirely when item
equals "stopHere"
.
Conclusion
The BREAK
and CONTINUE
keywords give you finer control over loop execution in ApLang. Whether you need to prematurely exit a loop or skip over specific iterations, these commands provide essential tools for managing complex looping conditions.
Procedures
Procedures in ApLang are a way to encapsulate a block of code that performs a specific task. Think of procedures as a box: you can put values into the box (inputs), the box does something with those values, and then gives you a result (output). Procedures help make your programs more organized, reusable, and easier to understand.
What is a Procedure?
A procedure is a reusable block of code that performs a particular function or task. You can define a procedure once and then use it (or "call" it) multiple times throughout your program, providing different inputs each time. This helps reduce code duplication and makes your program easier to manage.
Defining a Procedure
To define a procedure in ApLang, use the PROCEDURE
keyword followed by the procedure’s name and a pair of parentheses ()
. Inside the parentheses, you can specify any parameters that the procedure takes as input. The code block inside the curly braces {}
is the body of the procedure, which contains the instructions that the procedure will execute.
Syntax
PROCEDURE procedure_name(parameter1, parameter2, ...) {
// Code to execute
RETURN result
}
Example: Defining a Simple Procedure
// Define a procedure to add two numbers
PROCEDURE add(a, b) {
sum <- a + b
RETURN sum
}
In this example, the add
procedure takes two parameters, a
and b
, adds them together, and returns the result. The RETURN
statement specifies the value that the procedure outputs.
Calling a Procedure
Once a procedure is defined, you can call it by using its name followed by parentheses containing any arguments you want to pass to it. The procedure will execute its code block using the provided arguments and return a result.
Example: Calling a Procedure
// Call the 'add' procedure with arguments 3 and 4
result <- add(3, 4)
DISPLAY(result) // Output: 7
In this example, the add
procedure is called with the arguments 3
and 4
. The procedure returns 7
, which is then displayed.
Reference vs. Value
When passing parameters to procedures in ApLang, it's important to understand the difference between passing by reference and passing by value:
-
Pass by Value: When a parameter is passed by value, the procedure receives a copy of the argument. Changes made to this parameter inside the procedure do not affect the original argument. In ApLang, numbers, strings, and booleans are passed by value.
-
Pass by Reference: When a parameter is passed by reference, the procedure receives a reference to the actual argument, not a copy. Any changes made to this parameter inside the procedure will affect the original argument. In ApLang, lists are passed by reference.
Example: Pass by Value
PROCEDURE modify_number(n) {
n <- n + 10
DISPLAY(n) // Output: 15
}
num <- 5
modify_number(num)
DISPLAY(num) // Output: 5
In this example, num
is passed by value to the modify_number
procedure. Inside the procedure, the local copy of n
is modified, but the original num
remains unchanged outside the procedure.
Example: Pass by Reference
PROCEDURE add_to_list(lst) {
APPEND(lst, 4)
DISPLAY(lst) // Output: [1, 2, 3, 4]
}
my_list <- [1, 2, 3]
add_to_list(my_list)
DISPLAY(my_list) // Output: [1, 2, 3, 4]
In this example, my_list
is passed by reference to the add_to_list
procedure. Inside the procedure, the list is modified, and this change affects the original my_list
outside the procedure.
Using Procedures to Organize Code
Procedures are a powerful way to organize your code by breaking it down into smaller, manageable pieces. Each procedure can focus on a specific task, making your code easier to read, debug, and maintain.
Example: Using Procedures to Break Down a Task
// Define a procedure to multiply two numbers
PROCEDURE multiply(a, b) {
product <- a * b
RETURN product
}
// Define a procedure to calculate the area of a rectangle
PROCEDURE calculate_area(length, width) {
area <- multiply(length, width)
RETURN area
}
// Call the 'calculate_area' procedure
area <- calculate_area(5, 10)
DISPLAY(area) // Output: 50
In this example, two procedures are defined: multiply
and calculate_area
. The calculate_area
procedure uses the multiply
procedure to compute the area of a rectangle. By using procedures, the code is modular and easy to understand.
Procedures with No Return Value
Not all procedures need to return a value. Sometimes, you might want a procedure to perform an action without giving back a result. In ApLang, procedures that do not have a RETURN
statement simply execute their code and then finish.
Example: Procedure with No Return Value
// Define a procedure to display a greeting
PROCEDURE greet(name) {
DISPLAY("Hello, " + name + "!")
}
// Call the 'greet' procedure
greet("Alice") // Output: "Hello, Alice!"
In this example, the greet
procedure takes a parameter name
and displays a greeting. It does not return any value; it simply performs an action.
Conclusion
Procedures are like a toolbox in ApLang, allowing you to encapsulate reusable blocks of code that perform specific tasks. By understanding how ApLang passes parameters—by reference for lists and by value for other types—you can better manage how your procedures interact with data. Whether you’re returning values or simply performing actions, procedures are an essential tool for building robust and maintainable programs in ApLang.
Modules
As you begin to write larger and more complex programs, organizing your code will become increasingly more important. (The Rust Book)
This is where modules come in. Modules help to encapsulate implementation details, which means they hide the internal workings of your code. By doing this, modules allow you to expose only the parts of the code that are necessary for the user, keeping the rest private. This makes it easier to understand and maintain your programs by breaking them down into smaller, more manageable building blocks.
Every .ap
file in ApLang is also considered a module. In ApLang, there are two types of modules: Standard Library Modules and User Modules.
Standard Library Modules
Standard Library Modules come built-in with ApLang and are written in Rust. These modules provide essential functionality that you can use in your programs. Standard Library Modules and their functions follow a convention of using SCREAMING_CASE for their names. Here’s how you can import them:
// Import all functions from a standard library module
IMPORT MOD "MATH"
// Now, we can use functions from the MATH module
// Import just the INPUT function from the IO module
IMPORT "INPUT" FROM MOD "IO"
// Import the FILE_CREATE and FILE_READ functions from the FS (file system) module
IMPORT ["FILE_CREATE", "FILE_READ"] FROM MOD "FS"
User Modules
User Modules are modules written by you, the programmer, using ApLang. These modules also have the .ap
file extension, and you can specify their path when importing them. Here’s an example:
// main.ap
// Importing a specific function from a user module using its relative path
IMPORT "myFunction" FROM "./myModule.ap"
// This is equivalent to the previous statement
IMPORT "myFunction" FROM "myModule.ap"
// Importing a whole nested module
IMPORT "./nested/myNestedModule.ap"
In contrast to Standard Library Modules, user-defined functions and modules should be written in camelCase rather than SCREAMING_CASE. This helps distinguish user code from the standard library code.
Directory Structure Example
To better visualize how modules are organized, let's look at a simple project directory tree:
/my_project
|-- main.ap
|-- myModule.ap
|-- nested/
| |-- myNestedModule.ap
Exporting Functions
By default, functions in ApLang are private, meaning they can't be accessed outside of the file they're defined in. To make a function accessible to other modules, you need to use the EXPORT
keyword before PROCEDURE
. Here’s how you can export a function:
// myModule.ap
EXPORT PROCEDURE myFunction() {
// does something
}
This Behavior Might Change In The Future
Importing the Module inside the Procedure
// main.ap
IMPORT MOD "module.ap"
myModuleFunction() // Function defined in module.ap
// module.ap
IMPORT MOD "TIME" // This import will not translate to main.ap
myModuleFunction() {
IMPORT MOD "TIME" // You need to import TIME here
TIME()
}
Importing the Module Inside Main
// main.ap
IMPORT MOD "module.ap"
IMPORT "TIME" // Or you can import TIME here
myModuleFunction() // Function defined in module.ap
// module.ap
IMPORT MOD "TIME" // This import will not translate to main.ap
myModuleFunction() {
TIME()
}
Exporting Values
You cannot directly export variables in ApLang. If you want to share a variable across modules, you need to wrap it in a function:
EXPORT PROCEDURE myFavoriteNumber() {
RETURN 8
}
By exporting this procedure, other modules can call myFavoriteNumber()
to get the value 8
.
Conclusion
Modules are a powerful tool in ApLang that help you organize and manage your code more effectively. By encapsulating implementation details, modules make it easier to break down complex programs into smaller, reusable components. Whether you're using built-in Standard Library Modules or creating your own User Modules, understanding how to import, export, and structure your code will allow you to build more robust and maintainable projects. As your programs grow, leveraging modules will become essential for keeping your codebase clean and efficient.
Other
ASCII Escape Codes
When writing strings in programming, there are times you need to represent characters that can't be typed directly, such as newlines or tabs. To handle these situations, ASCII escape codes provide a way to "write the un-writable." Escape codes allow you to include special or unprintable characters in your strings by using a sequence that starts with a backslash (\
).
Valid Escape Codes
CODE | Description |
---|---|
\\ | Backslash (\ ) |
\n | Newline |
\r | Carriage Return |
\t | Tab |
\" | Double Quote (" ) |
Error Anatomy
When you're writing code, you're bound to run into errors. It's just a fact of life. While they might look complicated at first, error messages are really just the program's way of telling you something went wrong, and our way of giving you clues on how to fix it. Let's break one down together.
Here's a super simple example of one:
Error: aplang::runtime
x Invalid Variable
,-[./examples.ap/main.ap:1:1]
1 | var
: |
: `-- Could not find variable
2 |
`----
help: Make sure to create the variable `var` before you use it
error: process didn't exit successfully: `target\debug\aplang.exe -d all ./examples.ap/main.ap` (exit code: 1)
Let's break this down step by step:
-
Error type:
Error: aplang::runtime
The very first line tells you what type of error occurred. This will often tell you the general category of the error, like a runtime error or a syntax error. In our case, this is a runtime error.
-
Error code:
x Invalid Variable
Right below the error type, you'll usually find a more succinct description of the error. It's like a headline that summarizes the problem in a few words. In our case, it's telling us that a variable that we tried to use is invalid.
-
Error Location (File and Line Number):
[./examples.ap/main.ap:1:1]
This part tells you where the error occurred. It's usually in the format
[file_path:line_number:column_number]
. In our case, the error occurred in the filemain.ap
at line 1, column 1.When Importing code from a Module, the file_path will always show the main file, even if the error is in the Module. This is subject to change. -
Code Snippet:
1 | var : | : `-- Could not find variable 2 |
The code snippet is a little snapshot of your code around the error. There is often a little pointer and a message that tells you almost exactly what went wrong. Here, it's showing us that the error occurred on line 1, where we tried to use the variable
var
. -
Help Message:
help: Make sure to create the variable `var` before you use it
Finally, the help message will often give you a hint on how to fix the error. It's the most common fix for the error you're seeing. In our case, it's telling us to create the variable
var
before we use it.
Some Confusing Errors
-
Error: x (todo) Expected from following specific imports, found |
For this one, check your import statements. You most likely forgot the word `MOD` after `IMPORT`.This error message is subject to be fixed
-
Error: x expected primary, instead found { | ,-[main.ap:1:14] 1 | someProcedure( { : ^ | : | `-- primary expected here : `-- consider checking your upstream code 2 | `---- help: a primary is made up of the following set: [expression | ident | literal | list]
This error is telling us that it expected a primary, but instead found a
{
. In this case, we missed a closing parenthesis)
.
Core Module Documentation
IMPORTED BY DEFAULT
The Core module provides essential functions for user interaction, list manipulation, and generating random numbers.
Table of Contents
Functions
DISPLAY
Outputs the given value to the console.
Parameters:
value: Any
The value to be displayed.
Returns:
NULL
Example Usage:
DISPLAY("Hello, world!")
DISPLAY(123)
DISPLAY_NOLN
Outputs the given value to the console without creating a newline.
Parameters:
value: Any
The value to be displayed.
Returns:
NULL
Example Usage:
DISPLAY_NOLN("Hello, world!")
DISPLAY_NOLN(123)
// Hello, world!123
INPUT
Prompts the user for input and returns the entered value as a string.
Parameters: None
Returns:
String
: The input provided by the user.
Example Usage:
user_input <- INPUT()
DISPLAY(user_input)
INSERT
Inserts a value into a list at a specified index.
Parameters:
list: List
The list in which to insert the value.i: Number
The index at which to insert the value (indexed starting at 1).value: Any
The value to insert.
Returns:
NULL
Example Usage:
my_list <- [1, 2, 4]
INSERT(my_list, 3, 3)
DISPLAY(my_list) // [1, 2, 3, 4]
APPEND
Appends a value to the end of a list.
Parameters:
list: List
The list to which the value will be appended.value: Any
The value to append.
Returns:
NULL
Example Usage:
my_list <- [1, 2, 3]
APPEND(my_list, 4)
DISPLAY(my_list) // [1, 2, 3, 4]
REMOVE
Removes a value from a list at the specified index and returns the removed value.
Parameters:
list: List
The list from which the value will be removed.i: Number
The index of the value to remove (indexed starting at 1).
Returns:
Value
: The value that was removed.
Example Usage:
my_list <- [1, 2, 3, 4]
removed <- REMOVE(my_list, 2)
DISPLAY(removed) // 2
DISPLAY(my_list) // [1, 3, 4]
LENGTH
Returns the length of a list.
Parameters:
list: List
The list whose length will be returned.
Returns:
Number
: The length of the list as a number.
Example Usage:
my_list <- [1, 2, 3]
list_length <- LENGTH(my_list)
DISPLAY(list_length) // 3
RANDOM
Generates a random integer between two numbers (inclusive).
Parameters:
a: Number
The lower bound.b: Number
The upper bound.
Returns:
Number
: A random integer betweena
andb
.
Example Usage:
random_number <- RANDOM(1, 10)
DISPLAY(random_number) // Random number between 1 and 10
File System Module Documentation
IMPORT MOD "FS"
The File System module provides functions for interacting with the file system, including checking paths, reading/writing files, and managing directories.
Table Of Contents
Functions
PATH_EXISTS
Checks whether a given path exists.
Parameters:
path: String
The path to check.
Returns:
Bool
:TRUE
if the path exists,FALSE
otherwise.
Example Usage:
exists <- PATH_EXISTS("/home/user/file.txt")
DISPLAY(exists)
PATH_IS_FILE
Checks if a given path is a file.
Parameters:
path: String
The path to check.
Returns:
Bool
:TRUE
if the path is a file,FALSE
otherwise.
Example Usage:
is_file <- PATH_IS_FILE("/home/user/file.txt")
DISPLAY(is_file)
PATH_IS_DIRECTORY
Checks if a given path is a directory.
Parameters:
path: String
The path to check.
Returns:
Bool
:TRUE
if the path is a directory,FALSE
otherwise.
Example Usage:
is_dir <- PATH_IS_DIRECTORY("/home/user/")
DISPLAY(is_dir)
FILE_CREATE
Creates a new file at the specified path. Returns TRUE
if the file was created successfully.
Parameters:
file_path: String
The path where the file should be created.
Returns:
Bool
:TRUE
if the file was created,FALSE
if there was an error.
Example Usage:
success <- FILE_CREATE("/home/user/new_file.txt")
DISPLAY(success)
FILE_READ
Reads the contents of a file as a string. Returns NULL
if the file cannot be read.
Parameters:
file_path: String
The path of the file to read.
Returns:
String
: The contents of the file,NULL
If the file cannot be read.
Example Usage:
contents <- FILE_READ("/home/user/file.txt")
IF (contents == NULL) {
DISPLAY("Failed to read file.")
} ELSE {
DISPLAY(contents)
}
FILE_APPEND
Appends the given content to the end of a file. Returns TRUE
if successful.
Parameters:
file_path: String
The path of the file.contents: Value
The content to append.
Returns:
Bool
:TRUE
if the content was successfully appended,FALSE
otherwise.
Example Usage:
success <- FILE_APPEND("/home/user/file.txt", "New content to add.")
DISPLAY(success)
FILE_OVERWRITE
Overwrites the contents of a file with the provided content. Returns TRUE
if successful.
Parameters:
file_path: String
The path of the file.contents: Value
The content to overwrite the file with.
Returns:
Bool
:TRUE
if the content was successfully written,FALSE
otherwise.
Example Usage:
success <- FILE_OVERWRITE("/home/user/file.txt", "Overwritten content.")
DISPLAY(success)
DIRECTORY_READ
Reads the contents of a directory and returns a list of file paths.
Parameters:
path: String
The path of the directory to read.
Returns:
List
A list of file paths in the directory.
Example Usage:
files <- DIRECTORY_READ("/home/user/")
FOR EACH file IN files {
DISPLAY(file)
}
DIRECTORY_CREATE
Creates a new, empty directory at the provided path. Does not create parent directories.
Note: To create a directory and all its missing parents at the same time, instead use DIRECTORY_CREATE_ALL
.
Parameters:
path: String
The path of the directory to be created.
Returns:
Bool
IsTRUE
if creation was successfullFALSE
otherwise.
Errors When:
- User lacks permissions to create directory at
path
. - A parent of the given path doesn't exist.
path
already exists.
Example Usage:
success <- DIRECTORY_CREATE("some/dir")
DISPLAY(success)
DIRECTORY_CREATE_ALL
Creates a new, empty directory at the provided path. Will create parent directories.
Parameters:
path: String
The path of the directory to be created.
Returns:
Bool
IsTRUE
if creation was successfullFALSE
otherwise.
Errors When:
- If any directory in the path specified by path does not already exist and it could not be created otherwise.
Example Usage:
success <- DIRECTORY_CREATE_ALL("some/dir")
DISPLAY(success)
DIRECTORY_REMOVE_ALL
Be very cautious when using this function!
Removes a directory at this path, after removing all its contents.
Parameters:
path: String
The path of the directory to be removed.
Returns:
Bool
IsTRUE
if creation was successfullFALSE
otherwise.
Example Usage:
success <- DIRECTORY_REMOVE_ALL("some/dir")
DISPLAY(success)
DIRECTORY_REMOVE
Removes an empty directory.
Parameters:
path: String
The path of the directory to be removed.
Returns:
Bool
IsTRUE
if creation was successfullFALSE
otherwise.
Errors When:
path
doesn't exist.path
isn't a directory.- The user lacks permissions to remove the directory at the provided
path
. - The directory isn't empty.
Example Usage:
success <- DIRECTORY_REMOVE("some/dir")
DISPLAY(success)
Time Module Documentation
IMPORT MOD "TIME"
The Time module provides functions for getting the current time and pausing execution for a specified duration.
Table of Contents
Functions
TIME
Returns the current time in milliseconds since the UNIX epoch (January 1, 1970).
Parameters: None
Returns:
Number
: The current time in milliseconds
Example Usage:
current_time <- TIME()
DISPLAY(current_time)
SLEEP
Pauses the execution of the program for a specified number of milliseconds.
Parameters:
duration: Number
The duration to sleep in milliseconds.
Returns:
NULL
Example Usage:
DISPLAY("Sleeping for 2 seconds...")
SLEEP(2000)
DISPLAY("Awake now!")
Math Module Documentation
IMPORT MOD "MATH"
The Math module provides a variety of mathematical functions, including trigonometric, hyperbolic, exponential, logarithmic, rounding, and clamping functions. It also includes important constants like PI, E, and TAU.
Table of Contents
Functions
SIN
Calculates the sine of an angle in radians.
Parameters:
angle: Number
The angle in radians.
Returns:
Number
: The sin of the given angle
Example Usage:
result <- SIN(1.5708) // Approx value of PI/2
DISPLAY(result)
COS
Calculates the cosine of an angle in radians.
Parameters:
angle: Number
The angle in radians.
Returns:
Number
: The cosine of the given angle.
Example Usage:
result <- COS(0)
DISPLAY(result)
TAN
Calculates the tangent of an angle in radians.
Parameters:
angle: Number
The angle in radians.
Returns:
Number
: The tangent of the given angle.
Example Usage:
result <- TAN(0.7854) // Approx value of PI/4
DISPLAY(result)
ASIN
Calculates the arc sine of a value.
Parameters:
value: Number
The input value, must be between -1 and 1.
Returns:
Number
: The arc sine in radians of the given angle.
Example Usage:
result <- ASIN(0.5)
DISPLAY(result)
ACOS
Calculates the arc cosine of a value.
Parameters:
value: Number
The input value, must be between -1 and 1.
Returns:
Number
: The arc cosine in radians of the given angle.
Example Usage:
result <- ACOS(0.5)
DISPLAY(result)
ATAN
Calculates the arc tangent of a value.
Parameters:
value: Number
The input value.
Returns:
Number
: The arc tangent in radians of the given angle.
Example Usage:
result <- ATAN(1)
DISPLAY(result)
ATAN2
Calculates the arc tangent of y/x
, using the signs of both values to determine the correct quadrant.
Parameters:
y: Number
The y-coordinate.x: Number
The x-coordinate.
Returns:
Number
: The arc tangent ofy/x
.
Example Usage:
result <- ATAN2(1, 1)
DISPLAY(result)
SINH
Calculates the hyperbolic sine of a value.
Parameters:
value: Number
The input value.
Returns:
Number
: The hyperbolic sine of the given value.
Example Usage:
result <- SINH(1)
DISPLAY(result)
COSH
Calculates the hyperbolic cosine of a value.
Parameters:
value: Number
The input value.
Returns:
Number
: The hyperbolic cosine of the given value.
Example Usage:
result <- COSH(1)
DISPLAY(result)
TANH
Calculates the hyperbolic tangent of a value.
Parameters:
value: Number
The input value.
Returns:
Number
: The hyperbolic tangent of the given value.
Example Usage:
result <- TANH(1)
DISPLAY(result)
ASINH
Calculates the inverse hyperbolic sine of a value.
Parameters:
value: Number
The input value.
Returns:
Number
: The inverse hyperbolic sine of the given value.
Example Usage:
result <- ASINH(1)
DISPLAY(result)
ACOSH
Calculates the inverse hyperbolic cosine of a value.
Parameters:
value: Number
The input value, must be greater than or equal to 1.
Returns:
Number
: The inverse hyperbolic cosine of the given value.
Example Usage:
result <- ACOSH(1)
DISPLAY(result)
ATANH
Calculates the inverse hyperbolic tangent of a value.
Parameters:
value: Number
The input value, must be between -1 and 1.
Returns:
Number
: The inverse hyperbolic tangent of the given value.
Example Usage:
result <- ATANH(0.5)
DISPLAY(result)
EXP
Calculates the exponential of a value (e^value).
Parameters:
value: Number
The input value.
Returns:
Number
: The result ofe^value
.
Example Usage:
result <- EXP(1)
DISPLAY(result)
LOG
Calculates the logarithm of a value with a specified base.
Parameters:
value: Number
The input value.base: Number
The base of the logarithm.
Returns:
Number
: The logarithm ofvalue
to the basebase
.
Example Usage:
result <- LOG(8, 2)
DISPLAY(result)
LOG10
Calculates the base-10 logarithm of a value.
Parameters:
value: Number
: The input value.
Returns:
Number
The base-10 logarithm of the given value.
Example Usage:
result <- LOG10(100)
DISPLAY(result)
LOG2
Calculates the base-2 logarithm of a value.
Parameters:
value: Number
The input value.
Returns:
Number
: The base-2 logarithm of the given value.
Example Usage:
result <- LOG2(8)
DISPLAY(result)
ROUND
Rounds a number to the nearest whole number.
Parameters:
value: Number
The input value.
Returns:
Number
: The rounded value.
Example Usage:
result <- ROUND(2.7)
DISPLAY(result)
FLOOR
Rounds a number down to the nearest whole number.
Parameters:
value: Number
The input value.
Returns:
Number
: The rounded-down value.
Example Usage:
result <- FLOOR(2.7)
DISPLAY(result) // 2
CEIL
Rounds a number up to the nearest whole number.
Parameters:
value: Number
The input value.
Returns:
Number
: The rounded-up value.
Example Usage:
result <- CEIL(2.1)
DISPLAY(result) // 3
INT
Truncates the decimal part of a number.
Parameters:
value: Number
The input value.
Returns:
Number
: The truncated value.
Example Usage:
result <- INT(2.7)
DISPLAY(result) // 2
CLAMP
Clamps a number between a minimum and maximum value.
Parameters:
value: Number
The input value.min: Number
The minimum value.max: Number
The maximum value.
Returns:
Number
: The clamped value.
Example Usage:
result <- CLAMP(15, 1, 10)
DISPLAY(result) // 10
PI
Returns the value of PI.
Returns:
Number
: The value of PI (3.14159...).
Example Usage:
pi_value <- PI()
DISPLAY(pi_value)
E
Returns the value of Euler's number (e).
Returns:
Number
: The value of Euler's number (2.71828...).
Example Usage:
e_value <- E()
DISPLAY(e_value)
TAU
Returns the value of TAU (2 * PI).
Returns:
Number
: The value of TAU (6.28318...).
Example Usage:
tau_value <- TAU()
DISPLAY(tau_value)
String Module Documentation
IMPORT MOD "STRING"
This module provides various string manipulation functions that allow for conversion, splitting, transformation, and inspection of strings.
Table of Contents
Functions
TO_NUMBER
Converts a string to a number (f64
). Returns NULL
if the conversion is not possible.
Parameters:
raw: String
The string to convert.
Returns:
Number
: The converted number,NULL
If the conversion fails.
Example Usage:
number <- TO_NUMBER("123.45")
IF (number == NULL) {
DISPLAY("Conversion failed.")
}
TO_BOOL
Converts a string to a boolean. Returns NULL
if the conversion is not possible.
Parameters:
raw: String
The string to convert.
Returns:
Bool
: The converted boolean,NULL
If the conversion fails.
Example Usage:
boolean <- TO_BOOL("TRUE") // you can also use "true" here
IF (boolean != NULL AND boolean == TRUE) {
DISPLAY("It's true!")
}
SPLIT
Splits a string into a list of strings based on a pattern.
Parameters:
raw: String
The string to split.pattern: String
The delimiter used to split the string.
Returns:
List
: A list of strings obtained by splitting the original string.
Example Usage:
parts <- SPLIT("apple,banana,orange", ",")
FOR EACH item IN parts {
DISPLAY(item)
}
// apple
// banana
// orange
TO_UPPER
Converts a string to uppercase.
Parameters:
raw: String
The string to convert.
Returns:
String
: The converted uppercase string.
Example Usage:
upper_case <- TO_UPPER("hello")
DISPLAY(upper_case) // "HELLO"
TO_LOWER
Converts a string to lowercase.
Parameters:
raw: String
The string to convert.
Returns:
String
: The converted lowercase string.
Example Usage:
lower_case <- TO_LOWER("HELLO")
DISPLAY(lower_case) // "hello"
TRIM
Removes leading and trailing whitespace from a string.
Parameters:
raw: String
The string to trim.
Returns:
String
: The trimmed string.
Example Usage:
trimmed <- TRIM(" hello ")
DISPLAY(trimmed) // "hello"
CONTAINS
Checks if a string contains a given substring.
Parameters:
raw: String
The string to search.pattern: String
The substring to search for.
Returns:
Bool
:TRUE
if the substring is found,FALSE
otherwise.
Example Usage:
contains <- CONTAINS("hello world", "world")
IF (contains) {
DISPLAY("Found it!")
}
REPLACE
Replaces all occurrences of a substring with another substring.
Parameters:
raw: String
The string to modify.from: String
The substring to replace.to: String
The substring to replace with.
Returns:
String
: The modified string with replacements.
Example Usage:
replaced <- REPLACE("hello world", "world", "everyone")
DISPLAY(replaced) // "hello everyone"
STARTS_WITH
Checks if a string starts with a given prefix.
Parameters:
raw: String
The string to check.prefix: String
The prefix to check for.
Returns:
Bool
:TRUE
if the string starts with the prefix,FALSE
otherwise.
Example Usage:
starts <- STARTS_WITH("hello", "he")
IF (starts) {
DISPLAY("Starts with 'he'")
}
ENDS_WITH
Checks if a string ends with a given suffix.
Parameters:
raw: String
The string to check.suffix: String
The suffix to check for.
Returns:
Bool
:TRUE
if the string ends with the suffix,FALSE
otherwise.
Example Usage:
ends <- ENDS_WITH("hello", "lo")
IF (ends) {
DISPLAY("Ends with 'lo'")
}
JOIN
Joins a list of strings into a single string, separated by a given separator.
Parameters:
list: List
The list of strings to join.separator: String
The separator to use between elements.
Returns:
String
: The joined string.
Example Usage:
joined <- JOIN(["apple", "banana", "orange"], ", ")
DISPLAY(joined) // "apple, banana, orange"
SUBSTRING
Extracts a substring from a string, starting at a given position and of a specified length.
Parameters:
raw: String
The original string.start: Number
The starting index (1-based).length: Number
The length of the substring.
Returns:
String
: The extracted substring.
Example Usage:
substring <- SUBSTRING("hello world", 1, 4)
DISPLAY(substring) // ello
TO_CHAR_ARRAY
Converts a string into a list of single-character strings.
Parameters:
raw: String
The string to convert.
Returns:
List
: A list where each element is a single-character string.
Example Usage:
char_array <- TO_CHAR_ARRAY("hello")
FOR EACH char in char_array {
DISPLAY(char)
}
// h
// e
// l
// l
// o
IO Module Documentation
IMPORT MOD "IO"
The IO module provides functions for formatted user input, output, and string formatting.
Table of Contents
Functions
INPUT_PROMPT
Prompts the user with a custom message and returns the user's input as a string.
Parameters:
prompt: String
The prompt message to display to the user.
Returns:
String
: The user's input as a string.
Example Usage:
user_input <- INPUT_PROMPT("Enter your name: ")
DISPLAY(user_input)
FORMAT
Formats a string by replacing placeholders ({}
) with values from a list.
Parameters:
fstring: String
The format string with{}
as placeholders.args: List
The list of values to insert into the format string.
Returns:
String
: The formatted string.
Example Usage:
name <- "Alice"
age <- 25
message <- FORMAT("My name is {} and I am {} years old.", [name, age])
DISPLAY(message)
// "My name is Alice and I am 25 years old."
DISPLAYF
Displays a formatted string to the console by replacing placeholders ({}
) with values from a list.
Parameters:
fstring: String
The format string with{}
as placeholders.args: List
The list of values to insert into the format string.
Returns:
NULL
Example Usage:
name <- "Bob"
score <- 100
DISPLAYF("Player {} scored {} points!", [name, score])
// "Player Bob scored 100 points!"
Style Module Documentation
IMPORT MOD "STYLE"
The style module includes utilities for coloring and adding styles to displayed text.
Table of Contents
Functions
CLEAR_STYLE
Clears all applied styles
Parameters: None.
Returns: None.
Example Usage:
STYLE("blue")
DISPLAY("This text is blue")
CLEAR_STYLE()
DISPLAY("This text is no longer blue")
STYLE
Applies a style
Parameters:
style: String
The style type to apply to the text
Style/Color | ANSI Code | Description |
---|---|---|
clear | \x1b[0m | Resets all styles and colors |
default_color | \x1b[39m | Resets the foreground color to default |
bg_default_color | \x1b[49m | Resets the background color to default |
Style/Color | ANSI Code | Description |
---|---|---|
black | \x1b[30m | Sets the text color to black |
red | \x1b[31m | Sets the text color to red |
green | \x1b[32m | Sets the text color to green |
yellow | \x1b[33m | Sets the text color to yellow |
blue | \x1b[34m | Sets the text color to blue |
magenta | \x1b[35m | Sets the text color to magenta |
cyan | \x1b[36m | Sets the text color to cyan |
white | \x1b[37m | Sets the text color to white |
bright_black | \x1b[90m | Sets the text color to bright black (gray) |
bright_red | \x1b[91m | Sets the text color to bright red |
bright_green | \x1b[92m | Sets the text color to bright green |
bright_yellow | \x1b[93m | Sets the text color to bright yellow |
bright_blue | \x1b[94m | Sets the text color to bright blue |
bright_magenta | \x1b[95m | Sets the text color to bright magenta |
bright_cyan | \x1b[96m | Sets the text color to bright cyan |
bright_white | \x1b[97m | Sets the text color to bright white |
Style/Color | ANSI Code | Description |
---|---|---|
bg_black | \x1b[40m | Sets the background color to black |
bg_red | \x1b[41m | Sets the background color to red |
bg_green | \x1b[42m | Sets the background color to green |
bg_yellow | \x1b[43m | Sets the background color to yellow |
bg_blue | \x1b[44m | Sets the background color to blue |
bg_magenta | \x1b[45m | Sets the background color to magenta |
bg_cyan | \x1b[46m | Sets the background color to cyan |
bg_white | \x1b[47m | Sets the background color to white |
bg_bright_black | \x1b[100m | Sets the background color to bright black (gray) |
bg_bright_red | \x1b[101m | Sets the background color to bright red |
bg_bright_green | \x1b[102m | Sets the background color to bright green |
bg_bright_yellow | \x1b[103m | Sets the background color to bright yellow |
bg_bright_blue | \x1b[104m | Sets the background color to bright blue |
bg_bright_magenta | \x1b[105m | Sets the background color to bright magenta |
bg_bright_cyan | \x1b[106m | Sets the background color to bright cyan |
bg_bright_white | \x1b[107m | Sets the background color to bright white |
Style/Color | ANSI Code | Description |
---|---|---|
bold | \x1b[1m | Makes the text bold or bright |
faint | \x1b[2m | Makes the text faint or dim |
underline | \x1b[4m | Underlines the text |
blink | \x1b[5m | Makes the text blink (less supported) |
Returns:
Bool
:TRUE
if the style was applied,FALSE
if it was not
Example Usage:
STYLE("red")
DISPLAY("This text is red")
CLEAR_STYLE()