Quick Language Overview
For those with good programming experience, reading through tons of pages of documentation may look like a waste of time since they'll already be equipped enough to pick off new stuff fast. If you are one of them — this is for you!
Click the
REPL
box to toggle the REPL mode on and off.
Reference
- Quick Language Overview
- Reference
- Start in REPL mode
- Running a script
- Print to the standard output
- Variables
- Comments
- String interpolation
if...else...
statements- Ternary operators
?:
while
loopdo...while
loopiter
loop- Ranges
for
loop- Iterables
- Functions
- Type check and conversions
- Class
- Class methods
- Class constructors
- Class fields
- Static class fields and methods
- Private class fields and methods
- Inheritance
- Class decorator
- Overriding builtin-methods
- Class as iterables
- Reading and Writing Files
- Throwing exceptions
- Handling exceptions
- Custom Exceptions
- Asserts
- Importing packages and modules
- Creating packages
- Fist-class package management
Start in REPL mode
Simple type blade
in your terminal to launch REPL mode
$ blade
Blade 0.0.86 (running on BladeVM 0.1.1), REPL/Interactive mode = ON
Clang 13.0.0, (Build time = Feb 8 2022, 02:47:36)
Type ".exit" to quit or ".credits" for more information
%>
Running a script
Type blade
followed by the path to the file in the terminal.
Blade scripts use the .b
extension.
$ blade /path/to/file.b
Print to the standard output
You can use the echo
keyword to print any object to standard output or use the print()
function to print one or more objects to standard output.
%> echo 'Hello, World' # using echo keyword
'Hello, World'
%> print('Hello,', 'World\n') # using the print function
Hello, World
@note: Statements are terminated by newlines, but they can also be separated by semicolons
;
@convention: use newlines
Variables
Use the var
keyword to declare variables.
%> var a = 10
%> a # in the REPL mode, you can omit `echo` to do a quick print
10
%> var b = 'Hello, World'
%> b
'Hello, World'
%> a = 25
%> b = 33
%> a; b # printing a and b to screen at the same time
25
33
Operators such as +=
, -=
, ++
, --
are all supported.
%> a++
%> b--
%> a; b
26
32
%> a += 10
%> b *= 5
%> a; b
36
160
Comments
Single line comments begin with an #
, multiline comments are wrapped in /*
and */
and they can be nested.
# a single line comment
/*
Multiline comments
/*
can be nested...
*/
*/
String interpolation
Blade strings allow you to evaluate expressions within strings using the interpolation syntax ${expression...}
.
@note: Blade strings always support interpolation and can span multiple lines whether wrapped in
''
or""
%> var a = 93
%> 'a is ${a}'
'a is 93'
%> var b = 'a is ${a}'
%> b
'a is 93'
%> a = 107
%> '${b.replace("is", "was")}, but is now ${a}'
'a was 93, but is now 107'
The arguments to replace could have used ''
pairs too. We only used ""
for clarity.
More
if...else...
statements
Blade has the standard if... else...
you'll find in most C-like languages except that it doesn't require the parenthesis.
%> var a = 20
%> if a > 20 {
.. echo 'a is greater than 20'
.. } else {
.. echo 'a is less than or equal to 20'
.. }
'a is less than or equal to 20'
It can be inlined if only one statement follows
if a == 20 echo 'a is 20'
else echo 'a is not 20'
/**
* Output:
* a is 20
*/
Ternary operators ?:
Simple expression time decisions are supported via ternary operators
%> var a = 10
%> echo a < 10 ? 'Failed.' : 'Congrats!'
'Congrats!'
using
statements
This statement takes a value and matches it against a set of constants to run the piece of code associated with it.
%> var name = 'james'
%>
%> using name {
.. when 10 echo 'My name is 10'
.. when true {
.. echo 'My name is true'
.. echo 'Yes, true is a constant!'
.. }
.. when 'james' echo 'My name is James'
.. default echo "I don't know my name"
.. }
'My name is James'
while
loop
%> var items = ['Apple', 'Mango', 'Banana', 'Peach']
%> var index = 0
%>
%> while index < items.length() {
.. echo 'Item at ${index} is ${items[index]}'
.. index++
.. }
'Item at 0 is Apple'
'Item at 1 is Mango'
'Item at 2 is Banana
'Item at 3 is Peach'
do...while
loop
%> var i = 5
%> do {
.. echo i
.. i--
.. } while i > 0
5
4
3
2
1
iter
loop
Blade's version of C/JavaScript's for loops. See here for why we didn't call it a for loop.
%> iter var i = 0; i < 5; i++ {
.. echo 'Iteration ${i}'
.. }
'Iteration 0'
'Iteration 1'
'Iteration 2'
'Iteration 3'
'Iteration 4'
Ranges
You can define numbers over a range using Blade's range operator ..
and they can be used with loops very easily.
%> 0..5
<range 0-5>
%> 1..10
<range 1-10>
%> 21..3
<range 21-3>
for
loop
%> var items = ['Nigeria', 'Ghanan', 'Senegal', 'Mali']
%> for item in items {
.. echo '${item} is a country'
.. }
'Nigeria is a country'
'Ghanan is a country'
'Senegal is a country'
'Mali is a country'
%>
%> var details = {name: 'Blade', version: 0.5, website: 'https://bladelang.org'}
%> for key, value in details {
.. echo '${key} -> ${value}'
.. }
'name -> Blade'
'version -> 0.5'
'website -> https://bladelang.org'
Iterables
Blade comes with built-in support for strings, ranges, bytes, lists, and dictionaries as its primary iterables and they support all common operations such as indexing and slicing. The concepts shown below apply to all iterables with the exception that strings are immutable.
%> var list = [1, 'game', false] # any data type can fit in...
%> var dictionary = {name: 'Blade', version: '0.0.86'}
%> var byte_array = bytes([104, 101, 108, 108, 111]) # hello
%> var sized_bytes = bytes(10) # a byte array of size 10 with all entries as 0x0
%>
%> echo list.length()
3
%> echo byte_array[2]
108
%> echo list[1,-1]
[game]
%>
%> # update value(string values cannot be updated as they are immutable)
%> dictionary['version'] = 'version 0.0.86'
%> list[0]++
%>
%> echo dictionary
{name: Blade, version: version 0.0.86}
%> echo list
[2, game, false]
%>
%> for _, value in byte_array {
.. echo chr(value)
.. }
'h'
'e'
'l'
'l'
'o'
Functions
Use the def
keyword to define a function.
@note: The default value of a parameter is
nil
. For this reason, parameters can be omitted when calling functions.
%> # define function name that takes one argument - name.
%> def say_hello(name) {
.. echo 'Hi, ' + name
.. }
%>
%> say_hello('Parker')
'Hi, Parker'
%> say_hello() # name will default to nil
'Hi, '
%>
%> def add(a, b) {
.. return a + b
.. }
%>
%> add(30, 45)
75
%>
%> # Functions can be nested into closures as they are first class objects...
%> def outer_function() {
.. def inner_function() {
.. return 20
.. }
.. return inner_function
.. }
%>
%> outer_function()()
20
Blade also has support for Anonymous function. Click more for information. More
Type check and conversions
You can check if a value is a type by calling the related built-in function all named as is_...
or convert to that type by calling the built-in to_...
functions. E.g.
%> is_string('hello')
true
%> to_list('hello')
[h, e, l, l, o]
@note: They type of a dictionary is shortened to
dict
for builtin functions. i.e. we haveto_dict()
andis_dict()
.
Class
%> class Person { /* class content goes here... */ }
%>
%> # creating instance of a class...
%> var person = Person()
Class methods
%> class Person {
.. say_hello(name) {
.. return 'Hello, ${name}'
.. }
.. }
%>
%> var person = Person()
%> person.say_hello('Hank')
'Hello, Hank'
Class constructors
Constructors are simply class methods bearing the same name as the class.
%> class Person {
..
.. Person(name) {
.. self.name = name
.. }
..
.. say_hello() {
.. return 'Hello, ${self.name}'
.. }
.. }
%>
%> var person = Person('Stark')
%> person.say_hello()
'Hello, Stark'
Class fields
%> class Point {
.. var x = 2.143
.. var y = 7.941
.. }
%>
%> var point = Point()
%> '${point.x}, ${point.y}'
'2.143, 7.941'
Static class fields and methods
%> class Math {
.. static var PI = 3.142
..
.. static abs(x) {
.. return x >= 0 ? x : -x
.. }
.. }
%>
%> Math.PI
3.142
%> Math.abs(-91)
91
Private class fields and methods
Class fields or methods whose name starts with an underscore (_
) are private and only accessible from the current class.
%> class Class {
.. var _number_of_desks = 10
..
.. _get_desks() {
.. return self._number_of_desks
.. }
..
.. get_desks() {
.. return self._get_desks()
.. }
.. }
%>
%> var cls = Class()
%> cls.get_desks()
10
%> cls._number_of_desks # this will cause an exception
Unhandled Exception: cannot call private property '_number_of_desks' from instance of Class
StackTrace:
<repl>:1 -> @.script()
Inheritance
%> class Animal {
.. Animal(name) {
.. self.name = name
.. }
..
.. greet() {
.. echo 'Hello ${self.name}'
.. }
..
.. call() {
.. echo 'Come here ${self.name}'
.. }
.. }
%>
%> class Dog < Animal {
.. Dog(name) {
.. parent(name)
.. }
..
.. call() {
.. parent.call()
.. echo 'Whats up?'
.. }
.. }
%>
%> var dog = Dog('Bingo')
%> dog.greet()
'Hello Bingo'
%> dog.call()
'Come here Bingo'
'Whats up?'
Class decorator
These are methods meant to provide information on how to use the class and they cannot be called directly by instances of the said class.
%> class Class {
.. @decoration() {
.. return 1
.. }
.. }
Overriding builtin-methods
Simply create a decorator for the function.
%> class Person {
.. Person(name) {
.. self.name = name
.. }
.. }
%>
%> class Animal {
.. Animal(name) {
.. self.name = name
.. }
..
.. @to_string() {
.. return '<Animal ${self.name}>'
.. }
.. }
%>
%> var person = Person('James')
%> var animal = Animal('Dog')
%>
%> to_string(animal) # using to_string function to convert classes to string
'<Animal Dog>'
%> to_string(person)
Unhandled Exception: undefined method '@to_string' in Person
StackTrace:
<repl>:1 -> @.script()
@note: Some builtin functions do not support decoration. e.g.
max()
.
Class as iterables
To convert a class into an iterable, simply implement the @iter()
and @itern()
decoration. @itern()
returns the current index and @iter()
returns the current value.
%> class Iterable {
.. var items = ['Richard', 'Alex', 'Justina']
..
.. @iter(x) {
.. return self.items[x]
.. }
..
.. @itern(x) {
.. if x == nil return 0
..
.. if x < self.items.length() - 1
.. return x + 1
.. return false
.. }
.. }
%>
%> for it in Iterable() {
.. echo it
.. }
'Richard'
'Alex'
'Justina'
Reading and Writing Files
Writing/Creating a file
%> var f = file('test.txt', 'w')
%> var written = f.write('It works!')
%> f.close()
%>
%> if written echo 'File created successfully!'
'File created successfully!'
Reading a file
%> file('test.txt').read()
'It works!'
Throwing exceptions
Blade comes with the built-in class Exception
and all exceptions must derive from this class.
%> raise Exception('I died')
Unhandled Exception: I died
StackTrace:
<repl>:1 -> @.script()
Handling exceptions
%> catch {
.. echo 'do something'
.. raise Exception('there was an exception here')
.. echo 'do something else'
.. } as error
'do something'
%>
%> if error {
.. echo error.type
.. echo error.message
.. echo error.stacktrace
.. }
'Exception'
'there was an exception here'
' <repl>:3 -> @.script()'
Custom Exceptions
Simply subclass Exception
as follows.
%> class CustomError < Exception {}
%>
%> raise CustomError('I died too!')
Unhandled CustomError: I died too!
StackTrace:
<repl>:1 -> @.script()
Asserts
%> assert 10 == 10
%> assert 10 > 11
Illegal State:
StackTrace:
<repl>:1 -> @.script()
%> assert 10 > 11, 'Failue!'
Illegal State: Failue!
StackTrace:
<repl>:1 -> @.script()
Importing packages and modules
Import package/module
%> import http
%> http
<module http at /blade/libs/http/index.b>
Import specific items from package/module
%> import http { HttpClient }
%> HttpClient
<class HttpClient at 0x143f1f060>
%> http
Unhandled Exception: 'http' is undefined in this scope
StackTrace:
<repl>:1 -> @.script()
Import all exported values into current namespace
%> import math { * }
%> math
Unhandled Exception: 'math' is undefined in this scope
StackTrace:
<repl>:1 -> @.script()
%> product
<function product at 0x133e10180>
Rename package/module on import
%> import os as osystem
%> os
Unhandled Exception: 'os' is undefined in this scope
StackTrace:
<repl>:1 -> @.script()
%> osystem
<module osystem at /blade/libs/os.b>
Import module/package in relative path
import .test # prefix the import path with a dot
import ..test # prefix path with a range(..) for the parent directory.
@note: Every Blade
.b
script is a module.
Creating packages
Create a directory with the name of the package and create an index.b
file in the directory. That's all!
my_package
|-- index.b
|...
Import as usual!
Fist-class package management
Blade allows you to download packages and libraries into your source code directory and call it from your code as if it were a standard library. It's simple.
Simply create a directory .blade/libs
at the root of your application and download
Blade modules and/or packages into the directory into that directory. For example,
create the directory .blade/libs
in your current directory and create a file test.b
in that directory. Paste the following code into it.
var name = 'Paula'
Now create a new file sample.b
in your current directory and save the following code in it:
import test
echo test.name
Now run your file using:
$ blade sample.b
You should see Paula
printed in the console. Voila!
This features extends to C extensions created for Blade as well.