builtin types added.

This commit adds the builtin types to the VM's builtin classes
buffer (however no methods were added to those classes) and a super
class parameter introduced while creating a new class.
This commit is contained in:
Thakee Nathees 2022-04-20 15:35:33 +05:30
parent 4d46930d1b
commit 776ea0ab87
9 changed files with 92 additions and 13 deletions

View File

@ -171,7 +171,7 @@ static void _fileClose(PKVM* vm) {
void registerModuleIO(PKVM* vm) {
PkHandle* io = pkNewModule(vm, "io");
PkHandle* cls_file = pkNewClass(vm, io, "File");
PkHandle* cls_file = pkNewClass(vm, NULL, io, "File");
pkClassAddMethod(vm, cls_file, "open", _fileOpen, -1);
pkClassAddMethod(vm, cls_file, "read", _fileRead, 0);
pkClassAddMethod(vm, cls_file, "write", _fileWrite, 1);

View File

@ -288,7 +288,9 @@ PK_PUBLIC PkHandle* pkNewModule(PKVM* vm, const char* name);
PK_PUBLIC void pkRegisterModule(PKVM* vm, PkHandle* module);
// Create a new class on the [module] with the [name] and return it.
PK_PUBLIC PkHandle* pkNewClass(PKVM* vm, PkHandle* module, const char* name);
// If the [base_class] is NULL by default it'll set to "Object" class.
PK_PUBLIC PkHandle* pkNewClass(PKVM* vm, PkHandle* base_class,
PkHandle* module, const char* name);
// Add a native method to the given class. If the [arity] is -1 that means
// the method has variadic parameters and use pkGetArgc() to get the argc.

View File

@ -1257,6 +1257,19 @@ static int findBuiltinFunction(const PKVM* vm,
return -1;
}
// Find the builtin classes name and returns it's index in the VM's builtin
// classes array, if not found returns -1.
static int findBuiltinClass(const PKVM* vm,
const char* name, uint32_t length) {
for (int i = 0; i < PK_INSTANCE; i++) {
uint32_t bfn_length = vm->builtin_classes[i]->name->length;
if (IS_CSTR_EQ(vm->builtin_classes[i]->name, name, length)) {
return i;
}
}
return -1;
}
// Find the local with the [name] in the given function [func] and return
// it's index, if not found returns -1.
static int findLocal(Func* func, const char* name, uint32_t length) {
@ -1337,7 +1350,8 @@ typedef enum {
NAME_LOCAL_VAR, //< Including parameter.
NAME_UPVALUE, //< Local to an enclosing function.
NAME_GLOBAL_VAR,
NAME_BUILTIN_FN, //< Native builtin function.
NAME_BUILTIN_FN, //< Native builtin function.
NAME_BUILTIN_TY, //< Builtin primitive type classes.
} NameDefnType;
// Identifier search result.
@ -1394,6 +1408,13 @@ static NameSearchResult compilerSearchName(Compiler* compiler,
return result;
}
index = findBuiltinClass(compiler->parser.vm, name, length);
if (index != -1) {
result.type = NAME_BUILTIN_TY;
result.index = index;
return result;
}
return result;
}
@ -1573,6 +1594,11 @@ static void emitPushName(Compiler* compiler, NameDefnType type, int index) {
emitOpcode(compiler, OP_PUSH_BUILTIN_FN);
emitByte(compiler, index);
return;
case NAME_BUILTIN_TY:
emitOpcode(compiler, OP_PUSH_BUILTIN_TY);
emitByte(compiler, index);
return;
}
}
@ -1584,6 +1610,7 @@ static void emitStoreName(Compiler* compiler, NameDefnType type, int index) {
switch (type) {
case NAME_NOT_DEFINED:
case NAME_BUILTIN_FN:
case NAME_BUILTIN_TY:
UNREACHABLE();
case NAME_LOCAL_VAR:
@ -1701,7 +1728,9 @@ static void exprName(Compiler* compiler) {
// like python does) and it's recommented to define all the globals
// before entering a local scope.
if (result.type == NAME_NOT_DEFINED || result.type == NAME_BUILTIN_FN) {
if (result.type == NAME_NOT_DEFINED ||
result.type == NAME_BUILTIN_FN ||
result.type == NAME_BUILTIN_TY ) {
name_type = (compiler->scope_depth == DEPTH_GLOBAL)
? NAME_GLOBAL_VAR
: NAME_LOCAL_VAR;
@ -2283,8 +2312,10 @@ static void compileClass(Compiler* compiler) {
// Create a new class.
int cls_index;
Class* cls = newClass(compiler->parser.vm, name, name_len,
compiler->module, NULL, &cls_index);
PKVM* _vm = compiler->parser.vm;
Class* cls = newClass(_vm, name, name_len,
_vm->builtin_classes[PK_OBJECT], compiler->module,
NULL, &cls_index);
// Check count exceeded.
checkMaxConstantsReached(compiler, cls_index);

View File

@ -69,13 +69,21 @@ void pkRegisterModule(PKVM* vm, PkHandle* module) {
vmRegisterModule(vm, module_, module_->name);
}
PkHandle* pkNewClass(PKVM* vm, PkHandle* module, const char* name) {
PkHandle* pkNewClass(PKVM* vm, PkHandle* base_class, PkHandle* module,
const char* name) {
CHECK_NULL(module);
CHECK_NULL(name);
CHECK_TYPE(module, OBJ_MODULE);
Class* super = vm->builtin_classes[PK_OBJECT];
if (base_class != NULL) {
CHECK_TYPE(base_class, OBJ_CLASS);
super = (Class*)AS_OBJ(base_class->value);
}
Class* class_ = newClass(vm, name, (int)strlen(name),
(Module*)AS_OBJ(module->value), NULL, NULL);
super, (Module*)AS_OBJ(module->value),
NULL, NULL);
return vmNewHandle(vm, VAR_OBJ(class_));
}
@ -1222,7 +1230,15 @@ static void initializeCoreModules(PKVM* vm) {
/*****************************************************************************/
static void initializePrimitiveClasses(PKVM* vm) {
// TODO
for (int i = 0; i < PK_INSTANCE; i++) {
Class* super = NULL;
if (i != 0) super = vm->builtin_classes[PK_OBJECT];
const char* name = getPkVarTypeName((PkVarType)i);
vm->builtin_classes[i] = newClass(vm, name, (int)strlen(name),
super, NULL, NULL, NULL);
}
// TODO: Add methods to those classes.
}
/*****************************************************************************/

View File

@ -227,6 +227,19 @@ void dumpFunctionCode(PKVM* vm, Function* func) {
break;
}
case OP_PUSH_BUILTIN_TY:
{
int index = READ_BYTE();
ASSERT_INDEX(index, PK_INSTANCE);
const char* name = vm->builtin_classes[index]->name->data;
// Prints: %5d [Fn:%s]\n
PRINT_INT(index);
PRINT(" [Class:");
PRINT(name);
PRINT("]\n");
break;
}
case OP_PUSH_UPVALUE:
case OP_STORE_UPVALUE:
{

View File

@ -92,6 +92,10 @@ OPCODE(STORE_GLOBAL, 1, 0)
// params: 1 bytes index.
OPCODE(PUSH_BUILTIN_FN, 1, 1)
// Push a built in class.
// params: 1 bytes index.
OPCODE(PUSH_BUILTIN_TY, 1, 1)
// Push an upvalue of the current closure at the index which is the first one
// byte argument.
// params: 1 byte index.

View File

@ -492,8 +492,8 @@ Fiber* newFiber(PKVM* vm, Closure* closure) {
}
Class* newClass(PKVM* vm, const char* name, int length,
Module* module, const char* docstring,
int* cls_index) {
Class* super, Module* module,
const char* docstring, int* cls_index) {
Class* cls = ALLOCATE(vm, Class);
varInitObject(&cls->_super, vm, OBJ_CLASS);
@ -501,6 +501,7 @@ Class* newClass(PKVM* vm, const char* name, int length,
vmPushTempRef(vm, &cls->_super); // class.
cls->owner = NULL;
cls->super_class = super;
cls->docstring = NULL;
cls->ctor = NULL;

View File

@ -480,6 +480,9 @@ struct Fiber {
struct Class {
Object _super;
// The base class of this class.
Class* super_class;
// The module that owns this class.
Module* owner;
@ -566,8 +569,8 @@ Function* newFunction(PKVM* vm, const char* name, int length,
// the module's constant pool. The class will be added to the modules global
// as well.
Class* newClass(PKVM* vm, const char* name, int length,
Module* module, const char* docstring,
int* cls_index);
Class* super, Module* module,
const char* docstring, int* cls_index);
// Allocate new instance with of the base [type].
Instance* newInstance(PKVM* vm, Class* cls);

View File

@ -949,6 +949,15 @@ L_vm_main_loop:
DISPATCH();
}
OPCODE(PUSH_BUILTIN_TY):
{
uint8_t index = READ_BYTE();
ASSERT_INDEX(index, PK_INSTANCE);
Class* cls = vm->builtin_classes[index];
PUSH(VAR_OBJ(cls));
DISPATCH();
}
OPCODE(PUSH_UPVALUE):
{
uint8_t index = READ_BYTE();