Code Editor
1
Console Output
Ready to run your code...
Keyboard Shortcuts:
Run Code: Ctrl + R Save Code: Ctrl + S Clear Console: Ctrl + L Indent: Ctrl + K | Tab Unindent: Ctrl + U

Basp v1.1.0 | Created by Ben Webster

View more projects like this on benwebs.com

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.js10
constants.js145
error.js52
launcher.js6
lexer.js68
main.js66
utils.js360
wrapper.js14
builtInFunctions/array.js42
builtInFunctions/binarySearch.js59
builtInFunctions/conversions.js37
builtInFunctions/math.js104
builtInFunctions/misc.js32
builtInFunctions/string.js56
builtInFunctions/types.js112
builtInFunctions/wrapper.js25
interpreter/compare.js71
interpreter/INodes.js390
interpreter/interpreter.js716
interpreter/interpreterSetup.js36
parser/nodes.js302
parser/parser.js813
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: 2
Within 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 { ... }

Comments

Comments must take up the whole line currently

//Good
string hello = "Hello World!"
string hello = "Hello World!" //Bad

Data Types

  • Number (int) - supports floats as well (interesting design choices by me πŸ€”)
  • int number = 5
    int floatNumber = 5.5
  • String (string)
  • string name = "Jeffrey"
  • Boolean (bool)
  • bool isNumber = True
  • Enum (enum)
  • enum days = { Monday, Tuesday, Wednesday, Thursday, Friday }
  • Array (array) - works as a list
  • array items = ["item1", 2, ["4"], { Four }]
  • Structure (struct)
  • 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

  1. Download Node.js (https://nodejs.org/)
  2. Download Basp repo (https://github.com/Astro-gram/Basp)
  3. Go into that folder
  4. Open the config file: src/config.js
  5. Check the PRODUCTION variable and make sure it is false
  6. Change NON_PRODUCTION_FILE_LOCATION to the location of your .basp file
  7. 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)

  1. Download Node.js (https://nodejs.org/)
  2. Install pkg package to build executable
npm install -g pkg
  1. Download Basp repo (https://github.com/Astro-gram/Basp)
  2. Go into that folder
  3. Open the config file: src/config.js
  4. Check the PRODUCTION variable and make sure it is true
  5. Go back to the root of the repo and run:
npm run build
  1. If everything was successful, there should be a file named "main.exe" under a folder named "exe"
Basp
└───exe
└───main.exe
  1. Run Command Prompt as administrator
  2. 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)

  1. Create a file with the extension of .basp

Example File:

Basp
└───code
└───example.basp
  1. 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
}