Skip to content

Reference

Shigeru Chiba edited this page Dec 7, 2024 · 15 revisions

BlueScript Reference

Introduction

BlueScript is a scripting language that borrows heavily from TypeScript syntax. However, not all TypeScript syntax is currently supported in BlueScript. Notable features that are not yet supported include exceptions, certain built-in objects, and async/await functionality.

BlueScript also diverges from TypeScript in some key semantics, particularly in its type system. Unlike TypeScript, BlueScript separates integer and float types, treating them as distinct.

Primitive Types

BlueScript provides six primitive types as well as object types:

  • integer (32bit integer)
  • number (an alias of integer)
  • float (32bit floating-point number)
  • string
  • boolean
  • null and undefined (they are the same)
  • any

Any kind of value can be implicitly converted into any type, and vice versa.

  • When an integer value is converted, the resulting value is represented as a 30bit integer.
  • When a float value is converted, the resulting value is represented as a 30bit floating-point number, where only 6 bits are allocated for an exponent instead of 8 bits.
  • For logical operations and the condition expressions of coditional/loop statements such as if and while, 0, 0.0, false, null, and undefined are considered as false while other values are true.

Literals

  • null and undefined (they are the same)
  • true
  • false
  • Numbers such as 7 and 0.3
  • Character strings such as "text" and 'text'
  • Arrays

Built-in Objects

Array

Array Objects

BlueScript currently supports arrays of integer, float, boolean, string, class types, array types, and any-type. Their names are T[], where T is an element type.

Array types are invariant. For example, integer[] is not a subtype of any[] or its super type. But array types can be implicitly converted into any-type, and vice versa. In other words, a reference to an array of integer, any, etc. is implicitly converted into an any-type value. An any-type value is also implicitly converted into a reference to an array if the any-type value points to an array object of that array type. Otherwise, a runtime error is thrown.

Array Literals

Array literals are defined using square brackets, with elements separated by commas.

let arr = [1, "Foo", 42];

The type of an array literal is array of the most specifict super type of the static types of all the elements. If there exists such a super type, the type of the array literal is array of any.

Array Construction

An array object is created by new Array<T>(size, value). Here, T is a meta variable representing a type name. size is the number of the array elements. value is the initial value for the array elements. T can be integer, float, boolean, string, an array type, a class type, or any-type.

let iarr = new Array<integer>(3, 0);

When the element type is integer, float, boolean, or any, the second argument to the Array constructor can be omitted. The initial values are zero, false, or undefined. For example, new Array<integer>(7) is a valid expression, and it constructs an array including 7 elements.

Type Annotations

Array types are represented by Type[]. Here, Type is a meta variable representing the type name of array elements.

let iarr: integer[] = [1, 2, 3];
let sarr: string[] = ['one', 'two', 'three'];

Note that Array or Array<integer> is not a valid type name.

Accessing Elements

Only numeric indices are supported for accessing array elements.

let arr = [1, 3, 4];
print(arr[0]); // 1

Accessing an index out of bounds will result in a runtime error.

let arr = [1, 2, 3];
print(arr[5]); // ** error: array index out of range: 5

Currently, array methods such as push, pop, map, filter, etc., are not supported in BlueScript.

The length property represents the length of an array.

let arr = [1, 2, 3];
print(arr.length);    // 3

If the type of arr is any-type, the type of arr[i] is any. arr[i] = v throws a runtime error if v is not a value of the element type for the array that arr points to. For example,

let arr: integer[] = [1, 2, 3];
let arr2: any = arr;
print(arr2.length)        // 3
print(arr2[0])            // 1
print(typeof arr2[0]);    // 'any'
arr2[1] = 'five';         // runtime error

Byte arrays

An Uint8Array object is also available. Its elements are unsigned 8 bit integers.

let arr = new Uint8Array(3, 0)    // create an array containing 3 elements.  Their initial values are 0.
print(arr[1])      // 0
arr[0] = 7
print(arr[0])      // 7
print(arr.length)  // 3

