mirror of
https://github.com/zekexiao/pocketlang.git
synced 2025-02-11 07:00:58 +08:00
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:
parent
4d46930d1b
commit
776ea0ab87
@ -171,7 +171,7 @@ static void _fileClose(PKVM* vm) {
|
|||||||
void registerModuleIO(PKVM* vm) {
|
void registerModuleIO(PKVM* vm) {
|
||||||
PkHandle* io = pkNewModule(vm, "io");
|
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, "open", _fileOpen, -1);
|
||||||
pkClassAddMethod(vm, cls_file, "read", _fileRead, 0);
|
pkClassAddMethod(vm, cls_file, "read", _fileRead, 0);
|
||||||
pkClassAddMethod(vm, cls_file, "write", _fileWrite, 1);
|
pkClassAddMethod(vm, cls_file, "write", _fileWrite, 1);
|
||||||
|
@ -288,7 +288,9 @@ PK_PUBLIC PkHandle* pkNewModule(PKVM* vm, const char* name);
|
|||||||
PK_PUBLIC void pkRegisterModule(PKVM* vm, PkHandle* module);
|
PK_PUBLIC void pkRegisterModule(PKVM* vm, PkHandle* module);
|
||||||
|
|
||||||
// Create a new class on the [module] with the [name] and return it.
|
// 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
|
// 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.
|
// the method has variadic parameters and use pkGetArgc() to get the argc.
|
||||||
|
@ -1257,6 +1257,19 @@ static int findBuiltinFunction(const PKVM* vm,
|
|||||||
return -1;
|
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
|
// Find the local with the [name] in the given function [func] and return
|
||||||
// it's index, if not found returns -1.
|
// it's index, if not found returns -1.
|
||||||
static int findLocal(Func* func, const char* name, uint32_t length) {
|
static int findLocal(Func* func, const char* name, uint32_t length) {
|
||||||
@ -1337,7 +1350,8 @@ typedef enum {
|
|||||||
NAME_LOCAL_VAR, //< Including parameter.
|
NAME_LOCAL_VAR, //< Including parameter.
|
||||||
NAME_UPVALUE, //< Local to an enclosing function.
|
NAME_UPVALUE, //< Local to an enclosing function.
|
||||||
NAME_GLOBAL_VAR,
|
NAME_GLOBAL_VAR,
|
||||||
NAME_BUILTIN_FN, //< Native builtin function.
|
NAME_BUILTIN_FN, //< Native builtin function.
|
||||||
|
NAME_BUILTIN_TY, //< Builtin primitive type classes.
|
||||||
} NameDefnType;
|
} NameDefnType;
|
||||||
|
|
||||||
// Identifier search result.
|
// Identifier search result.
|
||||||
@ -1394,6 +1408,13 @@ static NameSearchResult compilerSearchName(Compiler* compiler,
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
index = findBuiltinClass(compiler->parser.vm, name, length);
|
||||||
|
if (index != -1) {
|
||||||
|
result.type = NAME_BUILTIN_TY;
|
||||||
|
result.index = index;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1573,6 +1594,11 @@ static void emitPushName(Compiler* compiler, NameDefnType type, int index) {
|
|||||||
emitOpcode(compiler, OP_PUSH_BUILTIN_FN);
|
emitOpcode(compiler, OP_PUSH_BUILTIN_FN);
|
||||||
emitByte(compiler, index);
|
emitByte(compiler, index);
|
||||||
return;
|
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) {
|
switch (type) {
|
||||||
case NAME_NOT_DEFINED:
|
case NAME_NOT_DEFINED:
|
||||||
case NAME_BUILTIN_FN:
|
case NAME_BUILTIN_FN:
|
||||||
|
case NAME_BUILTIN_TY:
|
||||||
UNREACHABLE();
|
UNREACHABLE();
|
||||||
|
|
||||||
case NAME_LOCAL_VAR:
|
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
|
// like python does) and it's recommented to define all the globals
|
||||||
// before entering a local scope.
|
// 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_type = (compiler->scope_depth == DEPTH_GLOBAL)
|
||||||
? NAME_GLOBAL_VAR
|
? NAME_GLOBAL_VAR
|
||||||
: NAME_LOCAL_VAR;
|
: NAME_LOCAL_VAR;
|
||||||
@ -2283,8 +2312,10 @@ static void compileClass(Compiler* compiler) {
|
|||||||
|
|
||||||
// Create a new class.
|
// Create a new class.
|
||||||
int cls_index;
|
int cls_index;
|
||||||
Class* cls = newClass(compiler->parser.vm, name, name_len,
|
PKVM* _vm = compiler->parser.vm;
|
||||||
compiler->module, NULL, &cls_index);
|
Class* cls = newClass(_vm, name, name_len,
|
||||||
|
_vm->builtin_classes[PK_OBJECT], compiler->module,
|
||||||
|
NULL, &cls_index);
|
||||||
|
|
||||||
// Check count exceeded.
|
// Check count exceeded.
|
||||||
checkMaxConstantsReached(compiler, cls_index);
|
checkMaxConstantsReached(compiler, cls_index);
|
||||||
|
@ -69,13 +69,21 @@ void pkRegisterModule(PKVM* vm, PkHandle* module) {
|
|||||||
vmRegisterModule(vm, module_, module_->name);
|
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(module);
|
||||||
CHECK_NULL(name);
|
CHECK_NULL(name);
|
||||||
CHECK_TYPE(module, OBJ_MODULE);
|
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),
|
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_));
|
return vmNewHandle(vm, VAR_OBJ(class_));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1222,7 +1230,15 @@ static void initializeCoreModules(PKVM* vm) {
|
|||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void initializePrimitiveClasses(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.
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
@ -227,6 +227,19 @@ void dumpFunctionCode(PKVM* vm, Function* func) {
|
|||||||
break;
|
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_PUSH_UPVALUE:
|
||||||
case OP_STORE_UPVALUE:
|
case OP_STORE_UPVALUE:
|
||||||
{
|
{
|
||||||
|
@ -92,6 +92,10 @@ OPCODE(STORE_GLOBAL, 1, 0)
|
|||||||
// params: 1 bytes index.
|
// params: 1 bytes index.
|
||||||
OPCODE(PUSH_BUILTIN_FN, 1, 1)
|
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
|
// Push an upvalue of the current closure at the index which is the first one
|
||||||
// byte argument.
|
// byte argument.
|
||||||
// params: 1 byte index.
|
// params: 1 byte index.
|
||||||
|
@ -492,8 +492,8 @@ Fiber* newFiber(PKVM* vm, Closure* closure) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Class* newClass(PKVM* vm, const char* name, int length,
|
Class* newClass(PKVM* vm, const char* name, int length,
|
||||||
Module* module, const char* docstring,
|
Class* super, Module* module,
|
||||||
int* cls_index) {
|
const char* docstring, int* cls_index) {
|
||||||
|
|
||||||
Class* cls = ALLOCATE(vm, Class);
|
Class* cls = ALLOCATE(vm, Class);
|
||||||
varInitObject(&cls->_super, vm, OBJ_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.
|
vmPushTempRef(vm, &cls->_super); // class.
|
||||||
|
|
||||||
cls->owner = NULL;
|
cls->owner = NULL;
|
||||||
|
cls->super_class = super;
|
||||||
cls->docstring = NULL;
|
cls->docstring = NULL;
|
||||||
cls->ctor = NULL;
|
cls->ctor = NULL;
|
||||||
|
|
||||||
|
@ -480,6 +480,9 @@ struct Fiber {
|
|||||||
struct Class {
|
struct Class {
|
||||||
Object _super;
|
Object _super;
|
||||||
|
|
||||||
|
// The base class of this class.
|
||||||
|
Class* super_class;
|
||||||
|
|
||||||
// The module that owns this class.
|
// The module that owns this class.
|
||||||
Module* owner;
|
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
|
// the module's constant pool. The class will be added to the modules global
|
||||||
// as well.
|
// as well.
|
||||||
Class* newClass(PKVM* vm, const char* name, int length,
|
Class* newClass(PKVM* vm, const char* name, int length,
|
||||||
Module* module, const char* docstring,
|
Class* super, Module* module,
|
||||||
int* cls_index);
|
const char* docstring, int* cls_index);
|
||||||
|
|
||||||
// Allocate new instance with of the base [type].
|
// Allocate new instance with of the base [type].
|
||||||
Instance* newInstance(PKVM* vm, Class* cls);
|
Instance* newInstance(PKVM* vm, Class* cls);
|
||||||
|
@ -949,6 +949,15 @@ L_vm_main_loop:
|
|||||||
DISPATCH();
|
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):
|
OPCODE(PUSH_UPVALUE):
|
||||||
{
|
{
|
||||||
uint8_t index = READ_BYTE();
|
uint8_t index = READ_BYTE();
|
||||||
|
Loading…
Reference in New Issue
Block a user