FixScript

Blog

FixScript SDK 0.6: WebAssembly, better syntax, SQL, GUI, REPL, console, macros (2024/05/05)

FixScript SDK 0.6 has been released. You can read an introduction to FixScript. A full change log is here.

WebAssembly

While the previous release did the groundwork for WebAssembly support it required much more effort to bring all the libraries to support it and also to improve it further (by making it more self-sufficient).

WebAssembly is now a fully supported platform, both in the browser and as a normal process using WASI. In both cases there is an emulation of the threads so it works the normal way, the asynchronous complexity is on the native side only.

While in the browser there is an option of using real threads by using the SharedArrayBuffer class it is unfortunatelly gated by some server-side headers impeding an easy way to just putting a single file on the webserver, therefore unsupported. Some future release may provide an option to enable the real threads for those who are able/willing to do the extra required steps in their setup. It will require to solve some complications first though.

For the browser the generated output is a single HTML file that embeds everything needed. All you need to do is to put it on the server and open it in the web browser. You can also embed it into other pages using the <iframe> tag.

The FixGUI library supports both desktop and mobile usage. It uses canvas rendering and has some optional functions and classes for improving the performance. On mobile it implements its own inertia scrolling so the behavior is always under your control and not how different browsers would implement it. The implementation uses tiled rendering and multiple canvases to make it smooth and efficient.

You can test the WebAssembly GUI demo below. It shows the code editor widget. When expanded it will automatically go to the fullscreen on mobiles, on iOS devices you need to add it to the home screen first (using the share menu). You can find the complete source code of the example in the SDK.

The syntax highlighting and the autocomplete (by pressing Ctrl+Space) is dynamically adjusted based on the used token processors in the edited file. It also changes the font size based on the browser text size and pixel density.

Syntax improvements

The syntax was improved quite a bit when using the classes token processor.

Length property for arrays and hash tables

It is now possible to use a postfix syntax for obtaining the length of arrays and hash tables. This provides a more natural way to obtain the length.

An example:

var array: Integer[];
for (var i=0; i<array.length; i++) {
    ...
}

instead of:

var array: Integer[];
for (var i=0; i<length(array); i++) {
    ...
}

Extension methods for built-in types

The classes implementation was improved to use a postfix syntax to call the various standard functions related to the built-in types. On top of that it also allows you to define your own methods, for example the FixUtil core library provides a bunch of utility methods for working with strings.

The extension methods feature is not planned as a general feature because with normal classes you can just add the needed methods directly whereas for built-in types you can't.

An example:

import "util/string";

var idx = str.search_char('x');

instead of:

import "util/string";

var idx = string_search_char(str, 'x');

And this is how you can extend the built-in types:

function Array::get_every_nth(nth: Integer, offset: Integer): Value[]
{
    var new_array: Value[] = [];
    for (var i=offset; i<this.length; i+=nth) {
        new_array[] = this[i];
    }
    return new_array;
}

You can use the special Key and Value generic types, more information is here.

Improved console support

Previously the console support was quite rudimentary. It has been expanded to allow the usual expected features such as showing a progress or a prompt.

The API was made friendly to both the users and the programmers. For example the output from other tasks (threads) is paused when the prompt is active. Similarly when showing a progress (updating the same line repeatedly) it is correctly cleaned when using the other functions or when the process exits.

There is also an advanced way to use the console where you have direct access to the whole screen and inputs. This allows you to use more advanced prompts with history and an autocomplete. You can also create text user interfaces (TUI).

SQL support

A support for connecting to SQL databases was added. There is currently support for SQLite and PostgreSQL databases. When using SQLite the library is directly embedded into the binary, no outside dependencies required.

The API makes it easy to do the right thing, using parameterized queries with ease. You can also use a parameterized string to construct SQL queries from individual SQL fragments that contain their associated parameters. Transactions are using a custom statement.

use "io/sql";
use "classes";

function test(sql: SQLConnection, id: Integer)
{
    transaction (sql) {
        var rs = sql.query("SELECT * FROM test WHERE id=?", id);
        while (rs.next()) {
            log("got "+rs.get_string("text_field"));
        }
        rs.close();
    }
}

GUI improvements

Work on FixGUI is quite slow because it's a huge endeavor, most work is driven by the actual needs and mostly on the subviews as these are cross-platform and need to be done only once.

While the library has an experimental status it is quite capable and skilled developers can use it. You're welcome to ask for features that you need so that I can prioritise the development for them.

In this release most of the improvements are in an improved MacOS support, most notably the native widgets, basic functionality (such as timers) and bug fixes.

Macros

The macros were improved by adding an ability to use code to directly generate other code. This is for cases where simple token pasting is not enough and having to write a custom token processor is too heavyweight for the given task.

Constant strings

The language was extended to allow creation of constant strings dynamically. Previously it was used just for the constants in the source code. This allows for safe deduplication of the same strings and also can be garbage collected when there is no reference to it.

This also helps to reduce a lot of defensive copies when you want to shield the internal state of the object from the outside. Before this you would have to make a defensive copy both when setting the value and storing it inside the object and getting it to return to the caller.

REPL

I've added an example that implements REPL that allows you to interactively try the language in the command line. I wasn't sure about it's utility before, but I have already used it to easily check some things related to parsing. It also serves as a nice more complex example to show off the various features of the language and it's libraries.

It features the advanced prompt functionality of the new console support with a history, searching and an autocompletion with an easy API.

Currently it supports just the base language, however improvements will be done in the future to support the more advanced features as well.

Sponsoring

If you like the language and it's libraries you can sponsor the language. It will allow to improve FixScript even further and increase the release pace.

You can sponsor with a one-time or a monthly donation by clicking on this button:

What's next?

The immediate plans are for working more on the IDE along with the GUI improvements. You can already see a glimpse of the code editor in the WebAssembly demo above.

Comments

1. jezek2 (2024/05/17 16:45)
Interesting information about SharedArrayBuffers:

https://godotengine.org/article/progress-report-web-export-in-4-3/

It looks like the required headers also remove other important features (ability to load resources from other domains) so the support for it will probably never be done.

The current approach works well and has the nice feature of being able to interact with the DOM and other stuff from any of the emulated threads.

I will certainly try to use Web Workers to accelerate some stuff in the future, but not in the traditional style of multithreading.

Add comment

Name:
Content:
Confirmation code:
 
  (type the letters shown in the picture)