some comments were added (#169)

This commit is contained in:
Thakee Nathees 2022-03-30 23:43:18 +05:30 committed by GitHub
parent bcfa4de706
commit 6e02e021bc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 61 additions and 54 deletions

View File

@ -74,7 +74,7 @@ const char* getObjName(uint32_t id) {
/*****************************************************************************/ /*****************************************************************************/
#include "thirdparty/cwalk/cwalk.h" #include "thirdparty/cwalk/cwalk.h"
#if defined(_WIN32) && (defined(_MSC_VER) || defined(__TINYC__)) #if defined(_WIN32) && (defined(_MSC_VER) || defined(__TINYC__))
#include "thirdparty/dirent/dirent.h" #include "thirdparty/dirent/dirent.h"
#else #else
#include <dirent.h> #include <dirent.h>

View File

@ -4,20 +4,14 @@ Add '.title' attribute to string
// To implement. // To implement.
- make assert as a keyword (like python) and disable it on release build.
- implement 'lang.getMaxCallDepth()' (default=1000 like python) and - implement 'lang.getMaxCallDepth()' (default=1000 like python) and
setMaxCallDepth(val) to change stack size at runtime. setMaxCallDepth(val) to change stack size at runtime. (at: pushCallFrame())
- make assert as a keyword (like python) and disable it on release build.
- change or add => to_string() to value.as_string - change or add => to_string() to value.as_string
and add as_repr, as_bool. and add as_repr, as_bool.
- literal function recursive call.
fn = func(a, b)
this(a, b) // Something like this.
fn(a, b) // May be closure support?
end
- Implement utf8 support. - Implement utf8 support.
- Implement gdb like debugger (add color print for readability). - Implement gdb like debugger (add color print for readability).
- Complete all the TODO; macros. - Complete all the TODO; macros.
@ -30,6 +24,11 @@ Add '.title' attribute to string
- To do so the functions and global variables should be in the same - To do so the functions and global variables should be in the same
buffer as the property of the script. buffer as the property of the script.
- Union tagging alter in var. - Union tagging alter in var.
- literal function recursive call.
fn = func(a, b)
this(a, b) // Something like this.
fn(a, b) // May be closure support?
end
// Add more. // Add more.
- Single header for embedding (script in pk, require file IO). - Single header for embedding (script in pk, require file IO).
@ -66,3 +65,6 @@ implement, and nothing would be work as expected.
... _f() // _f not defined (no closure). ... _f() // _f not defined (no closure).
... end ... end
Error: Expected an expression // expected Name '_f' not defined. Error: Expected an expression // expected Name '_f' not defined.
Update: The above code just terminates in repl without printing any
error messages.

View File

@ -73,7 +73,8 @@ typedef struct PkHandle PkHandle;
// A temproary pointer to the pocketlang variable. This pointer is acquired // A temproary pointer to the pocketlang variable. This pointer is acquired
// from the pocketlang's current stack frame and the pointer will become // from the pocketlang's current stack frame and the pointer will become
// dangling once after the stack frame is popped. // dangling once the stack frame is popped. If you want to keep the value
// alive use `pkNewHandle()`.
typedef void* PkVar; typedef void* PkVar;
// Type enum of the pocketlang variables, this can be used to get the type // Type enum of the pocketlang variables, this can be used to get the type
@ -160,10 +161,10 @@ typedef PkStringPtr (*pkReadFn) (PKVM* vm);
// the native instance. // the native instance.
typedef void (*pkInstFreeFn) (PKVM* vm, void* instance, uint32_t id); typedef void (*pkInstFreeFn) (PKVM* vm, void* instance, uint32_t id);
// A function callback to get the name of the native instance from pocketlang, // A function callback to get the type name of the native instance from
// using it's [id]. The returned string won't be copied by pocketlang so it's // pocketlang, using it's [id]. The returned string won't be copied by
// expected to be alived since the instance is alive and recomended to return // pocketlang so it's expected to be alived since the instance is alive and
// a C literal string. // recomended to return a C literal string.
typedef const char* (*pkInstNameFn) (uint32_t id); typedef const char* (*pkInstNameFn) (uint32_t id);
// A get arribute callback, called by pocket VM when trying to get an attribute // A get arribute callback, called by pocket VM when trying to get an attribute
@ -226,9 +227,10 @@ PK_PUBLIC void pkSetUserData(PKVM* vm, void* user_data);
PK_PUBLIC void* pkGetUserData(const PKVM* vm); PK_PUBLIC void* pkGetUserData(const PKVM* vm);
// Create a new handle for the [value]. This is useful to keep the [value] // Create a new handle for the [value]. This is useful to keep the [value]
// alive once it acquired from the stack. Do not use the [value] once // alive once it acquired from the stack. **DO NOT** use the [value] once
// creating a new handle for it instead get the value from the handle by // creating a new handle for it instead get the value from the handle by
// using pkGetHandleValue() function. // using pkGetHandleValue() function (otherwise the [value] would become a
// dangling pointer once it's stack frame is popped).
PK_PUBLIC PkHandle* pkNewHandle(PKVM* vm, PkVar value); PK_PUBLIC PkHandle* pkNewHandle(PKVM* vm, PkVar value);
// Return the PkVar pointer in the handle, the returned pointer will be valid // Return the PkVar pointer in the handle, the returned pointer will be valid

View File

@ -195,7 +195,7 @@ static _Keyword _keywords[] = {
{ "continue", 8, TK_CONTINUE }, { "continue", 8, TK_CONTINUE },
{ "return", 6, TK_RETURN }, { "return", 6, TK_RETURN },
{ NULL, 0, (TokenType)(0) }, // Sentinel to mark the end of the array { NULL, 0, (TokenType)(0) }, // Sentinel to mark the end of the array.
}; };
/*****************************************************************************/ /*****************************************************************************/
@ -1935,8 +1935,8 @@ typedef enum {
static void compileStatement(Compiler* compiler); static void compileStatement(Compiler* compiler);
static void compileBlockBody(Compiler* compiler, BlockType type); static void compileBlockBody(Compiler* compiler, BlockType type);
// Compile a type and return it's index in the script's types buffer. // Compile a class and return it's index in the script's types buffer.
static int compileType(Compiler* compiler) { static int compileClass(Compiler* compiler) {
// Consume the name of the type. // Consume the name of the type.
consume(compiler, TK_NAME, "Expected a type name."); consume(compiler, TK_NAME, "Expected a type name.");
@ -1947,10 +1947,10 @@ static int compileType(Compiler* compiler) {
parseError(compiler, "Name '%.*s' already exists.", name_len, name); parseError(compiler, "Name '%.*s' already exists.", name_len, name);
} }
// Create a new type. // Create a new class.
Class* type = newClass(compiler->vm, compiler->script, Class* cls = newClass(compiler->vm, compiler->script,
name, (uint32_t)name_len); name, (uint32_t)name_len);
type->ctor->arity = 0; cls->ctor->arity = 0;
// Check count exceeded. // Check count exceeded.
int fn_index = (int)compiler->script->functions.count - 1; int fn_index = (int)compiler->script->functions.count - 1;
@ -1959,8 +1959,8 @@ static int compileType(Compiler* compiler) {
MAX_FUNCTIONS); MAX_FUNCTIONS);
} }
int ty_index = (int)(compiler->script->classes.count - 1); int cls_index = (int)(compiler->script->classes.count - 1);
if (ty_index == MAX_CLASSES) { if (cls_index == MAX_CLASSES) {
parseError(compiler, "A script should contain at most %d types.", parseError(compiler, "A script should contain at most %d types.",
MAX_CLASSES); MAX_CLASSES);
} }
@ -1968,12 +1968,12 @@ static int compileType(Compiler* compiler) {
// Compile the constructor function. // Compile the constructor function.
ASSERT(compiler->func->ptr == compiler->script->body, OOPS); ASSERT(compiler->func->ptr == compiler->script->body, OOPS);
Func curr_fn; Func curr_fn;
compilerPushFunc(compiler, &curr_fn, type->ctor, fn_index); compilerPushFunc(compiler, &curr_fn, cls->ctor, fn_index);
compilerEnterBlock(compiler); compilerEnterBlock(compiler);
// Push an instance on the stack. // Push an instance on the stack.
emitOpcode(compiler, OP_PUSH_INSTANCE); emitOpcode(compiler, OP_PUSH_INSTANCE);
emitByte(compiler, ty_index); emitByte(compiler, cls_index);
skipNewLines(compiler); skipNewLines(compiler);
TokenType next = peek(compiler); TokenType next = peek(compiler);
@ -1989,8 +1989,8 @@ static int compileType(Compiler* compiler) {
// TODO: Add a string compare macro. // TODO: Add a string compare macro.
String* new_name = compiler->script->names.data[f_index]; String* new_name = compiler->script->names.data[f_index];
for (uint32_t i = 0; i < type->field_names.count; i++) { for (uint32_t i = 0; i < cls->field_names.count; i++) {
String* prev = compiler->script->names.data[type->field_names.data[i]]; String* prev = compiler->script->names.data[cls->field_names.data[i]];
if (new_name->hash == prev->hash && new_name->length == prev->length && if (new_name->hash == prev->hash && new_name->length == prev->length &&
memcmp(new_name->data, prev->data, prev->length) == 0) { memcmp(new_name->data, prev->data, prev->length) == 0) {
parseError(compiler, "Class field with name '%s' already exists.", parseError(compiler, "Class field with name '%s' already exists.",
@ -1998,7 +1998,7 @@ static int compileType(Compiler* compiler) {
} }
} }
pkUintBufferWrite(&type->field_names, compiler->vm, f_index); pkUintBufferWrite(&cls->field_names, compiler->vm, f_index);
// Consume the assignment expression. // Consume the assignment expression.
consume(compiler, TK_EQ, "Expected an assignment after field name."); consume(compiler, TK_EQ, "Expected an assignment after field name.");
@ -2011,7 +2011,7 @@ static int compileType(Compiler* compiler) {
skipNewLines(compiler); skipNewLines(compiler);
next = peek(compiler); next = peek(compiler);
} }
consume(compiler, TK_END, "Expected 'end' after type declaration end."); consume(compiler, TK_END, "Expected 'end' after a class declaration end.");
compilerExitBlock(compiler); compilerExitBlock(compiler);
@ -2352,7 +2352,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);
// Import all types. // Import all classes.
for (uint32_t i = 0; i < script->classes.count; i++) { for (uint32_t i = 0; i < script->classes.count; i++) {
uint32_t name_ind = script->classes.data[i]->name; uint32_t name_ind = script->classes.data[i]->name;
String* name = script->names.data[name_ind]; String* name = script->names.data[name_ind];
@ -2742,7 +2742,7 @@ static void compileTopLevelStatement(Compiler* compiler) {
compiler->is_last_call = false; compiler->is_last_call = false;
if (match(compiler, TK_CLASS)) { if (match(compiler, TK_CLASS)) {
compileType(compiler); compileClass(compiler);
} else if (match(compiler, TK_NATIVE)) { } else if (match(compiler, TK_NATIVE)) {
compileFunction(compiler, FN_NATIVE); compileFunction(compiler, FN_NATIVE);

View File

@ -810,8 +810,6 @@ static void moduleAddFunctionInternal(PKVM* vm, Script* script,
fn->arity = arity; fn->arity = arity;
} }
// TODO: make the below module functions as PK_DOC(name, doc);
// 'lang' library methods. // 'lang' library methods.
// ----------------------- // -----------------------
@ -1189,7 +1187,7 @@ DEF(stdFiberRun,
} }
DEF(stdFiberResume, DEF(stdFiberResume,
"fiber_resume(fb:Fiber) -> var\n" "resume(fb:Fiber) -> var\n"
"Resumes a yielded function from a previous call of fiber_run() function. " "Resumes a yielded function from a previous call of fiber_run() function. "
"Return it's return value or the yielded value if it's yielded.") { "Return it's return value or the yielded value if it's yielded.") {
@ -1678,7 +1676,7 @@ Var varGetAttrib(PKVM* vm, Var on, String* attrib) {
{ {
Script* scr = (Script*)obj; Script* scr = (Script*)obj;
// Search in types. // Search in classes.
int index = scriptGetClass(scr, attrib->data, attrib->length); int index = scriptGetClass(scr, attrib->data, attrib->length);
if (index != -1) { if (index != -1) {
ASSERT_INDEX((uint32_t)index, scr->classes.count); ASSERT_INDEX((uint32_t)index, scr->classes.count);

View File

@ -46,7 +46,7 @@ Var varBitNot(PKVM* vm, Var v); // Returns ~v.
bool varGreater(Var v1, Var v2); // Returns v1 > v2. bool varGreater(Var v1, Var v2); // Returns v1 > v2.
bool varLesser(Var v1, Var v2); // Returns v1 < v2. bool varLesser(Var v1, Var v2); // Returns v1 < v2.
// Returns elem in container. // Returns [elem] in [container].
bool varContains(PKVM* vm, Var elem, Var container); bool varContains(PKVM* vm, Var elem, Var container);
// Returns the attribute named [attrib] on the variable [on]. // Returns the attribute named [attrib] on the variable [on].

View File

@ -506,7 +506,8 @@ Class* newClass(PKVM* vm, Script* scr, const char* name, uint32_t length) {
type->name = scriptAddName(scr, vm, name, length); type->name = scriptAddName(scr, vm, name, length);
pkUintBufferInit(&type->field_names); pkUintBufferInit(&type->field_names);
// Can't use '$' in string format. (TODO) // Can't use '$' in string format, since it has a special meaning.
// TODO: escape the character.
String* ty_name = scr->names.data[type->name]; String* ty_name = scr->names.data[type->name];
String* dollar = newStringLength(vm, "$", 1); String* dollar = newStringLength(vm, "$", 1);
vmPushTempRef(vm, &dollar->_super); // dollar vmPushTempRef(vm, &dollar->_super); // dollar
@ -531,7 +532,7 @@ Instance* newInstance(PKVM* vm, Class* ty, bool initialize) {
vmPushTempRef(vm, &inst->_super); // inst. vmPushTempRef(vm, &inst->_super); // inst.
ASSERT(ty->name < ty->owner->names.count, OOPS); ASSERT(ty->name < ty->owner->names.count, OOPS);
inst->name = ty->owner->names.data[ty->name]->data; inst->ty_name = ty->owner->names.data[ty->name]->data;
inst->is_native = false; inst->is_native = false;
Inst* ins = ALLOCATE(vm, Inst); Inst* ins = ALLOCATE(vm, Inst);
@ -555,9 +556,9 @@ Instance* newInstanceNative(PKVM* vm, void* data, uint32_t id) {
inst->native_id = id; inst->native_id = id;
if (vm->config.inst_name_fn != NULL) { if (vm->config.inst_name_fn != NULL) {
inst->name = vm->config.inst_name_fn(id); inst->ty_name = vm->config.inst_name_fn(id);
} else { } else {
inst->name = "$(?)"; inst->ty_name = "$(?)";
} }
inst->native = data; inst->native = data;
@ -1078,7 +1079,7 @@ void freeObject(PKVM* vm, Object* self) {
} }
uint32_t scriptAddName(Script* self, PKVM* vm, const char* name, uint32_t scriptAddName(Script* self, PKVM* vm, const char* name,
uint32_t length) { uint32_t length) {
for (uint32_t i = 0; i < self->names.count; i++) { for (uint32_t i = 0; i < self->names.count; i++) {
String* _name = self->names.data[i]; String* _name = self->names.data[i];
@ -1236,8 +1237,10 @@ bool instSetAttrib(PKVM* vm, Instance* inst, String* attrib, Var value) {
if (vm->config.inst_set_attrib_fn) { if (vm->config.inst_set_attrib_fn) {
// Temproarly change the fiber's "return address" to points to the // Temproarly change the fiber's "return address" to points to the
// below var 'ret' so that the users can use 'pkGetArg...()' function // below var 'attrib_ptr' so that the users can use 'pkGetArg...()'
// to validate and get the attribute. // function to validate and get the attribute (users should use 0 as the
// index of the argument since it's at the return address and we cannot
// ensure fiber->ret[1] will be in bounds).
Var* temp = vm->fiber->ret; Var* temp = vm->fiber->ret;
Var attrib_ptr = value; Var attrib_ptr = value;
@ -1612,8 +1615,8 @@ static void _toStringInternal(PKVM* vm, const Var v, pkByteBuffer* buff,
{ {
const Instance* inst = (const Instance*)obj; const Instance* inst = (const Instance*)obj;
pkByteBufferWrite(buff, vm, '['); pkByteBufferWrite(buff, vm, '[');
pkByteBufferAddString(buff, vm, inst->name, pkByteBufferAddString(buff, vm, inst->ty_name,
(uint32_t)strlen(inst->name)); (uint32_t)strlen(inst->ty_name));
pkByteBufferWrite(buff, vm, ':'); pkByteBufferWrite(buff, vm, ':');
if (!inst->is_native) { if (!inst->is_native) {

View File

@ -9,7 +9,7 @@
#include "pk_buffers.h" #include "pk_buffers.h"
#include "pk_internal.h" #include "pk_internal.h"
/** @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 awesome language written by Bob Nystrom the * wren (https://wren.io/) an awesome language written by Bob Nystrom the
@ -277,6 +277,8 @@ struct Range {
double to; //< End of the range exclusive. double to; //< End of the range exclusive.
}; };
// In pocketlang, the terms Script and Module are interchangable. (Consider
// renaming it to Module to be consistance with the terms).
struct Script { struct Script {
Object _super; Object _super;
@ -395,14 +397,14 @@ typedef struct {
struct Instance { struct Instance {
Object _super; Object _super;
const char* name; //< Name of the type it belongs to. const char* ty_name; //< Name of the type it belongs to.
bool is_native; //< True if it's a native type instance. bool is_native; //< True if it's a native type instance.
uint32_t native_id; //< Unique ID of this native instance. uint32_t native_id; //< Unique ID of this native instance.
union { union {
void* native; //< C struct pointer. // TODO: void* native; //< C struct pointer. // TODO:
Inst* ins; //< Module instance pointer. Inst* ins; //< Module instance pointer.
}; };
}; };