Then second argumemnt to the constructor of `Uint8Array' cannot be omitted.

Expressions and Operators

Operators

Increment and Decrement Operators

The operands' types of the increment and decrement operators must be integer, float, or any.

  • Postfix Increment/Decrement Operators
    The value is incremented or decremented by 1, and the original value is returned.

    let x = 1;
    print(x++); // 1
    print(x);   // 2
    
    let y = 1.0;
    print(y--); // 1.0
    print(y);   // 0.0
  • Prefix Increment/Decrement Operators
    The value is incremented or decremented by 1, and the updated value is returned.

    let x = 1;
    print(++x); // 2
    print(x);   // 2

Unary Operators

BlueScript supports the following unary operators:

  • + (Unary plus, returns the value of its operand. The operand's type must be integer, float, or any.)
  • - (Unary negation, returns the negation of its operand. The operand's type must be integer, float, or any.)
  • ~ (Bitwise NOT. The operand's type must be integer or any.)
  • ! (Logical NOT. The operand's type can be any kind of type.)
print(-3)  // -3

Arithmetic Operators

The operands' types must be integer, float, or any. If either the left operand or the right operand is any, the resulting type is any. If either left or right is float, the resulting type is float. Otherwise, it is integer.

  • + (Addition)
  • - (Subtraction)
  • * (Multiplication)
  • / (Division)
  • % (Modulus) The operands must be an integer value or an any-type value holding an integer value.
  • ** (Exponentiation) The operands are converted into double values, and pow() in C computes the result.

Relational Operators

The operands' types must be integer, float, string, or any. The resulting type is boolean. Both operands share the same type or any-type. If a left or right operand is any-type, the value of the other operand is converted into an any-type value before comparison.

  • < (Less than)
  • > (Greater than)
  • <= (Less than or equal to)
  • >= (Greater than or equal to)

Equality Operators

  • == and === are used as equality operators. Their semantics is the same as the === operator in JavaScript.
  • != and !== are used as inequality operators. Their semantics is the same as the !== operator in JavaScript.

If either the left operand or the right operand is a boolean type, the other operand must be also boolean type.

Bitwise Shift Operators

The operands' types must be integer. The type of the resulting value is integer.

  • << (Left shift)
  • >> (Right shift)
  • >>> (Unsigned right shift)

Binary Bitwise Operators

The operands' types must be integer. The type of the resulting value is integer.

  • & (AND)
  • | (OR)
  • ^ (XOR)

Binary Logical Operators

  • && (Logical AND)
  • || (Logical OR)

Type operators

  • typeof (returns the static type name of its operand. Unlike JavaScript, it is not a dynamic type name.)

  • instanceof (checks whether the left operand is an instance of the class given as the right operand or its subclass. The right operand may be string or Array. The type of the left operand must be a class type, string, an array type, or any.)

obj instanceof Array results in true when obj is an array object no matter what its element type is.

Ternary Operator

The ternary operator ? : is used for conditional expressions:

let result = condition ? trueValue : falseValue;

Assignment Operators

BlueScript supports the following assignment operators:

  • =
  • +=, -=, *=, /= (Compound assignment operators. The operands' type must be integer, float, or any.)
  • %= (The operands' type must be integer or any.)

Statements and Declarations

Variable Declarations

Variables in BlueScript are declared using let or const.

let x = 10;
let y: float = 5.5;
const t: boolean = true

Loops

  • while loop

    let i = 0;
    while (i < 10) {
        print(i);
        i++;
    }
  • for loop

    for (let i = 0; i < 10; i++) {
        print(i);
    }
  • break and continue

    for (let i = 0; i < 10; i++) {
        if (i == 5) {
            continue;
        }
        if (i == 8) {
            break;
        }
        print(i);
    }

Conditional Statements

  • if … else …

    let a = 10;
    if (a > 5) {
        print("Greater than 5");
    } else {
        print("Less than or equal to 5");
    }

Functions

Declarations

Functions are declared with function keyword.

function add(a:integer, b:integer):integer {
  return a + b;
}

The function definition can be overwritten only if the function’s argument types and return type are the same.

Arrow Functions

let add = (a: integer, b: integer): integer => a + b;

Currently, closures are not supported in BlueScript.

Classes

Class declarations

Classes in BlueScript are declared by using class keyword.

class Rectangle {
  height:float;
  width: float;

  constructor(height: float, width:float) {
    this.height = height;
    this.width = width;
  }

  getArea() {
    return this.height * this.width;
  }
}

Currently, access modifiers are not supported in BlueScript.

extends

extends keyword is used to create subclasses.

class Square extends Rectangle {
  constructor(sideLength:float) {
    super(sideLenght, sideLength);
  }
}

new

new keyword is used to create class instance.

let rect = new Rectangle(13, 15);

Access properties and methods

Properties and methods are accessed with dot notation.

print(rect.height) // 13
print(rect.getArea()); // 195

In the methods' definitions, the properties and methods are accessed with this keyword.

class Rectangle {
  height:float;
  width: float;

  constructor(height: float, width:float) {
    this.height = height;
    this.width = width;
  }

  getArea() {
    return this.height * this.width;
  }
}