**Pocketlang** is a lightweight (~3000 semicolons) and [fast](https://github.com/ThakeeNathees/pocketlang#performance) object oriented, embeddable scripting language written in C. It has a ruby flavoured python syntax, that can be learned [within 15 minutes](https://thakeenathees.github.io/pocketlang/docs/v0.1.0/Reference/Cheat-Sheet.html). Including the compiler, bytecode VM and runtime, it's a standalone executable with zero external dependencies just as it's self descriptive name. The pocketlang VM can be embedded in another hosting program very easily. [Wren Language](https://wren.io/) and their wonderful book [Crafting Interpreters](http://www.craftinginterpreters.com/) were used as a reference to write this language. ## What pocketlang looks like ```ruby # Python like import statement. from time import clock as now # A recursive fibonacci function. def fib(n) if n < 2 then return n end return fib(n-1) + fib(n-2) end # Prints all fibonacci from 0 to 10 exclusive. for i in 0..10 print("fib($i) = ${fib(i)}") end ``` ## Try It Now You can [try pocketlang on your browser](https://thakeenathees.github.io/pocketlang/try-online.html). It's a [WebAssembly](https://webassembly.org/) build of the VM compiled using [emscripten](https://emscripten.org/). Note that in the webassembly version of the language, some features (input, file handling, relative import, etc.) have disabled, has limited memory allocations, and the stdout calls might be slower. ## Documentation The pocketlang documentation is hosted at https://thakeenathees.github.io/pocketlang/ which is built from the `docs` branch generated by a little python script at `docs/generate.py`. Note that the documentations are WIP and might not be up to date. ## Performance Pocketlang uses [NaN-Boxing](https://leonardschuetz.ch/blog/nan-boxing/) which is a memory efficient way to represent dynamic types and dealing with them are much faster. It supports [tail call](https://en.wikipedia.org/wiki/Tail_call) [optimization](https://wiki.c2.com/?TailCallOptimization). When a function returns a call, the callee can re-use the caller's stack frame, this will optimize memory from O(n) to O(1) and for [tail recursive](https://www.youtube.com/watch?v=-PX0BV9hGZY) it'll completely prevent stackoverflows and yet it's faster. All benchmarks below were executed on: Windows10 (64bit), ASUS N552VX, Intel Core i7-6700HQ 2.6GHz with 12GB SODIMM Ram. And the language versions are: pocketlang (pre-alpha), wren v0.3.0, python v3.7.4, ruby v2.7.2. ![performance](https://user-images.githubusercontent.com/41085900/120123257-6f043280-c1cb-11eb-8c20-a42153268a0f.png) The source files used to run benchmarks can be found at `test/benchmarks/` directory. They were executed using a small python script in the test directory. ## Building From Source It can be build from source easily without any dependencies, or additional requirements except for a c99 compatible compiler. It can be compiled with the following command. #### GCC / MinGw / Clang (alias with gcc) ``` gcc -o pocket cli/*.c src/core/*.c src/libs/*.c -Isrc/include -lm ``` #### MSVC ``` cl /Fepocket cli/*.c src/core/*.c src/libs/*.c /Isrc/include && rm *.obj ``` #### Makefile ``` make ``` To run the make file on windows with `mingw`, you require the GNU `make` tool which you can get from [msys2](https://www.msys2.org/) or [cygwin](https://www.cygwin.com/). #### Windows batch script ``` scripts\build.bat ``` You don't have to run the script from a Visual Studio .NET developer command prompt, It'll search for the MSVS installation path and setup the build environment. ### For other compiler/IDE 1. Create an empty project file / makefile. 2. Add all C files in the src directory. 3. Add all C files in the cli directory (**NOT** recursively). 4. Add `src/include` to include path. 5. Compile. Visual studio project files can be generated with the premake, see [scripts/README](https://github.com/ThakeeNathees/pocketlang/scripts/README.md) for more information. If you weren't able to compile it, please report us by [opening an issue](https://github.com/ThakeeNathees/pocketlang/issues/new). ## References - Bob Nystrom.(2021) *craftinginterpreters* [online] Available at www.craftinginterpreters.com/ (Accessed January 2021) - Mark W. Bailey, Nathan C. Weston (June 2001) Technical report. *Performance Benefits of Tail Recursion Removal in Procedural Languages* [online] Available at http://cs.hamilton.edu/~mbailey/pubs/techreps/TR-2001-2.pdf - Roberto Ierusalimschy, Luiz Henrique de Figueiredo, Waldemar Celes *Closures in Lua* [pdf] Available at https://www.cs.tufts.edu/~nr/cs257/archive/roberto-ierusalimschy/closures-draft.pdf (Accessed March 2022) - Leonard schütz.(2020) *Dynamic Typing and NaN Boxing* [online] Available at https://leonardschuetz.ch/blog/nan-boxing/ (Accessed December 2020) - Bob Nystrom.(2011) *Pratt Parsers: Expression Parsing Made Easy* [online] Avaliable at http://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/ (Accessed December 2020)