About Basp
Basp is a cool programming language which has similar syntax to JavaScript. It features a clean syntax, built-in functions, and support for common programming constructs like loops, conditionals, and functions.
It uses JavaScript as its underlying engine. It has 0 dependencies and was made over the course of a few weeks.
Basp is an acronym for Ben, Astro, Sky, and Pixel. Ben is myself (obviously), Astro and Sky are my dogs, and Pixel is my guinea pig.
While this website is the offical page for Basp, it isn't running the exact same version as the downloadable one on GitHub. Some changes include:
- Added Binary Search built-in function (see bottom of Built-In Functions)
- Removed Import keywords
- All code is updated from CommonJS to ES6 (doesn't affect usage)
- Strings can be compared to enum values (see bottom of Enum)
- Some array bug fixes
- Brand new UI using html/js/css instead of Vue.js (old UI found in /web directory on GitHub)
- If the error occurred within the parser or interpreter (runtime), it will be displayed now
- Added enum documentation (finally)
- Created error documentation
Basp is still in development (maybe), so expect bugs and missing features. If you find any issues or have suggestions for new features, please open an issue on the GitHub repository.
Source Code Summary
A brief overview of the source code file structure and line counts as of the latest update.
| File | Lines |
|---|---|
| config.js | 10 |
| constants.js | 145 |
| error.js | 52 |
| launcher.js | 6 |
| lexer.js | 68 |
| main.js | 66 |
| utils.js | 360 |
| wrapper.js | 14 |
| builtInFunctions/array.js | 42 |
| builtInFunctions/binarySearch.js | 59 |
| builtInFunctions/conversions.js | 37 |
| builtInFunctions/math.js | 104 |
| builtInFunctions/misc.js | 32 |
| builtInFunctions/string.js | 56 |
| builtInFunctions/types.js | 112 |
| builtInFunctions/wrapper.js | 25 |
| interpreter/compare.js | 71 |
| interpreter/INodes.js | 390 |
| interpreter/interpreter.js | 716 |
| interpreter/interpreterSetup.js | 36 |
| parser/nodes.js | 302 |
| parser/parser.js | 813 |
| Total files: 22 | 3516 |
This website is brand new. To view the original website click: View Old Basp Website [UGLY WEBSITE AHEAD]
Arithmetic Operations
Operations
- + Addition
- - Subtract
- * Multiply
- / Divide
- ^ Exponent
- % Modulus
Operations Equal
- += Addition
- -= Subtract
- *= Multiply
- /= Divide
- ^= Exponent
- %= Modulus
Comparison Operations
- < Greater Than
- > Less Than
- <= Greater Than Or Equal To
- >= Less Than Or Equal To
- == Equal To
- != Not Equal To
- & And
- ~ Or
- ! Not
Array
Effectively works as a list. There is no set type/size for arrays.
Add To Array
array numbers = [1, 2, 3] numbers.push(4) //Result: [1, 2, 3, 4]
Index Array
array numbers = [1, 2, 3] numbers[0] //Result: 1
Array Properties & Methods
array numbers = [1, 2, 3] numbers.length numbers.push(5) numbers.pop(0) //Result: 3
Built-In Functions
Conversions
To Number:
Expected Type: String
int number = Number("123")
//Result: 123
int number = Number("Bad Number")
//Result: NaN
To String:
Expected Type: Any
string number = String(123) //Result: "123"
Type Checks
Is Array:
Expected Type: Any
bool isArray = IsArray("Hello World!")
//Result: False
bool isArray = IsArray(["Hello", "World"]) //Result: True
Is Number:
Expected Type: Any
bool isNumber = IsNumber("Hello World!")
//Result: False
bool isNumber = IsNumber(123) //Result: True
Is String:
Expected Type: Any
bool isString = IsString({ Hello })
//Result: False
bool isString = IsString("Hello World!")
//Result: True
Is Enum:
Expected Type: Any
bool isEnum = IsEnum("Not a enum")
//Result: False
bool isEnum = IsEnum({ Hello, World })
//Result: True
Is Boolean:
Expected Type: Any
bool isBoolean = IsBoolean("This is a string")
//Result: False
bool isBoolean = IsBoolean(False) //Result: True
Is Function:
Expected Type: Any
bool isFunction = IsFunction(123) //Result: False
fn int add(int a, int b) {
return a + b
}
bool isFunction = IsFunction(add)
//Result: True
Miscellaneous
Print:
Expected Type: Any
Print("Hello World!")
//Result: [Basp] "Hello World!"
Clear:
No Arguments
Clear() //Result:
Type of:
Expected Type: Any
Typeof(5) //Result: "NUMBER"
Typeof({ Monday, Tuesday })
//Result: "ENUM"
[NEW] Binary Search:
** This built-in function only works in web environment. This was NOT added to the GitHub repo.
Expected Type: Array, Number
array numbers = [1, 2, 3, 4, 5] int index = BinarySearch(numbers, 3) //Result: 2Within the array only numbers are supported. If there is a non-number in the array, it will be ignored.
array numbers = [1, 2, "Bad Number", 4, 5] int index = BinarySearch(numbers, 4) //Result: 2
Import:
** Externally package fetching not implemented **
Expected Type: String
Import will fetch a package from an external repository. You can also import from another .basp file locally.
Import("./utils.basp")
//Result: Utils { ... }
Data Types
- Number (int) - supports floats as well (interesting design choices by me π€)
int number = 5 int floatNumber = 5.5
string name = "Jeffrey"
bool isNumber = True
enum days = { Monday, Tuesday, Wednesday, Thursday, Friday }
array items = ["item1", 2, ["4"], { Four }]
struct Person {
age: int
}
Person person = new Person(5)
Download
Setup Locally (Directly Run)
If you don't want to build it, run it direct from the source code
- Download
Node.js(https://nodejs.org/) - Download Basp repo (https://github.com/Astro-gram/Basp)
- Go into that folder
- Open the config file:
src/config.js - Check the
PRODUCTIONvariable and make sure it isfalse - Change
NON_PRODUCTION_FILE_LOCATIONto the location of your .basp file - Go back to the root of the repo and run:
npm run go
If everything worked, you should get the results of your code in your terminal.
Setup Locally (Build)
(This setup is for Windows only)
- Download
Node.js(https://nodejs.org/) - Install
pkg packageto build executable
npm install -g pkg
- Download Basp repo (https://github.com/Astro-gram/Basp)
- Go into that folder
- Open the config file:
src/config.js - Check the
PRODUCTIONvariable and make sure it istrue - Go back to the root of the repo and run:
npm run build
- If everything was successful, there should be a file named "main.exe" under a folder named "exe"
Basp ββββexe ββββmain.exe
- Run Command Prompt as administrator
- Run these commands to associate .basp files with the executable
assoc .basp=BaspScript ftype BaspScript=PathToMain.exe %1 %*
(Replace "PathToMain.exe" with the path to the main.exe file)
- Create a file with the extension of .basp
Example File:
Basp ββββcode ββββexample.basp
- Write some code in your file and open it
If everything worked, you should get a node.js window popup giving you the results of your code.
Enum
An enum, short for 'enumeration', is a special data type that consists of a set of named values called elements or members. It provides a way to define a collection of related constants.
Declaration
You can declare an enum using the enum keyword, followed by the name and a list of members inside curly braces.
enum Days = {
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
}
Accessing Members
Enum members can be accessed using dot notation. When accessed, they return a string representation of the member name.
Print(Days.Monday)
// Result: { Monday }
Usage in Conditionals
Enums are useful for making code more readable and avoiding magic strings or numbers.
Enum values (ENUM_VALUE) and strings (STRING) are comparable. This means that you can directly compare an enum member to a string like the example below.
string today = "Sunday"
if (today == Days.Sunday) {
Print("It's the weekend!")
} else {
Print("Back to work.")
}
For Loop
For loop allows for break and continue keywords
for (value in ["string", "string2"]) {
//loop through each element in array
}
for (index in (0, 2, 1)) {
//index starts at 0, goes through 2 loops, and steps by 1
}
for (index in 5) {
//Loop 5 times
}
Functions
- Can be passed into other functions as if it were a variable
- Argument types are optional. Accepts any type if not specified
- Return type is not optional - it must be specified (if you don't want to return anything, use "null")
To call a function:
identifier(args)
To declare a function:
fn identifier(args: type): returnType {
statements
}
OR
fn identifier(args): returnType {
statements
}
Example:
fn add(num: int, num2: int): int {
return num + num2
}
add(3, 3)
//Result: 6
fn printValue(value): null {
Print(value)
}
printValue(5)
printValue("Hello")
//Result: 5
//Result: "Hello"
If Statements
if (condition) {
statements
}
elif (condition) {
statements
}
else {
statements
}
Errors
The Error class is used to standardize error reporting across the language. When something goes wrong during parsing or execution, an Error object is created to provide detailed information about the problem, including where it occurred and the context of the execution.
Error Types
Basp defines several types of errors. Here's a summary of what each one means:
InvalidSyntaxError
This error occurs when the code violates the language's grammatical rules, making it impossible for the parser to understand. For example, a missing parenthesis or an unexpected keyword.
[Basp] Invalid Syntax Error: Unexpected token: <Token RPAR: ')'>
at Token 5 <line: 1, col: 10> [PARSER]
TypeError
This error occurs when an operation is performed on a value of an inappropriate type, such as trying to add a number to a function.
[Basp] Type Error: Cannot perform operation on type FUNCTION
at Token 3 <line: 2, col: 5> [RUNTIME]
in main (C:\main.basp)
RuntimeError
This error occurs during the execution of the program, after it has been successfully parsed. Examples include division by zero or referencing a variable that hasn't been defined.
[Basp] Runtime Error: Division by zero
at Token 4 <line: 3, col: 8> [RUNTIME]
in main (C:\main.basp)
IndexOutOfBoundsError
This error occurs when trying to access an element of an array using an index that is outside the valid range (e.g., a negative index or an index greater than or equal to the array's length).
[Basp] Index Out Of Bounds Error: Index 5 is out of bounds for array of length 3
at Token 7 <line: 5, col: 12> [RUNTIME]
in main (C:\main.basp)
InternalError
This error indicates a problem within the Basp interpreter itself, rather than an issue with your code. It often signifies a bug in the language's implementation. If you encounter this, please report it.
UnknownError
This is a general-purpose error type used when a more specific category is not available.
Error Structure
An error object contains the following information:
- position: The token index, line, and column number where the error occurred.
- error: The category of the error (e.g., "Runtime", "Type").
- details: A human-readable message explaining the specific cause of the error.
- context: The execution context, used to generate a stack trace for runtime errors.
Stack Trace
When an error occurs, Basp provides a stack trace to help you debug. The trace shows the sequence of function calls that led to the error.
[Basp] RuntimeError Error: Something went wrong
at Token 12 <line: 10, col: 4> [RUNTIME]
in innerFunction (C:\utils.basp)
in outerFunction (C:\main.basp)
in main (C:\main.basp)
The stack trace indicates whether the error happened during parsing [PARSER] or execution [RUNTIME] and lists the file and function where the error originated ONLY for a [RUNTIME] error. This is because the parser doesn't a context (a way to keep track of errors).
Import
** Web environment does not support package importing **
Import data from other basp files
Structured Result
file1.basp
import FoodMenu from "./file2.basp" as Menu
Print(Menu)
//Result: Export { FoodMenu: "Food 1: Chicken | Food 2: Steak" }
file2.basp
string FoodMenu = "Food 1: Chicken | Food 2: Steak"
Import gives a Export structure as a return value which contains all of the data imported.
Import also allows you to import more than one piece of data:
file1.basp
import FoodMenu, Drinks from "./file2.basp" as Menu
Print(Menu)
//Result: Export { FoodMenu: "Food 1: Chicken | Food 2: Steak", Drinks: "Drink 1: Coke | Drink 2: Pepsi" }
file2.basp
string Menu = "Food 1: Chicken | Food 2: Steak" string Drinks = "Drink 1: Coke | Drink 2: Pepsi"
Destructured Result
file1.basp
import FoodMenu, Drinks from "./file2.basp" Print(FoodMenu) Print(Drinks) //Result: "Food 1: Chicken | Food 2: Steak" //Result: "Drink 1: Coke | Drink 2: Pepsi"
file2.basp
string FoodMenu = "Food 1: Chicken | Food 2: Steak" string Drinks = "Drink 1: Coke | Drink 2: Pepsi"
Math
Math is a struct containing properties and methods
Properties
- (Math.PI)
Methods
- Floor (Math.Floor)
- Ceil (Math.Ceil)
- Round (Math.Round)
- Absolute Value (Math.Abs)
- Square Root (Math.Sqrt)
- Random (Math.Random)
All functions are based off the Javascript implementation meaning that all functions will behave the same as the Javascript version
String
Strings are created using double quotes ("), similar to any other language. Strings can't be made using single quotes (') currently.
//Create a string like this string text = "Hello World"
Properties & Methods
Get the length of a string:
Returns Integer
string text = "test" int length = text.length //length = 4
Convert string to upper case:
Returns String
string text = "test" string textInCaps = text.toUpperCase() //textInCaps = "TEST"
Convert string to lower case:
Returns String
string text = "TEST" string textInCaps = text.toLowerCase() //textInCaps = "test"
Split text into chunks:
Returns Array
string text = "I Like Basp!"
array textInChunks = text.split(" ")
//textInChunks = [ "I", "Like", "Basp!" ]
Structure
struct Person {
age: int,
name: string
}
Person person = new Person(5, "jeff")
Print(person)
//Result: Person { age: 5, name: "jeff" }
Both properties in struct 'Person' are not writable.
To make it writable:
struct Person {
!age: int,
!name: string
}
Person person = new Person(5, "jeff")
person.age = 6
//Result: Person { age: 6, name: "jeff" }
While Loop
While loop allows for break and continue keywords
while (condition) {
statements
}
Comments
Comments must take up the whole line currently