readme rewrite

master
Daniel Kolesa 2021-04-07 01:25:28 +02:00
parent 2de2c9b46c
commit e254000f5f
1 changed files with 110 additions and 66 deletions

176
README.md
View File

@ -4,77 +4,122 @@
## Overview ## Overview
Libcubescript is an embeddable implementation of the CubeScript scripting Cubescript is a minimal scripting language first introduced in the Cube FPS
language. CubeScript is the console/config language of the Cube engines/games and carried over into derived games and game engines such as Sauerbraten.
(and derived engines/games). It's a simplistic language defined around the Originally being little more than a few hundred lines of code, serving
idea of everything being a string, with Lisp-like syntax (allowing various primarily as the console and configuration file format of the game, it
control structures to be defined as commands). grew more advanced features as well as a bytecode VM.
## Benefits and use cases Nowadays, it is a minimal but relatively fully featured scripting language
based around the concept that everything can be interpreted as a string.
It excels at its original purpose as well as things like text preprocessing.
It comes with a Lisp-like syntax and a variety of standard library functions.
CubeScript is suitable for any use that calls for a simple scripting language Libcubescript is a project that aims to provide an independent, improved,
that is easy to embed. It's particularly strong at macro processing, so it can separate implementation of the language, available as a library, intended to
be used as a preprocessor, or for any string-heavy use. Since it has descended satisfy the needs of the OctaForge project. It was originally forked from
from a console language for a video game, it can still be used for that very Cubescript as present in the Tesseract game/engine and gradually rewritten;
purpose, as well as a configuration file language. right now, very little of the original code remains. At language level it is
mostly compatible with the other implementations (although with a stricter
parser and extra features), while the standard library does not aim to be
fully compatible. Some features are also left up to the user to customize,
so that it is not tied to game engines feature-wise.
Its thread-friendliness allows for usage in any context that requires parallel Like the codebase it is derived from, it is available under the permissive
processing and involvement of the scripting system in it. zlib license, and therefore compatible with just about anything.
As far as benefits over the original implementation go, while it is based on ## Benefits and differences
the original implementation, it's largely rewritten; thus, it's gained many
advantages, including:
* Independent implementation (can be embedded in any project) There's a variety of things that set this implementation apart:
* No global state (multiple CubeScripts in a single program)
* Modern C++20 API
* C++ lambdas can be used as commands (including captures and type inference)
* Error handling including recovery (protected call system similar to Lua)
* Stricter parsing (strings cannot be left unfinished etc.)
* Loop control statements (`break` and `continue`)
* No manual memory mangement, values manage themselves
* Clean codebase that is easy to read and contribute to
* Support for arbitrary size integers and floats (can be set at compile time)
* Allows building into a static or shared library, supports `-fvisibility=hidden`
* Custom allocator support (control over how heap memory is allocated)
There are some features that are a work in progress and will come later: * It's independent and can be embedded in any project
* There is no global state, so you can have as many Cubescripts as you want,
in one program
* Written in C++20, following modern language conventions, both internally
and at API level
* That means the ability to use lambdas as commands, including captures,
type inference and so on
* There is a robust allocator system in place, and all memory the library
uses is allocated through it; that gives you complete control over its
memory (for tracking, sandboxing, limits, etc.)
* A large degree of memory safety, with no manual management
* Strings are interned, with a single reference counted instance of any
string existing at a time, which lowers memory usage and simplifies its
management
* Minimal stack memory usage, which means no artificial limits on recursion
depth as well as safe usage from threads and coroutines with small stacks
* Errors will no longer cause the interpreter to march on, instead acting
like real errors
* Protected calls allow you to catch errors in a similar way to exceptions,
and nearly every error can be caught
* Stricter parsing, with things like unfinished strings being caught
* Loops now have `break` and `continue` statements
* Customizable integer and floating point types
* Full support for symbol visibility in API
* Highly portable and cross-platform, no dependencies other than a compiler
* Clean codebase that is easy to pick up and contribute to
* More helpful debug information (proper line infos at both parse and run time) More features and enhancements are planned, such as:
* A degree of thread safety (see below)
* Coroutines
The API is currently very unstable, as is the actual codebase. Therefore you * Improved support for debugging information (line information tracking
should not use the project in production environments just yet, but you're at runtime rather than just compile-time)
also free to experiment - feedback is welcome. * Thread safety
**The project is also open for contributions.** You can use pull requests on Right now, the codebase is unstable, but quickly approaching production
GitHub and there is also a discussion channel `#octaforge` on FreeNode; this readiness. You are encouraged to test things and report bugs; contributions
project is a part of the larger OctaForge umbrella. of any kind are also welcome (you can use pull requests in our Gitea instance
as well as the GitHub mirror).
## Threads and coroutines Our primary means of communication is the `#octaforge` IRC channel on Freenode.
*(In progress)* ### Threads
Libcubescript supports integration with coroutines and threads by providing a The API provides a concept of threads. The first created thread is the main
concept of threads itself. You can create a thread (child state) using the thread, which owns all variables and most state. Based on the main thread
main state and it will share global data with the main state, but it also you can create side threads, which share a lot of state with the main thread
has its own call stack. but have their own call stack.
The "global" state is thread safe, allowing concurrent access from multiple In the future, accesses to "global" state (the state shared between threads)
threads. The "local" state can be yielded as a part of the coroutine without will be made thread safe.
affecting any other threads.
This functionality is not exposed into the language itself, but it can be That means you will be able to use the library in multithreaded contexts, as
utilized in the outside native code. long as you make sure to only use any Cubescript thread from at most one
real thread at a time (accesses to thread state will not be thread-safe).
Right now, this at least means the library is coroutine-safe. You can call
into a Cubescript thread inside a coroutine, yield somewhere mid-command,
and still be able to access the state safely through other Cubescript
threads. Once you resume the coroutine, it will continue where it left
off, without anything being wrong.
Since strings are interned and reference counted, this is also geared
towards thread safety - any API returning a string will give you your own
reference, which means nothing can free it while you are still using it.
Similarly, things taking string references will generally increment the
count for their own purposes. This all happens automatically thanks to
C++'s scoped value handling.
## Building and usage ## Building and usage
There are no dependencies (other than a suitable compiler and the standard The library has absolutely no dependencies other than a C++20 compiler,
library). similarly there are no dependencies on system or architecture specific
things, so it should work on any OS and any CPU.
Libcubescript is built using `meson`. After installing it, you can do The C++20 support does not have to be complete. Right now, tested
something like this: compilers include:
* GCC 10
* Clang 11
* Visual Studio 2019
Older versions of GCC and Clang may work, with no guarantees.
You will need [Meson](https://mesonbuild.com/) to build the project. Most
Unix-like systems have it in their package management, on Windows there is
an installer available on their website. Being written in Python, you can
also use `pip` to get an up to date version on any OS.
Once you have it, compiling is simple, e.g. on Unix-likes you can do:
~~~ ~~~
mkdir build && cd build mkdir build && cd build
@ -82,22 +127,21 @@ meson ..
ninja all ninja all
~~~ ~~~
Link the `libcubescript` library together with your application and everything Refer to Meson's manual for how to customize whether you want a shared or
should just work. It also builds the REPL by default. static library and so on. By default, you will get a shared library plus
a REPL (interactive interpreter). The REPL also serves as an example of
how to use the API.
For the REPL (when not disabled with `-Drepl=disabled`) you have a choice of If you don't want the REPL, use `-Drepl=disabled`. When compiled, it can
two line editing libraries - either the `readline` library (which is always have support for line editing and command history. This is provided either
disabled by default, so you need to enable it manually) or the `linenoise` through `linenoise` (which is a minimal single-file line editing library
library (bundled and enabled by default). There is also a fallback without bundled with the project, and is the default) or through `readline` (a
any line editing, used when you disable both (but then there is no line popular line editing library on many Unix-like systems). There is also
editing or history). a fallback for when you disable both (but then you lose line editing and
command history in the interpreter).
The version of `linenoise` bundled with the project is `cpp-linenoise`, available The version of `linenoise` bundled with the project is `cpp-linenoise`, available
at https://github.com/yhirose/cpp-linenoise. Our version is modified, so that at https://github.com/yhirose/cpp-linenoise. Our version is modified, so that
it builds cleanly with our flags, and so that it supports the "hints" feature it builds cleanly with our flags, and so that it supports the "hints" feature
available in original `linenoise`. Other than the modifications, it is baseed available in original `linenoise`. Other than the modifications, it is baseed
on upstream git revision a927043cdd5bfe203560802e56a7e7ed43156ed3. on upstream git revision `a927043cdd5bfe203560802e56a7e7ed43156ed3`.
## Licensing
See COPYING.md for licensing information.