documentations updated

This commit is contained in:
Thakee Nathees 2021-06-01 17:20:41 +05:30
parent 39c3bb41a0
commit 3b36e9002e
12 changed files with 154 additions and 92 deletions

View File

@ -3,9 +3,15 @@
<img src="https://user-images.githubusercontent.com/41085900/117528974-88fa8d00-aff2-11eb-8001-183c14786362.png" width="500" >
</p>
**Pocketlang** is a small (~3000 semicollons) and fast functional programming language written in C. It's syntactically similar to Ruby and it can be learned in less than an hour. Including the compiler, bytecode VM and runtime, it's a standalone executable with zero external dependecies just as it's self descriptive name. The pocketlang VM can be embedded in another hosting program very easily.
**Pocketlang** is a small (~3000 semicollons) and fast functional programming
language written in C. It's syntactically similar to Ruby and it can be learned
in less than an hour. Including the compiler, bytecode VM and runtime, it's a
standalone executable with zero external dependecies just as it's self descriptive
name. The pocketlang VM can be embedded in another hosting program very easily.
The language is written using [Wren Language](https://wren.io/) and their wonderful book [craftinginterpreters](http://www.craftinginterpreters.com/) as a reference.
The language is written using [Wren Language](https://wren.io/) and their
wonderful book [craftinginterpreters](http://www.craftinginterpreters.com/) as
a reference.
### What pocketlang looks like
@ -25,31 +31,52 @@ for i in 0..10
end
```
## Performance!
## Performance
The source files used to run benchmarks could be found at `test/benchmarks/` directory. They were ran using a small python script in the test directory.
- PC: ASUS N552VX, Intel Core i7-6700HQ 2.6GHz, 12GB SODIMM Ram
- Lnaguages: pocketlang (pre-alpha), wren v0.3.0, python v3.7.4, ruby v2.7.2,
All the tests are ran 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.
![preformance2](https://user-images.githubusercontent.com/41085900/120123257-6f043280-c1cb-11eb-8c20-a42153268a0f.png)
When it comes to loops pocketlang much faster (even faster than [wren](https://wren.io/), the language I'm using as a reference) because we have dedicated opcode instructions for iterations and calling builtin functions. And it's is a functional language, which makes is possible to avoid object orianted/ class instance creation overhead.
![preformance](https://user-images.githubusercontent.com/41085900/120123257-6f043280-c1cb-11eb-8c20-a42153268a0f.png)
The source files used to run benchmarks could be found at `test/benchmarks/`
directory. They were ran using a small python script in the test directory.
## Building From Source
It can be build from source easily without any depencency, requirenments or even a build system, just a c99 compatible compiler is enough. It can be compiled with the following command.
It can be build from source easily without any depencency, or additional
requirenments except for a c99 compatible compiler. And build systems are
optional. It can be compiled with the following command.
#### gcc/mingw
#### GCC
```
gcc -o pocket cli/*.c src/*.c -Isrc/include -lm -Wno-int-to-pointer-cast
```
#### msvc
#### MSVC
```
cl /Fepocket cli/*.c src/*.c /Isrc/include && rm *.obj
```
For other compilers it's the same (If you weren't able to compile it, please report by [opening an issue](https://github.com/ThakeeNathees/pocketlang/issues/new)). In addition you can use some of our build scripts (Makefile, batch script for MSVC, SCons) in the `build/` directory. For more see [build from source docs](https://thakeenathees.github.io/pocketlang/Getting%20Started/build%20from%20source.html).
### 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.
If you weren't able to compile it, please report by [opening an issue](https://github.com/ThakeeNathees/pocketlang/issues/new)).
In addition you can use some of our build scripts (Makefile, batch script for MSVC, SCons)
in the `build/` directory. For more see [build from source docs](https://thakeenathees.github.io/pocketlang/Getting%20Started/build%20from%20source.html).
## References
- Bob Nystrom.(2021) *craftinginterpreters* [online] Available at: www.craftinginterpreters.com/ (Accessed January 2021)
- 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)
- Carol E. Wolf of Pace University, adapted by P. Oser. *The Shunting Yard Algorithm* [online] Available at: http://mathcenter.oxford.emory.edu/site/cs171/shuntingYardAlgorithm/ (Accessed September 2020)

View File

@ -3,11 +3,13 @@
## Without a build script
Pocketlang has zero dependencies and you don't even require a build system, just a c99 compiler is enought, and it can be compiled with the following command.
It can be build from source easily without any depencency, or additional
requirenments except for a c99 compatible compiler. And build systems are
optional. It can be compiled with the following command.
Using gcc
```
gcc -o pocket cli/*.c src/*.c -Isrc/include -lm
gcc -o pocket cli/*.c src/*.c -Isrc/include -lm -Wno-int-to-pointer-cast
```
Using MSVC
@ -15,11 +17,22 @@ Using MSVC
cl /Fepocket cli/*.c src/*.c /Isrc/include && rm *.obj
```
For other compilers it's the same (If you weren't able to compile it with any c99 compatible compiler, please report by [opening an issue](https://github.com/ThakeeNathees/pocketlang/issues/new)). And add ` -Wno-int-to-pointer-cast` for gcc to suppress those warnings emitted when nan-tagging is enabled.
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.
If you weren't able to compile it, please report by [opening an issue](https://github.com/ThakeeNathees/pocketlang/issues/new)).
## Using a build script
You could find some of the build script for different build system in the `build/` direcroty. If you don't find a scirpt for your prifered system, request on github by [opening an issue](https://github.com/ThakeeNathees/pocketlang/issues/new) or feel free to contribute one.
You could find some of the build script for different build system in the `build/`
direcroty. If you don't find a scirpt for your prifered system, request on github
by [opening an issue](https://github.com/ThakeeNathees/pocketlang/issues/new) or
feel free to contribute one.
## Makefile
@ -27,19 +40,37 @@ You could find some of the build script for different build system in the `build
cd build && make
```
I haven't tested the makefile on different platforms except for "windows subsystem for linux".
And the makefile is still need to be imporved. If you find any problems with the script or
have any improvements, let us know in [github](https://github.com/ThakeeNathees/pocketlang).
## Batch script with MSVC
```
cd build && build
```
You don't require to run the script from a Visual Studio .NET Command Prompt, It'll search for the MSVS installation path and use it to compile. But if it can't, try running on VS command prompt.
You don't need to run the script from a Visual Studio .NET Command Prompt,
It'll search for the MSVS installation path and use it to compile. But if it
can't, try running on VS command prompt.
## SCons
pocketlang mainly focused on [scons](https://www.scons.org/), and it's recommended to use it for contributions since it has various configurations and compiler support. It's a python based build system. You need to have python 3.6+ installed in your development environment. To install scons run `python3 -m pip install scons`. Make sure it's version is 3.0+ and for Visual Studio 2019 it require v3.1.1+. In Linux if scons using python2 instead of 3 you'll have to edit `/usr/local/bin/scons` or `~/.local/bin/scons` to ensure that it points to `/usr/bin/env python3` and not `python`
pocketlang mainly focused on [scons](https://www.scons.org/), and it's
recommended to use it for contributions since it has various configurations
and compiler support. It's a python based build system. You need to have
python 3.6+ installed in your development environment. To install scons run
`python3 -m pip install scons`. Make sure it's version is 3.0+ and for Visual
Studio 2019 it require v3.1.1+. In Linux if scons using python2 instead of 3
you'll have to edit `/usr/local/bin/scons` or `~/.local/bin/scons` to ensure
that it points to `/usr/bin/env python3` and not `python`
```
cd build && scons
```
You can specify the number of jobs scons to use to speed up the building process using the -j flag (-j6, -j8). To generate Visual Studio project files add `vsproj=true` argument when building. To compile using mingw in windows use `use_mingw=true` argument. If your build failed feel free to [open an issue](https://github.com/ThakeeNathees/pocketlang/issues/new).
You can specify the number of jobs scons to use to speed up the building process
using the -j flag (-j6, -j8). To generate Visual Studio project files add `vsproj=true`
argument when building. To compile using mingw in windows use `use_mingw=true` argument.
If your build failed feel free to [open an issue](https://github.com/ThakeeNathees/pocketlang/issues/new).

View File

@ -1,4 +1,3 @@
# Contributing
Lorem **ipsum** dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
TODO

View File

@ -1,22 +1,4 @@
# Functions
```ruby
def f()
print('test')
end
```
## Another title
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud
```ruby
fn = func print('test') end
f2 = func(arg) print('arg =', arg) end
```
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud
TODO

View File

@ -1,17 +1,5 @@
# Variables
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud
```ruby
from os import clock as c
some_variable = 12
print(some_variable) ## prints 12
some_variable = 'testing'
print(some_variable) ## prints 'testing'
```
## More lorem ipsum
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud. Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud
TODO

View File

@ -8,8 +8,8 @@
#include "utils.h"
#include "vm.h"
// TODO: Replace bufferFill with bufferWrite, and (maybe) shrink the buffer if
// it's more than enough.
// The buffer "template" implementation of diferent types, defined in the
// buffers.h header.
#define DEFINE_BUFFER(M__NAME, M__NAME_L, M__TYPE) \
void M__NAME_L##BufferInit(M__NAME##Buffer* self) { \

View File

@ -7,7 +7,16 @@
#define BUFFERS_TEMPLATE_H
#include "common.h"
#include "include/pocketlang.h"
// The macro 'DECLARE_BUFFER()' emulate the C++ template to declare and define
// different types of buffer objects.
// A buffer of type 'T' will contain a heap allocated array of 'T' with the
// capacity of 'Tbuffer.capacity' as 'T* Tbuffer.data'. When the capacity is
// filled with 'T' values (ie. Tbuffer.count == Tbuffer.capacity) the buffer's
// internal data array will be reallocate to a capacity of 'GROW_FACTOR' times
// it's last capacity.
#define DECLARE_BUFFER(M__NAME, M__NAME_L, M__TYPE) \
typedef struct { \

View File

@ -39,6 +39,10 @@
// available in C++98.
#define ERROR_MESSAGE_SIZE 256
/*****************************************************************************
* TOKENS *
*****************************************************************************/
typedef enum {
TK_ERROR = 0,
@ -187,10 +191,14 @@ static _Keyword _keywords[] = {
};
// Compiler Types ////////////////////////////////////////////////////////////
/*****************************************************************************
* COMPILIER INTERNAL TYPES *
*****************************************************************************/
// Precedence parsing references:
// https://en.wikipedia.org/wiki/Shunting-yard_algorithm
// http://mathcenter.oxford.emory.edu/site/cs171/shuntingYardAlgorithm/
// http://journal.stuffwithstuff.com/2011/03/19/pratt-parsers-expression-parsing-made-easy/
typedef enum {
PREC_NONE,

View File

@ -9,10 +9,21 @@
#include "common.h"
#include "var.h"
// Pocketlang compiler is a single pass compiler, which means it doesn't go
// throught the basic compilation pipline such as lexing, parsing (AST),
// analyzing, intermediate codegeneration, and target codegeneration one by one
// instead it'll generate the target code as it reads the source (directly from
// lexing to codegen). Despite it's faster than multipass compilers, we're
// restricted syntax-wise and from compiletime optimizations, yet we support
// "forward names" to call functions before they defined (unlike C/Python).
typedef struct Compiler Compiler;
// This will take source code as a cstring, compiles it to pocketlang bytecodes
// and append them to the script's implicit main (the $SourceBody function).
bool compile(PKVM* vm, Script* script, const char* source);
// Mark the heap allocated ojbects of the compiler at the garbage collection
// called at the marking phase of vmCollectGarbage().
void compilerMarkObjects(PKVM* vm, Compiler* compiler);
#endif // COMPILER_H

View File

@ -64,14 +64,21 @@ uint32_t utilHashNumber(double num) {
uint32_t utilHashString(const char* string) {
// FNV-1a hash. See: http://www.isthe.com/chongo/tech/comp/fnv/
uint32_t hash = 2166136261u;
#define FNV_prime_32_bit 16777619u
#define FNV_offset_basis_32_bit 2166136261u
uint32_t hash = FNV_offset_basis_32_bit;
for (const char* c = string; *c != '\0'; c++) {
hash ^= *c;
hash *= 16777619;
hash *= FNV_prime_32_bit;
}
return hash;
#undef FNV_prime_32_bit
#undef FNV_offset_basis_32_bit
}
/****************************************************************************

View File

@ -203,7 +203,7 @@ struct Object {
struct String {
Object _super;
uint32_t hash; //< Hash value of the string.
uint32_t hash; //< 32 bit hash value of the string.
uint32_t length; //< Length of the string in \ref data.
uint32_t capacity; //< Size of allocated \ref data.
char data[DYNAMIC_TAIL_ARRAY];

View File

@ -133,12 +133,12 @@ PkHandle* vmNewHandle(PKVM* self, Var value);
// working set '------------------------'
//
// First we preform a tree traversel from all the vm's root objects. such as
// temp references, handles, vm's running fiber, current compiler (if it has
// any) etc. Mark them (ie. is_marked = true) and add them to the working set
// (the gray_list). Pop the top object from the working set add all of it's
// referenced objects to the working set and mark it black (try-color marking)
// We'll keep doing this till the working set become empty, and at this point
// any object which isn't marked is a garbage.
// stack values, temp references, handles, vm's running fiber, current
// compiler (if it has any) etc. Mark them (ie. is_marked = true) and add
// them to the working set (the gray_list). Pop the top object from the
// working set add all of it's referenced objects to the working set and mark
// it black (try-color marking) We'll keep doing this till the working set
// become empty, and at this point any object which isn't marked is a garbage.
//
// Every single heap allocated objects will be in the VM's link list. Those
// objects which are reachable have marked (ie. is_marked = true) once the