Sunday, August 30, 2015

LiveCode Builder without the LiveCode bit

Since my last post almost two years ago, I've moved to Edinburgh. I now work for LiveCode as an open source software engineer.

Introducing LiveCode Builder

LiveCode 8, the upcoming release of the LiveCode HyperCard-like application development environment, introduces a new xTalk-like language for writing LiveCode extensions. It's called LiveCode Builder (or LCB). It shares much of the same syntax as the original LiveCode scripting language, but it's a compiled, strongly-typed language.

Most of the public discussion about LiveCode Builder has revolved around using it to extend LiveCode — either by creating new widgets to display in the user interface, or by writing libraries that add new capabilities to the scripting language. However, one topic that *hasn't* been discussed much is the fact that you can write complete applications using only LCB, and compile and run them without using the main LiveCode engine at all.

LiveCode Builder without the engine

This is actually pretty useful when writing simple command-line tools or services that don't need a user interface and for which the main LiveCode engine provides little value (for example, if you need your tool to start up really quickly). There are a couple of good examples that I've written during the last few months.

The LCB standard library's test suite uses a test runner written in LCB. This is quite a useful "smoke test" for the compiler, virtual machine, and standard library -- if any of them break, the test suite won't run at all!

More recently, I've written a bot that connects our GitHub repositories to our BuildBot continuous integration system. Every few minutes, it checks the status of all the outstanding pull requests, and either submits new build jobs or reports on completed ones. This is also written entirely in LCB. One of main advantages of using LCB for this were that LCB has a proper List type that can contain arrays as elements.

"Hello World" in LCB

A pure LCB program looks like this:

module org.example.helloworld

public handler Main()
   write the contents of file "hello.txt" to the output stream
end handler

end module

It has a top-level module, that contains a public handler called Main. Note that unlike in C or C++, the Main handler doesn't take any arguments (you can access the command-line arguments using `the command arguments`).

Next, you need to compile your application using the lc-compile tool. To do this, you need to locate the directory from the LiveCode installation that contains the `.lci` files -- these are LiveCode's equivalent to C or C++'s header files. For example, on my system, I could compile the example above using (let's assume I've saved it to a file called hello.lcb:

$ export TOOLCHAIN='/opt/runrev/livecodecommunity-8.0.0-dp-3 (x86_64)/Toolchain/
$ "$TOOLCHAIN/lc-compile" --modulepath . --modulepath "$TOOLCHAIN/modules/lci" --output hello.lcm hello.lcb

These commands generate two files: hello.lcm, containing LCB bytecode, and org.example.helloworld.lci containing the interface.

Finally, you can run the program using lc-run. This is a really minimal tool that provides only the LCB virtual machine and standard library.

$ echo "Hello world!" > hello.txt
$ "$TOOLCHAIN/lc-run" hello.lcm
Hello world!

Finding out more

To more information on the standard library syntax available in LCB, visit the "LiveCode Builder" section of the dictionary in the LiveCode IDE. Note that the "widget", "engine" and "canvas" syntax isn't currently available to pure LCB programs. You should also check out the "Extending LiveCode" guide.