Skip to content

torkelicious/ObSL

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

The Obliberry Scripting Language

ObSL is a small interpreted, thread safe, dynamically typed programming language designed for game logic inside the
(work in progress) Obliberry Game Engine, made to be easily extendable.


Contents


Documentation


Features

  • Dynamically typed variables
  • Functions with default parameters
  • Closures and first-class functions
  • Structs with custom constructors
  • Dynamic objects
  • Dynamic arrays with negative indexing
  • Module importing
  • Exception handling
  • Runtime reflection
  • Built-in regex support
  • Automatic garbage collection with cyclic reference handling

Building from Source

Prerequisites

  • C++20 compatible compiler (GCC, Clang, MSVC)
  • CMake
  • Git

Clone the Repository

git clone https://github.com/torkelicious/ObSL.git
cd ObSL

Build the Project

mkdir build
cd build
cmake ..
cmake --build .

CMake Options

Option Default Description
OBSL_BUILD_RUNTIME ON Builds the obsl_runtime CLI executable. Set to OFF to build only the obsl static library useful when embedding ObSL into another project (e.g. the Obliberry Game Engine) that doesn't need the standalone CLI/REPL.
cmake .. -DOBSL_BUILD_RUNTIME=OFF

Run the Interpreter

./obsl_runtime

Only available when OBSL_BUILD_RUNTIME is ON (the default).


Quick Start

println "Hello, World!";

Variables are dynamically typed:

var score = 100;
var name = "Player";
var alive = true;
var nothing = null;

Language Basics

Variables

Variables are declared using the var keyword:

var number = 100;
var text = "hello";
var enabled = true;

Variables can change type:

var value = 10;
value = "Now a string";

Printing

ObSL provides print and println.

print (no newline)

print "Hello ";
print "World";

Output:

Hello World

println (with newline)

println "Hello";
println "World";

Output:

Hello
World

Operators

Arithmetic

var a = 10 + 5;
var b = 10 - 5;
var c = 5 * 2;
var d = 10 / 2;
var remainder = 10 % 3;

Comparison

a == b;
a != b;

a > b;
a >= b;

a < b;
a <= b;

Logical

true and false;
true or false;
!true;

// Alternative syntax
true && false;
true || false;

Assignment

a = 10;

a += 5;
a -= 2;
a *= 3;
a /= 2;

a++;
a--;

Bitwise

var bitAnd = 5 & 3;
var bitOr = 5 | 3;
var bitXor = 5 ^ 3;

var bitNot = ~0;

var left = 2 << 3;
var right = 16 >> 2;

Control Flow

If Statements

var score = 100;

if (score > 50) {
    println "Passed!";
} else {
    println "Failed!";
}

Switch

var value = 2;

switch (value) {
    case 1:
        println "One";
    case 2:
        println "Two";
    default:
        println "Unknown";
}

Type Checking

The is operator checks runtime type:

var value = 10;

if (value is number) {
    println "Number";
}

Supported Types

number
string
boolean / bool
null / nil
function / fn
array
object

Note: These are the type names accepted by is, which are distinct from the strings returned by the reflection function type_of() most notably, is uses function/fn where type_of() returns "callable". See the Standard Library Reference for type_of()'s exact return values.

Expressions

var result = 5 + 3;

if (result is number) {
    println "Math result";
}

Precedence

is binds tighter than equality checks:

(x == y) is boolean;

Null Checking

var value = null;

if (value is null) {
    println "Empty";
}

if (value is nil) {
    println "Also empty";
}

Loops

While

var i = 0;

while (i < 5) {
    println i;
    i++;
}

For

var total = 0;

for (var i = 0; i < 10; i++) {
    total += i;
}

Foreach

var numbers = [10, 20, 30];
var sum = 0;

foreach (var number in numbers) {
    sum += number;
}

Break

for (var i = 0; i < 10; i++) {
    if (i == 5) {
        break;
    }
}

Arrays

Arrays are dynamic and support negative indexing:

var arr = [10, 20, 30];

println arr[0];

arr[-1] = 99;

Negative Indexing

arr[-1] // last element
arr[-2] // second last element

Methods

println arr.len;

arr.push(100);

var item = arr.pop();

arr.clear();

Functions

Basic Functions

fn sayHello(name) {
    println "Hello " + name;
}

sayHello("Player");

Return Values

fn add(a, b) {
    return a + b;
}

var result = add(5, 10);

Default Parameters

fn damage(amount = 10) {
    return amount;
}

println damage();

Closures

fn createAdder(amount) {
    fn add(value) {
        return value + amount;
    }

    return add;
}

var addFive = createAdder(5);
println addFive(10);

Structs

struct Vector3 {
    x;
    y;
    z;
}

Default Values

struct Player {
    health = 100;
    name = "Unknown";
}

Example:

var player = Player();
println player.health;

Objects

var obj = Object();

obj.value = 42;
obj.printValue = printValue;

Modules

using "assets/scripts/module.obsl";

Error Handling

Try / Catch

try {
    var result = sqrt("invalid");
} catch (err) {
    println err;
}

Assertions

assert(player != null, "Player missing");

Throwing Errors

throw("Something failed!");

Built-in Library

Conversion

to_string(value);
to_fixed(value, decimals);
to_num(string);

Math

sqrt(x);
pow(a, b);
abs(x);
min(a, b);
max(a, b);
floor(x);
ceil(x);
round(x);
random();
clamp(value, min, max);

Trigonometry

sin(x);
cos(x);
tan(x);
atan2(y, x);

Helpers

pi();
rad(degrees);
deg(radians);
lerp(start, end, t);
map_value(value, inMin, inMax, outMin, outMax);

Strings

len(text);
to_upper(text);
to_lower(text);
trim(text);
contains(text, value);
starts_with(text, value);
substring(text, start, length);
replace(text, old, new);

Regex

regex_match(text, pattern);
regex_search(text, pattern);
regex_replace(text, pattern, replacement);
regex_find_all(text, pattern);

System Utilities

Files

file_exists(path);
read_file(path);
write_file(path, data);
get_file_ext(path);

Input

read();
readln();

Time

clock();
sleep_thread(seconds);

Environment

get_env(name);

Process

exit(code);

Reflection

Types

type_of(value);

Returns:

null
bool
number
string
array
object
callable

Functions

get_arity(function);

Objects

has_field(object, "name");
get_fields(object);

Garbage Collection

ObSL includes automatic garbage collection with cyclic reference handling.


Examples

See the Examples/ directory for additional runnable usage examples.


todo:

  • Proper Linter
  • LSP?

This is still very much a toy language :)


Resources & Acknowledgments

Learning Resources

ObSL's design and implementation were informed by:

Third-Party Libraries

Library License Purpose More
nlohmann/json v3.12.0 MIT JSON output for --lint mode docs/THIRD_PARTY_LICENSES.md

License

ObSL is licensed under the MIT License. See third-party dependency licenses in THIRD_PARTY_LICENSES.md.

About

A small, interpreted, thread-safe, dynamically-typed scripting language for game logic in the Obliberry Game Engine, designed to be easily extendable.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors