Fix typos + rename variables (#73)

* fixed typos in src/

* fixed typos in docs/

* fixed typos in README and tests/

* rename INITALIZE to INITIALIZE

* rename PRIMITE to PRIMITIVE

* rename moudle to module

Co-authored-by: Alexander Patel <acpatel@andrew.cmu.edu>
This commit is contained in:
Alexander Patel 2021-06-15 00:37:49 -07:00 committed by GitHub
parent da5d5d6993
commit c58159b63d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
20 changed files with 155 additions and 155 deletions

View File

@ -3,11 +3,11 @@
<img src="https://user-images.githubusercontent.com/41085900/117528974-88fa8d00-aff2-11eb-8001-183c14786362.png" width="500" > <img src="https://user-images.githubusercontent.com/41085900/117528974-88fa8d00-aff2-11eb-8001-183c14786362.png" width="500" >
</p> </p>
**Pocketlang** is a small (~3000 semicollons) and [fast](https://github.com/ThakeeNathees/pocketlang#performance) **Pocketlang** is a small (~3000 semicolons) and [fast](https://github.com/ThakeeNathees/pocketlang#performance)
functional language written in C. It's syntactically similar to Ruby and it can functional language written in C. It's syntactically similar to Ruby and it can
be learned [within 15 minutes](https://thakeenathees.github.io/pocketlang/getting-started-learn-in-15-minutes.html). be learned [within 15 minutes](https://thakeenathees.github.io/pocketlang/getting-started-learn-in-15-minutes.html).
Including the compiler, bytecode VM and runtime, it's a standalone executable 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 with zero external dependencies just as it's self descriptive name. The pocketlang
VM can be embedded in another hosting program very easily. VM can be embedded in another hosting program very easily.
The language is written using [Wren Language](https://wren.io/) and their The language is written using [Wren Language](https://wren.io/) and their
@ -65,8 +65,8 @@ directory. They were ran using a small python script in the test directory.
See [build documentation](https://thakeenathees.github.io/pocketlang/getting-started-build-from-source.html#using-a-build-script) See [build documentation](https://thakeenathees.github.io/pocketlang/getting-started-build-from-source.html#using-a-build-script)
for using an optional build script (Makefile, batch script for MSVC, SCons found in the `build/` directory). for using an optional build script (Makefile, batch script for MSVC, SCons found in the `build/` directory).
It can be build from source easily without any depencency, or additional It can be build from source easily without any dependencies, or additional
requirenments except for a c99 compatible compiler. It can be compiled with the requirements except for a c99 compatible compiler. It can be compiled with the
following command. following command.
#### GCC #### GCC

View File

@ -36,7 +36,7 @@
- Implement argparse. - Implement argparse.
- -v --version - -v --version
- emit opcodes - emit opcodes
- maybe write a similer .pyc file for pocket - maybe write a similar .pyc file for pocket
- --docs to generate docs from cstring. - --docs to generate docs from cstring.
- dump compiled code to a file. - dump compiled code to a file.
- In keyword. - In keyword.
@ -76,7 +76,7 @@
string (currently our max is uint32_t) and for binary string (currently our max is uint32_t) and for binary
(C doesn't have a sprintf("%b", num) for us. (C doesn't have a sprintf("%b", num) for us.
- Ensure that the bitwise optration result `a << b` can be fit - Ensure that the bitwise operation result `a << b` can be fit
into a double value before casting it to one. and we're allowing into a double value before casting it to one. and we're allowing
the integer overflow when shifting. the integer overflow when shifting.
@ -84,9 +84,9 @@
It's at pre-alpha and every thing is left to It's at pre-alpha and every thing is left to
implement, and nothing would be work as expected. implement, and nothing would be work as expected.
- f = func print() end; print(f) # semicollon should be there. - f = func print() end; print(f) # semicolon should be there.
def f() print() end print(f) # semicollon should be there. def f() print() end print(f) # semicolon should be there.
make it okey to use semicollon freely like new lines. make it okay to use semicolon freely like new lines.
- REPL error message should be the first one (not the last). - REPL error message should be the first one (not the last).
>>> def f() >>> def f()

View File

@ -56,7 +56,7 @@ PAGES = [
def new_context(): def new_context():
return { return {
'{{ TITLE }}' : '', '{{ TITLE }}' : '',
'{{ NAVIGAION }}' : '', '{{ NAVIGATION }}' : '',
'{{ CONTENT }}' : '', '{{ CONTENT }}' : '',
'{{ HOME_URL }}' : '', '{{ HOME_URL }}' : '',
'{{ STATIC_DIR }}' : '', '{{ STATIC_DIR }}' : '',
@ -142,11 +142,11 @@ def generate_page_context(src, dst, navigation):
static_dir = relative_static_dir(dst) static_dir = relative_static_dir(dst)
content = path_to_content(src) content = path_to_content(src)
ctx = new_context() ctx = new_context()
ctx[ '{{ TITLE }}' ] = title ctx[ '{{ TITLE }}' ] = title
ctx[ '{{ NAVIGAION }}' ] = navigation ctx[ '{{ NAVIGATION }}' ] = navigation
ctx[ '{{ CONTENT }}' ] = content ctx[ '{{ CONTENT }}' ] = content
ctx[ '{{ HOME_URL }}' ] = ROOT_URL + 'index.html' ctx[ '{{ HOME_URL }}' ] = ROOT_URL + 'index.html'
ctx[ '{{ STATIC_DIR }}'] = static_dir ctx[ '{{ STATIC_DIR }}' ] = static_dir
return ctx; return ctx;
def get_validated_ext(path) : def get_validated_ext(path) :

View File

@ -3,8 +3,8 @@
## %% Without a build script %% ## %% Without a build script %%
It can be build from source easily without any depencency, or additional It can be build from source easily without any dependency, or additional
requirenments except for a c99 compatible compiler. And build systems are requirements except for a c99 compatible compiler. And build systems are
optional. It can be compiled with the following command. optional. It can be compiled with the following command.
Using gcc Using gcc
@ -30,7 +30,7 @@ If you weren't able to compile it, please report by [opening an issue](https://g
## %% Using a build script %% ## %% Using a build script %%
You could find some of the build script for different build system in the `build/` 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 directory. If you don't find a script for your preferred system, request on github
by [opening an issue](https://github.com/ThakeeNathees/pocketlang/issues/new) or by [opening an issue](https://github.com/ThakeeNathees/pocketlang/issues/new) or
feel free to contribute one. feel free to contribute one.
@ -41,7 +41,7 @@ cd build && make
``` ```
I haven't tested the makefile on different platforms except for "windows subsystem for linux". 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 And the makefile is still need to be improved. If you find any problems with the script or
have any improvements, let us know in [github](https://github.com/ThakeeNathees/pocketlang). have any improvements, let us know in [github](https://github.com/ThakeeNathees/pocketlang).

View File

@ -8,7 +8,7 @@
x = 0 # Creating a variable. x = 0 # Creating a variable.
# In pocketlang statements should end with a new line # In pocketlang statements should end with a new line
# or a semicollon. White space characters except for new # or a semicolon. White space characters except for new
# lines are ignored in pocketlang. # lines are ignored in pocketlang.
a = 1; b = 2; a = 1; b = 2;
@ -68,12 +68,12 @@ def call(fn, x)
return func print('foo') end return func print('foo') end
end end
# Concanative call operator '->' # Concatenative call operator '->'
str_lower(str_strip('Foo ')) # This can be written as below str_lower(str_strip('Foo ')) # This can be written as below
'Foo ' -> str_strip -> str_lower 'Foo ' -> str_strip -> str_lower
'foo' -> print # similer as print('foo') 'foo' -> print # similar to print('foo')
# Fibers & Coroutine # Fibers & Coroutine
#------------------- #-------------------

View File

@ -1,13 +1,13 @@
# %% Import statements and Modules %% # %% Import statements and Modules %%
Each source file in pocketlang itself is a module that can be imported in another module, which makes it easier to split and share the project. There are two major kinds of modules in pocketlang. First one is core modules which are builtin to the VM and the second one is the local modlues where it's a written script file you'll import it with the path of it. Each source file in pocketlang itself is a module that can be imported in another module, which makes it easier to split and share the project. There are two major kinds of modules in pocketlang. First one is core modules which are builtin to the VM and the second one is the local modules where it's a written script file you'll import it with the path of it.
## %% Importing a core module %% ## %% Importing a core module %%
The import statement of the pocketlang is highly inspired from python's import syntax. Here how it looks like. The import statement of the pocketlang is highly inspired from python's import syntax. Here how it looks like.
```ruby ```ruby
# To import a core modlue. # To import a core module.
import lang import lang
# Import multiple modules. # Import multiple modules.
@ -16,7 +16,7 @@ import lang, math
# Import functions from a module. # Import functions from a module.
from lang import write, gc from lang import write, gc
# Using alias to bind with a differt name. # Using alias to bind with a different name.
import math as foo import math as foo
from lang import clock as bar from lang import clock as bar
@ -40,7 +40,7 @@ from '../baz.pk' import *
``` ```
If the local scripts have defined a module name, they'll imported and binded with it's module name if not they've imported with an alias. If the local script don't have a module name and imported without an alias, every symbols (global variables, and functions) will be imported and that's similer to import all statement. If the local scripts have defined a module name, they'll imported and bound with it's module name if not they've imported with an alias. If the local script don't have a module name and imported without an alias, every symbols (global variables, and functions) will be imported and that's similar to import all statement.
```ruby ```ruby
# 'foo.pk' isn't defined a module name. # 'foo.pk' isn't defined a module name.
@ -52,7 +52,7 @@ import 'foo.pk' as foo
foo.fn() foo.fn()
# 'bar.pk' is defined with a module name 'bar'. # 'bar.pk' is defined with a module name 'bar'.
# It'll imported and binded as variable bar. # It'll be imported and bound as variable bar.
import 'bar.pk' import 'bar.pk'
bar.fn() bar.fn()
@ -60,7 +60,7 @@ bar.fn()
## %% The module keyword. %% ## %% The module keyword. %%
We can define a name to a modlue with the `module` keyword. The name will become the namespace for that module's functions and global variables when importing it. We can define a name to a module with the `module` keyword. The name will become the namespace for that module's functions and global variables when importing it.
```ruby ```ruby

View File

@ -39,7 +39,7 @@
<div id="sidebar-wrapper"> <div id="sidebar-wrapper">
<div id="sidebar"> <div id="sidebar">
<!-- <img src=" $sttaicdir/ icon.png" style="width:120px"> --> <!-- <img src=" $sttaicdir/ icon.png" style="width:120px"> -->
{{ NAVIGAION }} {{ NAVIGATION }}
</div> </div>
</div> </div>

View File

@ -54,7 +54,7 @@ extern "C" {
#define PK_PUBLIC #define PK_PUBLIC
#endif #endif
// A convinent macro to define documentation of funcions. Use it to document // A convenient macro to define documentation of funcions. Use it to document
// your native functions. // your native functions.
// //
// PK_DOC( // PK_DOC(
@ -88,7 +88,7 @@ typedef struct PkHandle PkHandle;
// dangling once after the stack frame is popped. // dangling once after the stack frame is popped.
typedef void* PkVar; typedef void* PkVar;
// Type enum of the pocketlang varaibles, this can be used to get the type // Type enum of the pocketlang variables, this can be used to get the type
// from a Var* in the method pkGetVarType(). // from a Var* in the method pkGetVarType().
typedef enum { typedef enum {
PK_NULL, PK_NULL,
@ -131,7 +131,7 @@ typedef enum {
PK_RESULT_UNEXPECTED_EOF, PK_RESULT_UNEXPECTED_EOF,
PK_RESULT_COMPILE_ERROR, // Compilation failed. PK_RESULT_COMPILE_ERROR, // Compilation failed.
PK_RESULT_RUNTIME_ERROR, // An error occured at runtime. PK_RESULT_RUNTIME_ERROR, // An error occurred at runtime.
} PkResult; } PkResult;
/*****************************************************************************/ /*****************************************************************************/
@ -186,7 +186,7 @@ typedef PkStringPtr (*pkLoadScriptFn) (PKVM* vm, const char* path);
/* POCKETLANG PUBLIC API */ /* POCKETLANG PUBLIC API */
/*****************************************************************************/ /*****************************************************************************/
// Create a new pkConfiguraition with the default values and return it. // Create a new PkConfiguration with the default values and return it.
// Override those default configuration to adopt to another hosting // Override those default configuration to adopt to another hosting
// application. // application.
PK_PUBLIC PkConfiguration pkNewConfiguration(void); PK_PUBLIC PkConfiguration pkNewConfiguration(void);
@ -254,14 +254,14 @@ PK_PUBLIC PkResult pkInterpretSource(PKVM* vm,
// Runs the fiber's function with the provided arguments (param [arc] is the // Runs the fiber's function with the provided arguments (param [arc] is the
// argument count and [argv] are the values). It'll returns it's run status // argument count and [argv] are the values). It'll returns it's run status
// reslt (success or failure) if you need the yielded or returned value use the // result (success or failure) if you need the yielded or returned value use
// pkFiberGetReturnValue() function, and use pkFiberIsDone() function to check // the pkFiberGetReturnValue() function, and use pkFiberIsDone() function to
// if the fiber can be resumed with pkFiberResume() function. // check if the fiber can be resumed with pkFiberResume() function.
PK_PUBLIC PkResult pkRunFiber(PKVM* vm, PkHandle* fiber, PK_PUBLIC PkResult pkRunFiber(PKVM* vm, PkHandle* fiber,
int argc, PkHandle** argv); int argc, PkHandle** argv);
// Resume a yielded fiber with an optional [value]. (could be set to NULL) // Resume a yielded fiber with an optional [value]. (could be set to NULL)
// It'll returns it's run status reslt (success or failure) if you need the // It'll returns it's run status result (success or failure) if you need the
// yielded or returned value use the pkFiberGetReturnValue() function. // yielded or returned value use the pkFiberGetReturnValue() function.
PK_PUBLIC PkResult pkResumeFiber(PKVM* vm, PkHandle* fiber, PkVar value); PK_PUBLIC PkResult pkResumeFiber(PKVM* vm, PkHandle* fiber, PkVar value);
@ -311,7 +311,7 @@ struct PkCompileOptions {
//FILE* dump_stream; //FILE* dump_stream;
// Set to true if compiling in REPL mode, This will print repr version of // Set to true if compiling in REPL mode, This will print repr version of
// each evaluvated non-null values. Note that if [repl_mode] is true the // each evaluated non-null values. Note that if [repl_mode] is true the
// [expression] should also be true otherwise it's incompatible, (will fail // [expression] should also be true otherwise it's incompatible, (will fail
// an assertion). // an assertion).
bool repl_mode; bool repl_mode;
@ -345,7 +345,7 @@ PK_PUBLIC PkVar pkGetArg(const PKVM* vm, int arg);
// with the extracted value. Note that the arguments are 1 based (to get the // with the extracted value. Note that the arguments are 1 based (to get the
// first argument use 1 not 0). // first argument use 1 not 0).
PK_PUBLIC bool pkGetArgBool(PKVM* vm, int arg, bool* vlaue); PK_PUBLIC bool pkGetArgBool(PKVM* vm, int arg, bool* value);
PK_PUBLIC bool pkGetArgNumber(PKVM* vm, int arg, double* value); PK_PUBLIC bool pkGetArgNumber(PKVM* vm, int arg, double* value);
PK_PUBLIC bool pkGetArgString(PKVM* vm, int arg, const char** value); PK_PUBLIC bool pkGetArgString(PKVM* vm, int arg, const char** value);
PK_PUBLIC bool pkGetArgValue(PKVM* vm, int arg, PkVarType type, PkVar* value); PK_PUBLIC bool pkGetArgValue(PKVM* vm, int arg, PkVarType type, PkVar* value);

View File

@ -27,7 +27,7 @@
/* Initialize a new buffer int instance. */ \ /* Initialize a new buffer int instance. */ \
void pk##m_name##BufferInit(pk##m_name##Buffer* self); \ void pk##m_name##BufferInit(pk##m_name##Buffer* self); \
\ \
/* Clears the allocated elementes from the VM's realloc function. */ \ /* Clears the allocated elements from the VM's realloc function. */ \
void pk##m_name##BufferClear(pk##m_name##Buffer* self, PKVM* vm); \ void pk##m_name##BufferClear(pk##m_name##Buffer* self, PKVM* vm); \
\ \
/* Ensure the capacity is greater than [size], if not resize. */ \ /* Ensure the capacity is greater than [size], if not resize. */ \

View File

@ -42,7 +42,7 @@
#define VAR_NAN_TAGGING 1 #define VAR_NAN_TAGGING 1
// The maximum number of argument a pocketlang function supported to call. This // The maximum number of argument a pocketlang function supported to call. This
// value is arbitary and feel free to change it. (Just used this limit for an // value is arbitrary and feel free to change it. (Just used this limit for an
// internal buffer to store values before calling a new fiber). // internal buffer to store values before calling a new fiber).
#define MAX_ARGC 32 #define MAX_ARGC 32
@ -65,7 +65,7 @@
#define ALLOCATE_DYNAMIC(vm, type, count, tail_type) \ #define ALLOCATE_DYNAMIC(vm, type, count, tail_type) \
((type*)vmRealloc(vm, NULL, 0, sizeof(type) + sizeof(tail_type) * (count))) ((type*)vmRealloc(vm, NULL, 0, sizeof(type) + sizeof(tail_type) * (count)))
// Allocate [count] ammount of object of [type] array. // Allocate [count] amount of object of [type] array.
#define ALLOCATE_ARRAY(vm, type, count) \ #define ALLOCATE_ARRAY(vm, type, count) \
((type*)vmRealloc(vm, NULL, 0, sizeof(type) * (count))) ((type*)vmRealloc(vm, NULL, 0, sizeof(type) * (count)))
@ -81,13 +81,13 @@
//< TODO; macro use this to print a crash report. //< TODO; macro use this to print a crash report.
// This will terminate the compilation if the [condition] is false, because of // This will terminate the compilation if the [condition] is false, because of
// 1/0 evaluvated. Use this to check missing enums in switch, or check if an // 1/0 evaluated. Use this to check missing enums in switch, or check if an
// enum or macro has a specific value. (STATIC_ASSERT(ENUM_SUCCESS == 0)). // enum or macro has a specific value. (STATIC_ASSERT(ENUM_SUCCESS == 0)).
#define STATIC_ASSERT(condition) ( 1 / ((int)(condition)) ) #define STATIC_ASSERT(condition) ( 1 / ((int)(condition)) )
// The internal assertion macro, this will print error and break regardless of // The internal assertion macro, this will print error and break regardless of
// the build target (debug or release). Use ASSERT() for debug assertion and // the build target (debug or release). Use ASSERT() for debug assertion and
// use __ASSERT() for TODOs and assetions in public methods (to indicate that // use __ASSERT() for TODOs and assertions in public methods (to indicate that
// the host application did something wrong). // the host application did something wrong).
#define __ASSERT(condition, message) \ #define __ASSERT(condition, message) \
do { \ do { \

View File

@ -196,11 +196,11 @@ static _Keyword _keywords[] = {
{ "continue", 8, TK_CONTINUE }, { "continue", 8, TK_CONTINUE },
{ "return", 6, TK_RETURN }, { "return", 6, TK_RETURN },
{ NULL, 0, (TokenType)(0) }, // Sentinal to mark the end of the array { NULL, 0, (TokenType)(0) }, // Sentinel to mark the end of the array
}; };
/***************************************************************************** /*****************************************************************************
* COMPILIER INTERNAL TYPES * * COMPILER INTERNAL TYPES *
*****************************************************************************/ *****************************************************************************/
// Precedence parsing references: // Precedence parsing references:
@ -322,7 +322,7 @@ typedef struct sFunc {
} Func; } Func;
// A convinent macro to get the current function. // A convenient macro to get the current function.
#define _FN (compiler->func->ptr->fn) #define _FN (compiler->func->ptr->fn)
struct Compiler { struct Compiler {
@ -337,7 +337,7 @@ struct Compiler {
int current_line; //< Line number of the current char. int current_line; //< Line number of the current char.
Token previous, current, next; //< Currently parsed tokens. Token previous, current, next; //< Currently parsed tokens.
bool has_errors; //< True if any syntex error occured at. bool has_errors; //< True if any syntex error occurred at.
bool need_more_lines; //< True if we need more lines in REPL mode. bool need_more_lines; //< True if we need more lines in REPL mode.
const PkCompileOptions* options; //< To configure the compilation. const PkCompileOptions* options; //< To configure the compilation.
@ -361,7 +361,7 @@ struct Compiler {
int forwards_count; int forwards_count;
// True if the last statement is a new local variable assignment. Because // True if the last statement is a new local variable assignment. Because
// the assignment is different than reqular assignment and use this boolean // the assignment is different than regular assignment and use this boolean
// to tell the compiler that dont pop it's assigned value because the value // to tell the compiler that dont pop it's assigned value because the value
// itself is the local. // itself is the local.
bool new_local; bool new_local;
@ -370,7 +370,7 @@ struct Compiler {
// using the assignment operator ('='). ie. 'a = 42' here a is an "l-value" // using the assignment operator ('='). ie. 'a = 42' here a is an "l-value"
// and the 42 is a "r-value" so the assignment is consumed and compiled. // and the 42 is a "r-value" so the assignment is consumed and compiled.
// Consider '42 = a' where 42 is a "r-value" which cannot be assigned. // Consider '42 = a' where 42 is a "r-value" which cannot be assigned.
// Similerly 'a = 1 + b = 2' the expression '(1 + b)' is a "r value" and // Similarly 'a = 1 + b = 2' the expression '(1 + b)' is a "r value" and
// the assignment here is invalid, however 'a = 1 + (b = 2)' is valid because // the assignment here is invalid, however 'a = 1 + (b = 2)' is valid because
// the 'b' is an "l-value" and can be assigned but the '(b = 2)' is a // the 'b' is an "l-value" and can be assigned but the '(b = 2)' is a
// "r-value". // "r-value".
@ -411,7 +411,7 @@ static void reportError(Compiler* compiler, const char* file, int line,
compiler->has_errors = true; compiler->has_errors = true;
// If the source is incompilete we're not printing an error message, // If the source is incomplete we're not printing an error message,
// instead return PK_RESULT_UNEXPECTED_EOF to the host. // instead return PK_RESULT_UNEXPECTED_EOF to the host.
if (compiler->need_more_lines) { if (compiler->need_more_lines) {
ASSERT(compiler->options && compiler->options->repl_mode, OOPS); ASSERT(compiler->options && compiler->options->repl_mode, OOPS);
@ -457,8 +457,8 @@ static void parseError(Compiler* compiler, const char* fmt, ...) {
} }
// Error caused when trying to resolve forward names (maybe more in the // Error caused when trying to resolve forward names (maybe more in the
// furure), Which will be called once after compiling the script and thus we // future), Which will be called once after compiling the script and thus we
// need to pass the line number the error origined from. // need to pass the line number the error originated from.
static void resolveError(Compiler* compiler, int line, const char* fmt, ...) { static void resolveError(Compiler* compiler, int line, const char* fmt, ...) {
va_list args; va_list args;
va_start(args, fmt); va_start(args, fmt);
@ -772,7 +772,7 @@ static TokenType peek(Compiler* self) {
} }
// Consume the current token if it's expected and lex for the next token // Consume the current token if it's expected and lex for the next token
// and return true otherwise reutrn false. // and return true otherwise return false.
static bool match(Compiler* self, TokenType expected) { static bool match(Compiler* self, TokenType expected) {
if (peek(self) != expected) return false; if (peek(self) != expected) return false;
lexToken(self); lexToken(self);
@ -806,7 +806,7 @@ static bool matchLine(Compiler* compiler) {
consumed = true; consumed = true;
} }
// If we're running on REPL mode, at the EOF and compile time error occured, // If we're running on REPL mode, at the EOF and compile time error occurred,
// signal the host to get more lines and try re-compiling it. // signal the host to get more lines and try re-compiling it.
if (compiler->options && compiler->options->repl_mode && if (compiler->options && compiler->options->repl_mode &&
!compiler->has_errors) { !compiler->has_errors) {
@ -833,7 +833,7 @@ static bool matchEndStatement(Compiler* compiler) {
if (matchLine(compiler) || peek(compiler) == TK_EOF) if (matchLine(compiler) || peek(compiler) == TK_EOF)
return true; return true;
// In the below statement we don't require any new lines or semicollons. // In the below statement we don't require any new lines or semicolons.
// 'if cond then stmnt1 elif cond2 then stmnt2 else stmnt3 end' // 'if cond then stmnt1 elif cond2 then stmnt2 else stmnt3 end'
if (peek(compiler) == TK_END || peek(compiler) == TK_ELSE || if (peek(compiler) == TK_END || peek(compiler) == TK_ELSE ||
peek(compiler) == TK_ELIF) peek(compiler) == TK_ELIF)
@ -1160,8 +1160,8 @@ static void exprName(Compiler* compiler) {
emitStoreVariable(compiler, index, true); emitStoreVariable(compiler, index, true);
} else { } else {
// This will prevent the assignment from poped out from the stack // This will prevent the assignment from being popped out from the
// since the assigned value itself is the local and not a temp. // stack since the assigned value itself is the local and not a temp.
compiler->new_local = true; compiler->new_local = true;
emitStoreVariable(compiler, index, false); emitStoreVariable(compiler, index, false);
} }
@ -1296,7 +1296,7 @@ static void exprChainCall(Compiler* compiler) {
} }
} }
// TOOD: ensure argc < 256 (MAX_ARGC) 1byte. // TODO: ensure argc < 256 (MAX_ARGC) 1byte.
emitOpcode(compiler, OP_CALL); emitOpcode(compiler, OP_CALL);
emitByte(compiler, argc); emitByte(compiler, argc);
@ -1607,7 +1607,7 @@ static int compilerAddVariable(Compiler* compiler, const char* name,
static void compilerAddForward(Compiler* compiler, int instruction, Fn* fn, static void compilerAddForward(Compiler* compiler, int instruction, Fn* fn,
const char* name, int length, int line) { const char* name, int length, int line) {
if (compiler->forwards_count == MAX_FORWARD_NAMES) { if (compiler->forwards_count == MAX_FORWARD_NAMES) {
parseError(compiler, "A script should contain at most %d implict forward " parseError(compiler, "A script should contain at most %d implicit forward "
"function declarations.", MAX_FORWARD_NAMES); "function declarations.", MAX_FORWARD_NAMES);
return; return;
} }
@ -2068,7 +2068,7 @@ static void compilerImportAll(Compiler* compiler, Script* script) {
ASSERT(script != NULL, OOPS); ASSERT(script != NULL, OOPS);
ASSERT(compiler->scope_depth == DEPTH_GLOBAL, OOPS); ASSERT(compiler->scope_depth == DEPTH_GLOBAL, OOPS);
// Line number of the variables which will be bind to the imported sybmol. // Line number of the variables which will be bind to the imported symbol.
int line = compiler->previous.line; int line = compiler->previous.line;
// TODO: Refactor this to a loop rather than jumping with goto. // TODO: Refactor this to a loop rather than jumping with goto.
@ -2219,12 +2219,12 @@ static void compileRegularImport(Compiler* compiler) {
// If it has a module name use it as binding variable. // If it has a module name use it as binding variable.
// Core libs names are it's module name but for local libs it's optional // Core libs names are it's module name but for local libs it's optional
// to define a module name for a script. // to define a module name for a script.
if (lib && lib->moudle != NULL) { if (lib && lib->module != NULL) {
// Get the variable to bind the imported symbol, if we already have a // Get the variable to bind the imported symbol, if we already have a
// variable with that name override it, otherwise use a new variable. // variable with that name override it, otherwise use a new variable.
const char* name = lib->moudle->data; const char* name = lib->module->data;
uint32_t length = lib->moudle->length; uint32_t length = lib->module->length;
int line = compiler->previous.line; int line = compiler->previous.line;
var_index = compilerImportName(compiler, line, name, length); var_index = compilerImportName(compiler, line, name, length);
@ -2470,7 +2470,7 @@ static void compileStatement(Compiler* compiler) {
compiler->new_local = false; compiler->new_local = false;
} }
// If running REPL mode, print the expression's evaluvated value. Only if // If running REPL mode, print the expression's evaluated value. Only if
// we're at the top level. Python does print local depth expression too. // we're at the top level. Python does print local depth expression too.
// (it's just a design decision). // (it's just a design decision).
if (compiler->options && compiler->options->repl_mode && if (compiler->options && compiler->options->repl_mode &&
@ -2484,7 +2484,7 @@ static void compileStatement(Compiler* compiler) {
// Compile statements that are only valid at the top level of the script. Such // Compile statements that are only valid at the top level of the script. Such
// as import statement, function define, and if we're running REPL mode top // as import statement, function define, and if we're running REPL mode top
// level expression's evaluvated value will be printed. // level expression's evaluated value will be printed.
static void compileTopLevelStatement(Compiler* compiler) { static void compileTopLevelStatement(Compiler* compiler) {
if (match(compiler, TK_NATIVE)) { if (match(compiler, TK_NATIVE)) {
compileFunction(compiler, FN_NATIVE); compileFunction(compiler, FN_NATIVE);
@ -2524,7 +2524,7 @@ PkResult compile(PKVM* vm, Script* script, const char* source,
vm->compiler = compiler; vm->compiler = compiler;
// If we're compiling for a script that was already compiled (when running // If we're compiling for a script that was already compiled (when running
// REPL or evaluvating an expression) we don't need the old main anymore. // REPL or evaluating an expression) we don't need the old main anymore.
// just use the globals and functions of the script and use a new body func. // just use the globals and functions of the script and use a new body func.
ASSERT(script->body != NULL, OOPS); ASSERT(script->body != NULL, OOPS);
pkByteBufferClear(&script->body->fn->opcodes, vm); pkByteBufferClear(&script->body->fn->opcodes, vm);
@ -2550,14 +2550,14 @@ PkResult compile(PKVM* vm, Script* script, const char* source,
// If the script running a REPL or compiled multiple times by hosting // If the script running a REPL or compiled multiple times by hosting
// application module attribute might already set. In that case make it // application module attribute might already set. In that case make it
// Compile error. // Compile error.
if (script->moudle != NULL) { if (script->module != NULL) {
parseError(compiler, "Module name already defined."); parseError(compiler, "Module name already defined.");
} else { } else {
consume(compiler, TK_NAME, "Expected a name for the module."); consume(compiler, TK_NAME, "Expected a name for the module.");
const char* name = compiler->previous.start; const char* name = compiler->previous.start;
uint32_t len = compiler->previous.length; uint32_t len = compiler->previous.length;
script->moudle = newStringLength(vm, name, len); script->module = newStringLength(vm, name, len);
consumeEndStatement(compiler); consumeEndStatement(compiler);
} }
} }

View File

@ -33,7 +33,7 @@ typedef struct Compiler Compiler;
PkResult compile(PKVM* vm, Script* script, const char* source, PkResult compile(PKVM* vm, Script* script, const char* source,
const PkCompileOptions* options); const PkCompileOptions* options);
// Mark the heap allocated ojbects of the compiler at the garbage collection // Mark the heap allocated objects of the compiler at the garbage collection
// called at the marking phase of vmCollectGarbage(). // called at the marking phase of vmCollectGarbage().
void compilerMarkObjects(PKVM* vm, Compiler* compiler); void compilerMarkObjects(PKVM* vm, Compiler* compiler);

View File

@ -377,7 +377,7 @@ Script* getCoreLib(const PKVM* vm, String* name) {
/* CORE BUILTIN FUNCTIONS */ /* CORE BUILTIN FUNCTIONS */
/*****************************************************************************/ /*****************************************************************************/
#define FN_IS_PRIMITE_TYPE(name, check) \ #define FN_IS_PRIMITIVE_TYPE(name, check) \
static void coreIs##name(PKVM* vm) { \ static void coreIs##name(PKVM* vm) { \
RET(VAR_BOOL(check(ARG(1)))); \ RET(VAR_BOOL(check(ARG(1)))); \
} }
@ -392,9 +392,9 @@ Script* getCoreLib(const PKVM* vm, String* name) {
} \ } \
} }
FN_IS_PRIMITE_TYPE(Null, IS_NULL) FN_IS_PRIMITIVE_TYPE(Null, IS_NULL)
FN_IS_PRIMITE_TYPE(Bool, IS_BOOL) FN_IS_PRIMITIVE_TYPE(Bool, IS_BOOL)
FN_IS_PRIMITE_TYPE(Num, IS_NUM) FN_IS_PRIMITIVE_TYPE(Num, IS_NUM)
FN_IS_OBJ_TYPE(String, OBJ_STRING) FN_IS_OBJ_TYPE(String, OBJ_STRING)
FN_IS_OBJ_TYPE(List, OBJ_LIST) FN_IS_OBJ_TYPE(List, OBJ_LIST)
@ -509,7 +509,7 @@ PK_DOC(
"Write each argument as comma seperated to the stdout and ends with a " "Write each argument as comma seperated to the stdout and ends with a "
"newline.", "newline.",
static void corePrint(PKVM* vm)) { static void corePrint(PKVM* vm)) {
// If the host appliaction donesn't provide any write function, discard the // If the host application doesn't provide any write function, discard the
// output. // output.
if (vm->config.write_fn == NULL) return; if (vm->config.write_fn == NULL) return;
@ -531,7 +531,7 @@ static void coreInput(PKVM* vm)) {
RET_ERR(newString(vm, "Invalid argument count.")); RET_ERR(newString(vm, "Invalid argument count."));
} }
// If the host appliaction donesn't provide any write function, return. // If the host application doesn't provide any write function, return.
if (vm->config.read_fn == NULL) return; if (vm->config.read_fn == NULL) return;
if (argc == 1) { if (argc == 1) {
@ -620,7 +620,7 @@ static void coreFiberNew(PKVM* vm)) {
PK_DOC( PK_DOC(
"fiber_get_func(fb:Fiber) -> function\n" "fiber_get_func(fb:Fiber) -> function\n"
"Retruns the fiber's functions. Which is usefull if you wan't to re-run the " "Retruns the fiber's functions. Which is usefull if you want to re-run the "
"fiber, you can get the function and crate a new fiber.", "fiber, you can get the function and crate a new fiber.",
static void coreFiberGetFunc(PKVM* vm)) { static void coreFiberGetFunc(PKVM* vm)) {
Fiber* fb; Fiber* fb;
@ -709,7 +709,7 @@ static Script* newModuleInternal(PKVM* vm, const char* name) {
} }
Script* scr = newScript(vm, _name); Script* scr = newScript(vm, _name);
scr->moudle = _name; scr->module = _name;
vmPopTempRef(vm); // _name vmPopTempRef(vm); // _name
// Add the script to core_libs. // Add the script to core_libs.
@ -727,13 +727,13 @@ static inline void assertModuleNameDef(PKVM* vm, Script* script,
// Check if function with the same name already exists. // Check if function with the same name already exists.
if (scriptGetFunc(script, name, (uint32_t)strlen(name)) != -1) { if (scriptGetFunc(script, name, (uint32_t)strlen(name)) != -1) {
__ASSERT(false, stringFormat(vm, "A function named '$' already esists " __ASSERT(false, stringFormat(vm, "A function named '$' already esists "
"on module '@'", name, script->moudle)->data); "on module '@'", name, script->module)->data);
} }
// Check if a global variable with the same name already exists. // Check if a global variable with the same name already exists.
if (scriptGetGlobals(script, name, (uint32_t)strlen(name)) != -1) { if (scriptGetGlobals(script, name, (uint32_t)strlen(name)) != -1) {
__ASSERT(false, stringFormat(vm, "A global variable named '$' already " __ASSERT(false, stringFormat(vm, "A global variable named '$' already "
"esists on module '@'", name, script->moudle)->data); "esists on module '@'", name, script->module)->data);
} }
} }
@ -775,7 +775,7 @@ void stdLangClock(PKVM* vm) {
RET(VAR_NUM((double)clock() / CLOCKS_PER_SEC)); RET(VAR_NUM((double)clock() / CLOCKS_PER_SEC));
} }
// Trigger garbage collection and return the ammount of bytes cleaned. // Trigger garbage collection and return the amount of bytes cleaned.
void stdLangGC(PKVM* vm) { void stdLangGC(PKVM* vm) {
size_t bytes_before = vm->bytes_allocated; size_t bytes_before = vm->bytes_allocated;
vmCollectGarbage(vm); vmCollectGarbage(vm);
@ -807,7 +807,7 @@ void stdLangDebugBreak(PKVM* vm) {
// Write function, just like print function but it wont put space between args // Write function, just like print function but it wont put space between args
// and write a new line at the end. // and write a new line at the end.
void stdLangWrite(PKVM* vm) { void stdLangWrite(PKVM* vm) {
// If the host appliaction donesn't provide any write function, discard the // If the host application doesn't provide any write function, discard the
// output. // output.
if (vm->config.write_fn == NULL) return; if (vm->config.write_fn == NULL) return;
@ -933,54 +933,54 @@ static void initializeBuiltinFN(PKVM* vm, BuiltinFn* bfn, const char* name,
void initializeCore(PKVM* vm) { void initializeCore(PKVM* vm) {
#define INITALIZE_BUILTIN_FN(name, fn, argc) \ #define INITIALIZE_BUILTIN_FN(name, fn, argc) \
initializeBuiltinFN(vm, &vm->builtins[vm->builtins_count++], name, \ initializeBuiltinFN(vm, &vm->builtins[vm->builtins_count++], name, \
(int)strlen(name), argc, fn); (int)strlen(name), argc, fn);
// Initialize builtin functions. // Initialize builtin functions.
INITALIZE_BUILTIN_FN("type_name", coreTypeName, 1); INITIALIZE_BUILTIN_FN("type_name", coreTypeName, 1);
// TOOD: (maybe remove is_*() functions) suspend by type_name. // TODO: (maybe remove is_*() functions) suspend by type_name.
// and add is keyword with modules for builtin types // and add is keyword with modules for builtin types
// ex: val is Num; val is null; val is List; val is Range // ex: val is Num; val is null; val is List; val is Range
// List.append(l, e) # List is implicitly imported core module. // List.append(l, e) # List is implicitly imported core module.
// String.lower(s) // String.lower(s)
INITALIZE_BUILTIN_FN("is_null", coreIsNull, 1); INITIALIZE_BUILTIN_FN("is_null", coreIsNull, 1);
INITALIZE_BUILTIN_FN("is_bool", coreIsBool, 1); INITIALIZE_BUILTIN_FN("is_bool", coreIsBool, 1);
INITALIZE_BUILTIN_FN("is_num", coreIsNum, 1); INITIALIZE_BUILTIN_FN("is_num", coreIsNum, 1);
INITALIZE_BUILTIN_FN("is_string", coreIsString, 1); INITIALIZE_BUILTIN_FN("is_string", coreIsString, 1);
INITALIZE_BUILTIN_FN("is_list", coreIsList, 1); INITIALIZE_BUILTIN_FN("is_list", coreIsList, 1);
INITALIZE_BUILTIN_FN("is_map", coreIsMap, 1); INITIALIZE_BUILTIN_FN("is_map", coreIsMap, 1);
INITALIZE_BUILTIN_FN("is_range", coreIsRange, 1); INITIALIZE_BUILTIN_FN("is_range", coreIsRange, 1);
INITALIZE_BUILTIN_FN("is_function", coreIsFunction, 1); INITIALIZE_BUILTIN_FN("is_function", coreIsFunction, 1);
INITALIZE_BUILTIN_FN("is_script", coreIsScript, 1); INITIALIZE_BUILTIN_FN("is_script", coreIsScript, 1);
INITALIZE_BUILTIN_FN("is_userobj", coreIsUserObj, 1); INITIALIZE_BUILTIN_FN("is_userobj", coreIsUserObj, 1);
INITALIZE_BUILTIN_FN("hex", coreHex, 1); INITIALIZE_BUILTIN_FN("hex", coreHex, 1);
INITALIZE_BUILTIN_FN("assert", coreAssert, -1); INITIALIZE_BUILTIN_FN("assert", coreAssert, -1);
INITALIZE_BUILTIN_FN("yield", coreYield, -1); INITIALIZE_BUILTIN_FN("yield", coreYield, -1);
INITALIZE_BUILTIN_FN("to_string", coreToString, 1); INITIALIZE_BUILTIN_FN("to_string", coreToString, 1);
INITALIZE_BUILTIN_FN("print", corePrint, -1); INITIALIZE_BUILTIN_FN("print", corePrint, -1);
INITALIZE_BUILTIN_FN("input", coreInput, -1); INITIALIZE_BUILTIN_FN("input", coreInput, -1);
// String functions. // String functions.
INITALIZE_BUILTIN_FN("str_chr", coreStrChr, 1); INITIALIZE_BUILTIN_FN("str_chr", coreStrChr, 1);
INITALIZE_BUILTIN_FN("str_ord", coreStrOrd, 1); INITIALIZE_BUILTIN_FN("str_ord", coreStrOrd, 1);
// List functions. // List functions.
INITALIZE_BUILTIN_FN("list_append", coreListAppend, 2); INITIALIZE_BUILTIN_FN("list_append", coreListAppend, 2);
// Map functions. // Map functions.
INITALIZE_BUILTIN_FN("map_remove", coreMapRemove, 2); INITIALIZE_BUILTIN_FN("map_remove", coreMapRemove, 2);
// Fiber functions. // Fiber functions.
INITALIZE_BUILTIN_FN("fiber_new", coreFiberNew, 1); INITIALIZE_BUILTIN_FN("fiber_new", coreFiberNew, 1);
INITALIZE_BUILTIN_FN("fiber_get_func", coreFiberGetFunc, 1); INITIALIZE_BUILTIN_FN("fiber_get_func", coreFiberGetFunc, 1);
INITALIZE_BUILTIN_FN("fiber_run", coreFiberRun, -1); INITIALIZE_BUILTIN_FN("fiber_run", coreFiberRun, -1);
INITALIZE_BUILTIN_FN("fiber_is_done", coreFiberIsDone, 1); INITIALIZE_BUILTIN_FN("fiber_is_done", coreFiberIsDone, 1);
INITALIZE_BUILTIN_FN("fiber_resume", coreFiberResume, -1); INITIALIZE_BUILTIN_FN("fiber_resume", coreFiberResume, -1);
// Core Modules ///////////////////////////////////////////////////////////// // Core Modules /////////////////////////////////////////////////////////////

View File

@ -48,7 +48,7 @@ OPCODE(LIST_APPEND, 0, -1)
OPCODE(MAP_INSERT, 0, -2) OPCODE(MAP_INSERT, 0, -2)
// Push stack local on top of the stack. Locals at 0 to 8 marked explicitly // Push stack local on top of the stack. Locals at 0 to 8 marked explicitly
// since it's performance criticle. // since it's performance critical.
// params: PUSH_LOCAL_N -> 1 byte count value. // params: PUSH_LOCAL_N -> 1 byte count value.
OPCODE(PUSH_LOCAL_0, 0, 1) OPCODE(PUSH_LOCAL_0, 0, 1)
OPCODE(PUSH_LOCAL_1, 0, 1) OPCODE(PUSH_LOCAL_1, 0, 1)

View File

@ -52,7 +52,7 @@ uint32_t utilHashString(const char* string);
* don't know about ASCII encoding it's just how a character is represented in * don't know about ASCII encoding it's just how a character is represented in
* a single byte. For an example the character 'A' is 01000001, 'B' is 01000010 * a single byte. For an example the character 'A' is 01000001, 'B' is 01000010
* and so on. The first bit in is always 0 called parity bit, it's a way to * and so on. The first bit in is always 0 called parity bit, it's a way to
* check if some of the bits have flipped by noice back in the old age of * check if some of the bits have flipped by noise back in the old age of
* computers. Parity bit should be equal to the sum of the rest of the bits mod * computers. Parity bit should be equal to the sum of the rest of the bits mod
* 2. So we have 7 bits to represent ASCII which is 127 different characters. * 2. So we have 7 bits to represent ASCII which is 127 different characters.
* But utf-8 can potentially encode 2,164,864 characters. * But utf-8 can potentially encode 2,164,864 characters.
@ -76,7 +76,7 @@ uint32_t utilHashString(const char* string);
* </pre> * </pre>
* *
* USAGE: * USAGE:
* // define imlpementation only a single *.c source file like this * // define implementation only a single *.c source file like this
* #define UTF8_IMPLEMENT * #define UTF8_IMPLEMENT
* #include "utf8.h" * #include "utf8.h"
*/ */

View File

@ -176,7 +176,7 @@ static void _blackenObject(Object* obj, PKVM* vm) {
vm->bytes_allocated += sizeof(Script); vm->bytes_allocated += sizeof(Script);
grayObject(vm, &scr->path->_super); grayObject(vm, &scr->path->_super);
grayObject(vm, &scr->moudle->_super); grayObject(vm, &scr->module->_super);
grayVarBuffer(vm, &scr->globals); grayVarBuffer(vm, &scr->globals);
vm->bytes_allocated += sizeof(Var) * scr->globals.capacity; vm->bytes_allocated += sizeof(Var) * scr->globals.capacity;
@ -324,7 +324,7 @@ Script* newScript(PKVM* vm, String* path) {
varInitObject(&script->_super, vm, OBJ_SCRIPT); varInitObject(&script->_super, vm, OBJ_SCRIPT);
script->path = path; script->path = path;
script->moudle = NULL; script->module = NULL;
script->initialized = false; script->initialized = false;
pkVarBufferInit(&script->globals); pkVarBufferInit(&script->globals);
@ -420,7 +420,7 @@ Fiber* newFiber(PKVM* vm, Function* fn) {
} }
// Initialize the return value to null (doesn't really have to do that here // Initialize the return value to null (doesn't really have to do that here
// but if we're trying to debut it may crash when dumping the return vaue). // but if we're trying to debut it may crash when dumping the return value).
*fiber->ret = VAR_NULL; *fiber->ret = VAR_NULL;
return fiber; return fiber;
@ -494,7 +494,7 @@ String* stringStrip(PKVM* vm, String* self) {
// //
// These 'start' and 'end' pointers will move respectively right and left // These 'start' and 'end' pointers will move respectively right and left
// while it's a white space and return an allocated string from 'start' with // while it's a white space and return an allocated string from 'start' with
// length of (end - start + 1). For already trimed string it'll not allocate // length of (end - start + 1). For already trimmed string it'll not allocate
// a new string, instead returns the same string provided. // a new string, instead returns the same string provided.
const char* start = self->data; const char* start = self->data;
@ -509,7 +509,7 @@ String* stringStrip(PKVM* vm, String* self) {
const char* end = self->data + self->length - 1; const char* end = self->data + self->length - 1;
while (isspace(*end)) end--; while (isspace(*end)) end--;
// If the string is already trimed, return the same string. // If the string is already trimmed, return the same string.
if (start == self->data && end == self->data + self->length - 1) { if (start == self->data && end == self->data + self->length - 1) {
return self; return self;
} }
@ -611,7 +611,7 @@ static bool _mapFindEntry(Map* self, Var key, MapEntry** result) {
if (self->capacity == 0) return false; if (self->capacity == 0) return false;
// The [start_index] is where the entry supposed to be if there wasn't any // The [start_index] is where the entry supposed to be if there wasn't any
// collision occured. It'll be the start index for the linear probing. // collision occurred. It'll be the start index for the linear probing.
uint32_t start_index = varHashValue(key) % self->capacity; uint32_t start_index = varHashValue(key) % self->capacity;
uint32_t index = start_index; uint32_t index = start_index;
@ -659,7 +659,7 @@ static bool _mapFindEntry(Map* self, Var key, MapEntry** result) {
} }
// Add the key, value pair to the entries array of the map. Returns true if // Add the key, value pair to the entries array of the map. Returns true if
// the entry added for the first time and false for replaced vlaue. // the entry added for the first time and false for replaced value.
static bool _mapInsertEntry(Map* self, Var key, Var value) { static bool _mapInsertEntry(Map* self, Var key, Var value) {
ASSERT(self->capacity != 0, "Should ensure the capacity before inserting."); ASSERT(self->capacity != 0, "Should ensure the capacity before inserting.");
@ -773,11 +773,11 @@ bool fiberHasError(Fiber* fiber) {
void freeObject(PKVM* vm, Object* self) { void freeObject(PKVM* vm, Object* self) {
// TODO: Debug trace memory here. // TODO: Debug trace memory here.
// First clean the object's referencs, but we're not recursively doallocating // First clean the object's references, but we're not recursively
// them because they're not marked and will be cleaned later. // deallocating them because they're not marked and will be cleaned later.
// Example: List's `elements` is VarBuffer that contain a heap allocated // Example: List's `elements` is VarBuffer that contain a heap allocated
// array of `var*` which will be cleaned below but the actual `var` elements // array of `var*` which will be cleaned below but the actual `var` elements
// will won't be freed here instead they havent marked at all, and will be // will won't be freed here instead they haven't marked at all, and will be
// removed at the sweeping phase of the garbage collection. // removed at the sweeping phase of the garbage collection.
switch (self->type) { switch (self->type) {
case OBJ_STRING: case OBJ_STRING:
@ -1111,9 +1111,9 @@ static void _toStringInternal(PKVM* vm, const Var v, pkByteBuffer* buff,
case OBJ_SCRIPT: { case OBJ_SCRIPT: {
const Script* scr = (const Script*)obj; const Script* scr = (const Script*)obj;
pkByteBufferAddString(buff, vm, "[Module:", 8); pkByteBufferAddString(buff, vm, "[Module:", 8);
if (scr->moudle != NULL) { if (scr->module != NULL) {
pkByteBufferAddString(buff, vm, scr->moudle->data, pkByteBufferAddString(buff, vm, scr->module->data,
scr->moudle->length); scr->module->length);
} else { } else {
pkByteBufferWrite(buff, vm, '"'); pkByteBufferWrite(buff, vm, '"');
pkByteBufferAddString(buff, vm, scr->path->data, scr->path->length); pkByteBufferAddString(buff, vm, scr->path->data, scr->path->length);

View File

@ -12,8 +12,8 @@
/** @file /** @file
* A simple dynamic type system library for small dynamic typed languages using * A simple dynamic type system library for small dynamic typed languages using
* a technique called NaN-tagging (optional). The method is inspired from the * a technique called NaN-tagging (optional). The method is inspired from the
* wren (https://wren.io/) an awsome language written by Bob Nystrom the author * wren (https://wren.io/) an awesome language written by Bob Nystrom the
* of "Crafting Interpreters" and it's contrbuters. * author of "Crafting Interpreters" and it's contrbuters.
* Reference: * Reference:
* https://github.com/wren-lang/wren/blob/main/src/vm/wren_value.h * https://github.com/wren-lang/wren/blob/main/src/vm/wren_value.h
* https://leonardschuetz.ch/blog/nan-boxing/ * https://leonardschuetz.ch/blog/nan-boxing/
@ -58,16 +58,16 @@
* -11111111111---------------------------------------------------- * -11111111111----------------------------------------------------
* *
* We define a our variant \ref var as an unsigned 64 bit integer (we treat it * We define a our variant \ref var as an unsigned 64 bit integer (we treat it
* like a bit array) if the exponent bits were not set, just reinterprit it as * like a bit array) if the exponent bits were not set, just reinterpret it as
* a IEEE 754 double precision 64 bit number. Other wise we there are a lot of * a IEEE 754 double precision 64 bit number. Other wise we there are a lot of
* different combination of bits we can use for our custom tagging, this method * different combination of bits we can use for our custom tagging, this method
* is called NaN-Tagging. * is called NaN-Tagging.
* *
* There are two kinds of NaN values "signalling" and "quiet". The first one is * There are two kinds of NaN values "signalling" and "quiet". The first one is
* intended to halt the execution but the second one is to continue the * intended to halt the execution but the second one is to continue the
* execution quietly. We get the quiet NaN by setting the highest mentissa bit. * execution quietly. We get the quiet NaN by setting the highest mantissa bit.
* *
* v~Highest mestissa bit * v~Highest mantissa bit
* -[NaN ]1--------------------------------------------------- * -[NaN ]1---------------------------------------------------
* *
* if sign bit set, it's a heap allocated pointer. * if sign bit set, it's a heap allocated pointer.
@ -160,7 +160,7 @@ typedef enum {
VAR_UNDEFINED, //< Internal type for exceptions. VAR_UNDEFINED, //< Internal type for exceptions.
VAR_NULL, //< Null pointer type. VAR_NULL, //< Null pointer type.
VAR_BOOL, //< Yin and yang of software. VAR_BOOL, //< Yin and yang of software.
VAR_INT, //< Only 32bit integers (to consistance with Nan-Tagging). VAR_INT, //< Only 32bit integers (for consistence with Nan-Tagging).
VAR_FLOAT, //< Floats are stored as (64bit) double. VAR_FLOAT, //< Floats are stored as (64bit) double.
VAR_OBJECT, //< Base type for all \ref var_Object types. VAR_OBJECT, //< Base type for all \ref var_Object types.
@ -239,7 +239,7 @@ struct List {
typedef struct { typedef struct {
// If the key is VAR_UNDEFINED it's an empty slot and if the value is false // If the key is VAR_UNDEFINED it's an empty slot and if the value is false
// the entry is new and available, if true it's a tumbstone - the entry // the entry is new and available, if true it's a tombstone - the entry
// previously used but then deleted. // previously used but then deleted.
Var key; //< The entry's key or VAR_UNDEFINED of the entry is not in use. Var key; //< The entry's key or VAR_UNDEFINED of the entry is not in use.
@ -266,7 +266,7 @@ struct Script {
// For core libraries the module and the path are same and points to the // For core libraries the module and the path are same and points to the
// same String objects. // same String objects.
String* moudle; //< Module name of the script. String* module; //< Module name of the script.
String* path; //< Path of the script. String* path; //< Path of the script.
/* /*
@ -384,7 +384,7 @@ String* newStringLength(PKVM* vm, const char* text, uint32_t length);
uint32_t length = (text == NULL) ? 0 : (uint32_t)strlen(text); uint32_t length = (text == NULL) ? 0 : (uint32_t)strlen(text);
return newStringLength(vm, text, length); return newStringLength(vm, text, length);
} }
#else // Macro implementaion. #else // Macro implementation.
// Allocate new string using the cstring [text]. // Allocate new string using the cstring [text].
#define newString(vm, text) \ #define newString(vm, text) \
newStringLength(vm, text, (text == NULL) ? 0 : (uint32_t)strlen(text)) newStringLength(vm, text, (text == NULL) ? 0 : (uint32_t)strlen(text))
@ -424,15 +424,15 @@ void grayObject(PKVM* vm, Object* self);
// collection. // collection.
void grayValue(PKVM* vm, Var self); void grayValue(PKVM* vm, Var self);
// Mark the elements of the buffer as reachable at the mark-and-sweep pahse of // Mark the elements of the buffer as reachable at the mark-and-sweep phase of
// the garbage collection. // the garbage collection.
void grayVarBuffer(PKVM* vm, pkVarBuffer* self); void grayVarBuffer(PKVM* vm, pkVarBuffer* self);
// Mark the elements of the buffer as reachable at the mark-and-sweep pahse of // Mark the elements of the buffer as reachable at the mark-and-sweep phase of
// the garbage collection. // the garbage collection.
void grayStringBuffer(PKVM* vm, pkStringBuffer* self); void grayStringBuffer(PKVM* vm, pkStringBuffer* self);
// Mark the elements of the buffer as reachable at the mark-and-sweep pahse of // Mark the elements of the buffer as reachable at the mark-and-sweep phase of
// the garbage collection. // the garbage collection.
void grayFunctionBuffer(PKVM* vm, pkFunctionBuffer* self); void grayFunctionBuffer(PKVM* vm, pkFunctionBuffer* self);
@ -453,8 +453,8 @@ String* stringLower(PKVM* vm, String* self);
// already upper it'll return the same string. // already upper it'll return the same string.
String* stringUpper(PKVM* vm, String* self); String* stringUpper(PKVM* vm, String* self);
// Returns string with the leading and trailing white spaces are trimed. // Returns string with the leading and trailing white spaces are trimmed.
// If the string is already trimed it'll return the same string. // If the string is already trimmed it'll return the same string.
String* stringStrip(PKVM* vm, String* self); String* stringStrip(PKVM* vm, String* self);
// An inline function/macro implementation of listAppend(). Set below 0 to 1, // An inline function/macro implementation of listAppend(). Set below 0 to 1,
@ -476,7 +476,7 @@ void listInsert(PKVM* vm, List* self, uint32_t index, Var value);
// Remove and return element at [index]. // Remove and return element at [index].
Var listRemoveAt(PKVM* vm, List* self, uint32_t index); Var listRemoveAt(PKVM* vm, List* self, uint32_t index);
// Returns the value for the [key] in the mape. If key not exists return // Returns the value for the [key] in the map. If key not exists return
// VAR_UNDEFINED. // VAR_UNDEFINED.
Var mapGet(Map* self, Var key); Var mapGet(Map* self, Var key);
@ -522,7 +522,7 @@ bool isValuesSame(Var v1, Var v2);
// Returns true if both variables are equal (ie v1 == v2). // Returns true if both variables are equal (ie v1 == v2).
bool isValuesEqual(Var v1, Var v2); bool isValuesEqual(Var v1, Var v2);
// Return the hash valur of the variable. (variable should be hashable). // Return the hash value of the variable. (variable should be hashable).
uint32_t varHashValue(Var v); uint32_t varHashValue(Var v);
// Return true if the object type is hashable. // Return true if the object type is hashable.
@ -531,14 +531,14 @@ bool isObjectHashable(ObjectType type);
// Returns the string version of the [value]. // Returns the string version of the [value].
String* toString(PKVM* vm, const Var value); String* toString(PKVM* vm, const Var value);
// Returns the representation version of the [value], similer of python's // Returns the representation version of the [value], similar to python's
// __repr__() method. // __repr__() method.
String * toRepr(PKVM * vm, const Var value); String * toRepr(PKVM * vm, const Var value);
// Returns the truthy value of the var. // Returns the truthy value of the var.
bool toBool(Var v); bool toBool(Var v);
// Creates a new string from the arguments. This is intented to used internal // Creates a new string from the arguments. This is intended for internal
// usage and it has 2 formated characters (just like wren does). // usage and it has 2 formated characters (just like wren does).
// $ - a C string // $ - a C string
// @ - a String object // @ - a String object

View File

@ -321,7 +321,7 @@ bool vmPrepareFiber(PKVM* vm, Fiber* fiber, int argc, Var** argv) {
if (argc != fiber->func->arity) { if (argc != fiber->func->arity) {
char buff[STR_INT_BUFF_SIZE]; sprintf(buff, "%d", fiber->func->arity); char buff[STR_INT_BUFF_SIZE]; sprintf(buff, "%d", fiber->func->arity);
_ERR_FAIL(stringFormat(vm, "Expected excatly $ argument(s).", buff)); _ERR_FAIL(stringFormat(vm, "Expected exactly $ argument(s).", buff));
} }
if (fiber->state != FIBER_NEW) { if (fiber->state != FIBER_NEW) {
@ -344,7 +344,7 @@ bool vmPrepareFiber(PKVM* vm, Fiber* fiber, int argc, Var** argv) {
// Pass the function arguments. // Pass the function arguments.
// Assert we have the first frame (to push the arguments). And assert we have // Assert we have the first frame (to push the arguments). And assert we have
// enought stack space for parameters. // enough stack space for parameters.
ASSERT(fiber->frame_count == 1, OOPS); ASSERT(fiber->frame_count == 1, OOPS);
ASSERT(fiber->frames[0].rbp == fiber->ret, OOPS); ASSERT(fiber->frames[0].rbp == fiber->ret, OOPS);
ASSERT((fiber->stack + fiber->stack_size) - fiber->sp >= argc, OOPS); ASSERT((fiber->stack + fiber->stack_size) - fiber->sp >= argc, OOPS);
@ -457,7 +457,7 @@ static inline bool resolveScriptPath(PKVM* vm, PkStringPtr* path_string) {
} }
// Import and return Script object as Var. If the script is imported and // Import and return Script object as Var. If the script is imported and
// compiled here it'll set [is_new_script] to true oterwise (using the cached // compiled here it'll set [is_new_script] to true otherwise (using the cached
// script) set to false. // script) set to false.
static inline Var importScript(PKVM* vm, String* path_name) { static inline Var importScript(PKVM* vm, String* path_name) {
@ -865,7 +865,7 @@ static PkResult runFiber(PKVM* vm, Fiber* fiber) {
String* name = script->names.data[READ_SHORT()]; String* name = script->names.data[READ_SHORT()];
Var scr = importScript(vm, name); Var scr = importScript(vm, name);
// TODO: implement fiber bsed execution. // TODO: implement fiber based execution.
//ASSERT(IS_OBJ_TYPE(script, OBJ_SCRIPT), OOPS); //ASSERT(IS_OBJ_TYPE(script, OBJ_SCRIPT), OOPS);
//Script* scr = (Script*)AS_OBJ(script); //Script* scr = (Script*)AS_OBJ(script);
//if (!scr->initialized) vmRunScript(vm, scr); //if (!scr->initialized) vmRunScript(vm, scr);
@ -891,7 +891,7 @@ static PkResult runFiber(PKVM* vm, Fiber* fiber) {
// -1 argument means multiple number of args. // -1 argument means multiple number of args.
if (fn->arity != -1 && fn->arity != argc) { if (fn->arity != -1 && fn->arity != argc) {
char buff[STR_INT_BUFF_SIZE]; sprintf(buff, "%d", fn->arity); char buff[STR_INT_BUFF_SIZE]; sprintf(buff, "%d", fn->arity);
String* msg = stringFormat(vm, "Expected excatly $ argument(s).", String* msg = stringFormat(vm, "Expected exactly $ argument(s).",
buff); buff);
RUNTIME_ERROR(msg); RUNTIME_ERROR(msg);
} }
@ -1102,7 +1102,7 @@ static PkResult runFiber(PKVM* vm, Fiber* fiber) {
// Pop the last frame, and if no more call frames, we're done with the // Pop the last frame, and if no more call frames, we're done with the
// current fiber. // current fiber.
if (--vm->fiber->frame_count == 0) { if (--vm->fiber->frame_count == 0) {
// TODO: if we're evaluvating an expressoin we need to set it's // TODO: if we're evaluating an expression we need to set it's
// value on the stack. // value on the stack.
//vm->fiber->sp = vm->fiber->stack; ?? //vm->fiber->sp = vm->fiber->stack; ??

View File

@ -24,7 +24,7 @@
// running one. // running one.
#define MIN_STACK_SIZE 128 #define MIN_STACK_SIZE 128
// The allocated size the'll trigger the first GC. (~10MB). // The allocated size that will trigger the first GC. (~10MB).
#define INITIAL_GC_SIZE (1024 * 1024 * 10) #define INITIAL_GC_SIZE (1024 * 1024 * 10)
// The heap size might shrink if the remaining allocated bytes after a GC // The heap size might shrink if the remaining allocated bytes after a GC
@ -80,7 +80,7 @@ struct PKVM {
int heap_fill_percent; int heap_fill_percent;
// In the tri coloring scheme gray is the working list. We recursively pop // In the tri coloring scheme gray is the working list. We recursively pop
// from the list color it balck and add it's referenced objects to gray_list. // from the list color it black and add it's referenced objects to gray_list.
Object** gray_list; Object** gray_list;
int gray_list_count; int gray_list_count;
int gray_list_capacity; int gray_list_capacity;
@ -146,7 +146,7 @@ PkHandle* vmNewHandle(PKVM* vm, Var value);
// '----------' | [obj4] | // '----------' | [obj4] |
// working set '------------------------' // working set '------------------------'
// //
// First we preform a tree traversel from all the vm's root objects. such as // First we preform a tree traversal from all the vm's root objects. such as
// stack values, temp references, handles, vm's running fiber, current // stack values, temp references, handles, vm's running fiber, current
// compiler (if it has any) etc. Mark them (ie. is_marked = true) and add // 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 // them to the working set (the gray_list). Pop the top object from the

View File

@ -7,8 +7,8 @@ from lang import write
## Reference: https://en.wikipedia.org/wiki/Brainfuck ## Reference: https://en.wikipedia.org/wiki/Brainfuck
## Note that this interpreter implementation is just to test pocketlang and is ## Note that this interpreter implementation is just to test pocketlang and is
## not an efficient one. This could be optimized by evaluvating the expressions ## not an efficient one. This could be optimized by evaluating the expressions
## at "compile time" (AOT) to avoid re-evaluvating those expressions at runtime ## at "compile time" (AOT) to avoid re-evaluating those expressions at runtime
## and also we can pre compile the loop jump offsets. ## and also we can pre compile the loop jump offsets.
## Source: https://en.wikipedia.org/wiki/Brainfuck ## Source: https://en.wikipedia.org/wiki/Brainfuck