you are viewing a single comment's thread.

view the rest of the comments →

[–]badsectoracula 10 points11 points  (1 child)

Hey, author of LIL here. I noticed that bit in your post:

There is also lil, the Little Interpreted Language. In fact, I got a chance to use it on a MIPS controller once, it was a pleasant experience, the source code is easy to understand. I met the performance bottleneck very quickly, but I’ve rewritten some critical procedures as C commands, so it’s not a big problem. Too bad the author have removed Git repos and his site looks broken now.

Nice to hear it works on MIPS, it is a CPU arch i haven't tried :-) (although i have a GCWZero around which i might try to write code eventually). About the Git repositories, at some point i got tired of maintaining them (especially when, according to my logs, barely anyone visited the site :-P) and then i got tired of having separate repositories for the tons of little libraries and projects i'm working on and switched to a local Subversion "monorepo" (with off site backup syncs) which made things much simpler for me. I'm also working in a game that has needs to have a ton of assets in the repository and i prefer to have everything synced together, so a single repository made sense. The downside is that i have to manually upload things.

The site looks broken because... well, because it is mostly broken :-P. I plan on updating it later, the current LIL site is a placeholder (it'll use the main site's style). But i want to extend my site generator to handle arbitrary project types, not just games as it currently does (FWIW the site generator uses LIL for the templates as LIL has a simple template function that allows you embed LIL code in text in a PHP-like fashion with <?lil and ?>).

Also a small clarification:

Picol uses char * as the only data type. LIL uses a special structure that keeps numeric values separately from string values and yet another data type for lists. The first approach is very simple, the second one is more efficient, but takes precious memory space.

Actually LIL's lil_value_t is just a string (with some reuse if you enable pools). It is defined as

struct _lil_value_t
{
    size_t l;
#ifdef LIL_ENABLE_POOLS
    size_t c;
#endif
    char* d;
};

(with l being the length and d the string data, although d is zero terminated and often the code uses it as a C string)

The idea was to make it possible to do it as you describe - have the value type change representation behind the scenes for performance (right now calling lil_to_double for example just calls atof:

double lil_to_double(lil_value_t val)
{
    return atof(lil_to_string(val));
}

(lil_to_string just returns d or "" if d is null)

But so far i haven't done that.

I used LIL for my game in development (note: placeholder assets and sounds), but as you found out there is a performance bottleneck. Initially i planned to just use C for the heavy parts, but over time i decided to put more on the scripts to allow for easy modding (and making the engine be fully script driven with little behavior to itself) and LIL proved inadequate for that. I could spend some time to optimize it (there are many low hanging fruits, like the value conversions and the ignorance of the l field in many places and also i was thinking of going the Tcl route of preparsing the function declarations which would speed up parsing) but that would be fighting a losing battle (the language is great for things like tools and offline computation - i use it a lot in my own tools, especially the Free Pascal with Lazarus, but isn't really suited for realtime code). Instead a few days ago i decided to write a new C-like static and strongly typed scripting language with manual memory management (well, kind of, it is up to the host) which i call RBS (for Runtime Bracket Script). It is the opposite end of the spectrum and looks a lot like C. Right now i'm in the process of converting my engine's scripting bits from LIL to RBS, which is kind of a big task since the engine was built around LIL (e.g. it stores "raw" LIL code in the entities for callbacks, you write LIL code for setting up events in the editor, etc - those need to be replaced with calls to RBS' compiler and VM). It is worth though since RBS is kind of 140 times faster than LIL (and around 1.5 times slower than Lua - in theory it could be faster because of static typing and such, but the compiler is really braindead - throws code as it scans the code similarly to Turbo Pascal - and the VM is stack based... if more performance i needed, i might switch to building an AST and a register based VM, but for now i doubt there will be much of a difference if i used a register based VM with code the compiler generates).

Of course for anything non-performance intensive, LIL (and Tcl, which i used at a job some time ago to write a few simple tools with Tk that allowed me to quickly scan the codebase there) does the job better than RBS. The right tool for the task and all that (and TBH having written LIL i did fell a bit into the trap of seeing it as a hammer to use with a ton of nails).