pocketlang/cli/modules/std_dummy.c
2022-05-17 07:08:14 +05:30

127 lines
3.3 KiB
C

/*
* Copyright (c) 2020-2022 Thakee Nathees
* Copyright (c) 2021-2022 Pocketlang Contributors
* Distributed Under The MIT License
*/
#include "modules.h"
// A DUMMY MODULE TO TEST NATIVE INTERFACE AND CLASSES.
typedef struct {
double val;
} Dummy;
void* _newDummy() {
Dummy* dummy = NEW_OBJ(Dummy);
ASSERT(dummy != NULL, "malloc failed.");
dummy->val = 0;
return dummy;
}
void _deleteDummy(void* ptr) {
Dummy* dummy = (Dummy*)ptr;
FREE_OBJ(dummy);
}
DEF(_dummyInit, "") {
double val;
if (!pkValidateSlotNumber(vm, 1, &val)) return;
Dummy* self = (Dummy*) pkGetSelf(vm);
self->val = val;
}
DEF(_dummyGetter, "") {
const char* name = pkGetSlotString(vm, 1, NULL);
Dummy* self = (Dummy*)pkGetSelf(vm);
if (strcmp("val", name) == 0) {
pkSetSlotNumber(vm, 0, self->val);
return;
}
}
DEF(_dummySetter, "") {
const char* name = pkGetSlotString(vm, 1, NULL);
Dummy* self = (Dummy*)pkGetSelf(vm);
if (strcmp("val", name) == 0) {
double val;
if (!pkValidateSlotNumber(vm, 2, &val)) return;
self->val = val;
return;
}
}
DEF(_dummyAdd, "") {
Dummy* self = (Dummy*) pkGetSelf(vm);
pkReserveSlots(vm, 4); // Now we have slots [0, 1, 2, 3].
pkPlaceSelf(vm, 2); // slot[2] = self
pkGetClass(vm, 2, 2); // slot[2] = Dummy class.
// slots[1] = other.
if (!pkValidateSlotInstanceOf(vm, 1, 2)) return;
Dummy* other = (Dummy*) pkGetSlotNativeInstance(vm, 1);
// slot[3] = self.val + other.val
pkSetSlotNumber(vm, 3, self->val + other->val);
// slot[0] = Dummy(slot[3]) => return value.
if (!pkNewInstance(vm, 2, 0, 1, 3)) return;
}
DEF(_dummyEq, "") {
// TODO: Currently there is no way of getting another native instance
// So, it's impossible to check self == other. So for now checking with
// number.
double value;
if (!pkValidateSlotNumber(vm, 1, &value)) return;
Dummy* self = (Dummy*)pkGetSelf(vm);
pkSetSlotBool(vm, 0, value == self->val);
}
DEF(_dummyGt, "") {
// TODO: Currently there is no way of getting another native instance
// So, it's impossible to check self == other. So for now checking with
// number.
double value;
if (!pkValidateSlotNumber(vm, 1, &value)) return;
Dummy* self = (Dummy*)pkGetSelf(vm);
pkSetSlotBool(vm, 0, self->val > value);
}
DEF(_dummyMethod,
"Dummy.a_method(n1:num, n2:num) -> num\n"
"A dummy method to check dummy method calls. Will take 2 number arguments "
"and return the multiplication.") {
double n1, n2;
if (!pkValidateSlotNumber(vm, 1, &n1)) return;
if (!pkValidateSlotNumber(vm, 2, &n2)) return;
pkSetSlotNumber(vm, 0, n1 * n2);
}
void registerModuleDummy(PKVM* vm) {
PkHandle* dummy = pkNewModule(vm, "dummy");
PkHandle* cls_dummy = pkNewClass(vm, "Dummy", NULL, dummy,
_newDummy, _deleteDummy);
pkClassAddMethod(vm, cls_dummy, "_init", _dummyInit, 1);
pkClassAddMethod(vm, cls_dummy, "@getter", _dummyGetter, 1);
pkClassAddMethod(vm, cls_dummy, "@setter", _dummySetter, 2);
pkClassAddMethod(vm, cls_dummy, "+", _dummyAdd, 1);
pkClassAddMethod(vm, cls_dummy, "==", _dummyEq, 1);
pkClassAddMethod(vm, cls_dummy, ">", _dummyGt, 1);
pkClassAddMethod(vm, cls_dummy, "a_method", _dummyMethod, 2);
pkReleaseHandle(vm, cls_dummy);
pkRegisterModule(vm, dummy);
pkReleaseHandle(vm, dummy);
}