Merged EngineNode and RenderNode

This commit is contained in:
2022-11-03 14:11:22 +01:00
parent 4ea1bd572a
commit 0775e56c1b
11 changed files with 365 additions and 536 deletions

View File

@@ -147,336 +147,6 @@ static int nativeLoadRootNode(Interpreter* interpreter, LiteralArray* arguments)
return 0;
}
static int nativeLoadNode(Interpreter* interpreter, LiteralArray* arguments) {
if (arguments->count != 1) {
interpreter->errorOutput("Incorrect number of arguments passed to loadNode\n");
return -1;
}
//extract the arguments
Literal fname = popLiteralArray(arguments);
Literal fnameIdn = fname;
if (IS_IDENTIFIER(fname) && parseIdentifierToValue(interpreter, &fname)) {
freeLiteral(fnameIdn);
}
//check argument types
if (!IS_STRING(fname)) {
interpreter->errorOutput("Incorrect argument type passed to loadNode\n");
freeLiteral(fname);
return -1;
}
//load the new node
size_t size = 0;
char* source = readFile(AS_STRING(fname), &size);
unsigned char* tb = compileString(source, &size);
free((void*)source);
EngineNode* node = ALLOCATE(EngineNode, 1);
//BUGFIX: make an inner-interpreter
Interpreter inner;
//init the inner interpreter manually
initLiteralArray(&inner.literalCache);
inner.scope = pushScope(NULL);
inner.bytecode = tb;
inner.length = size;
inner.count = 0;
inner.codeStart = -1;
inner.depth = interpreter->depth + 1;
inner.panic = false;
initLiteralArray(&inner.stack);
inner.exports = interpreter->exports;
inner.exportTypes = interpreter->exportTypes;
inner.hooks = interpreter->hooks;
setInterpreterPrint(&inner, interpreter->printOutput);
setInterpreterAssert(&inner, interpreter->assertOutput);
setInterpreterError(&inner, interpreter->errorOutput);
initEngineNode(node, &inner, tb, size);
// return the node
Literal nodeLiteral = TO_OPAQUE_LITERAL(node, node->tag);
pushLiteralArray(&interpreter->stack, nodeLiteral);
//cleanup
freeLiteralArray(&inner.stack);
freeLiteralArray(&inner.literalCache);
freeLiteral(fname);
freeLiteral(nodeLiteral);
return 1;
}
static int nativeInitNode(Interpreter* interpreter, LiteralArray* arguments) {
if (arguments->count != 1) {
interpreter->errorOutput("Incorrect number of arguments passed to initNode\n");
return -1;
}
Literal node = popLiteralArray(arguments);
Literal nodeIdn = node;
if (IS_IDENTIFIER(node) && parseIdentifierToValue(interpreter, &node)) {
freeLiteral(nodeIdn);
}
//check argument types
if (!IS_OPAQUE(node)) {
interpreter->errorOutput("Incorrect argument type passed to initNode\n");
freeLiteral(node);
return -1;
}
EngineNode* engineNode = AS_OPAQUE(node);
//init the new node
callEngineNode(engineNode, &engine.interpreter, "onInit");
//cleanup
freeLiteral(node);
return 0;
}
static int nativeFreeNode(Interpreter* interpreter, LiteralArray* arguments) {
if (arguments->count != 1) {
interpreter->errorOutput("Incorrect number of arguments passed to freeNode\n");
return -1;
}
Literal node = popLiteralArray(arguments);
Literal nodeIdn = node;
if (IS_IDENTIFIER(node) && parseIdentifierToValue(interpreter, &node)) {
freeLiteral(nodeIdn);
}
//check argument types
if (!IS_OPAQUE(node)) {
interpreter->errorOutput("Incorrect argument type passed to freeNode\n");
freeLiteral(node);
return -1;
}
EngineNode* engineNode = AS_OPAQUE(node);
//free the node
callEngineNode(engineNode, &engine.interpreter, "onFree");
freeEngineNode(engineNode);
//cleanup
freeLiteral(node);
return 0;
}
static int nativeFreeChildNode(Interpreter* interpreter, LiteralArray* arguments) {
if (arguments->count != 2) {
interpreter->errorOutput("Incorrect number of arguments passed to freeChildNode\n");
return -1;
}
Literal index = popLiteralArray(arguments);
Literal node = popLiteralArray(arguments);
Literal nodeIdn = node; //annoying
if (IS_IDENTIFIER(node) && parseIdentifierToValue(interpreter, &node)) {
freeLiteral(nodeIdn);
}
//check argument types
if (!IS_OPAQUE(node) || !IS_INTEGER(index)) {
interpreter->errorOutput("Incorrect argument type passed to freeChildNode\n");
freeLiteral(node);
return -1;
}
EngineNode* parentNode = AS_OPAQUE(node);
int idx = AS_INTEGER(index);
//check bounds
if (idx < 0 || idx >= parentNode->count) {
interpreter->errorOutput("Node index out of bounds in freeChildNode\n");
freeLiteral(node);
freeLiteral(index);
return -1;
}
//get the child node
EngineNode* childNode = parentNode->children[idx];
//free the node
if (childNode != NULL) {
callEngineNode(childNode, &engine.interpreter, "onFree");
freeEngineNode(childNode);
}
parentNode->children[idx] = NULL;
//cleanup
freeLiteral(node);
freeLiteral(index);
return 0;
}
static int nativePushNode(Interpreter* interpreter, LiteralArray* arguments) {
//checks
if (arguments->count != 2) {
interpreter->errorOutput("Incorrect number of arguments passed to pushNode\n");
return -1;
}
Literal child = popLiteralArray(arguments);
Literal parent = popLiteralArray(arguments);
Literal parentIdn = parent;
if (IS_IDENTIFIER(parent) && parseIdentifierToValue(interpreter, &parent)) {
freeLiteral(parentIdn);
}
Literal childIdn = child;
if (IS_IDENTIFIER(child) && parseIdentifierToValue(interpreter, &child)) {
freeLiteral(childIdn);
}
if (!IS_OPAQUE(parent) || !IS_OPAQUE(child)) {
interpreter->errorOutput("Incorrect argument type passed to pushNode\n");
freeLiteral(parent);
freeLiteral(child);
return -1;
}
//push the node
EngineNode* parentNode = AS_OPAQUE(parent);
EngineNode* childNode = AS_OPAQUE(child);
pushEngineNode(parentNode, childNode);
//no return value
freeLiteral(parent);
freeLiteral(child);
return 0;
}
static int nativeGetNode(Interpreter* interpreter, LiteralArray* arguments) {
//checks
if (arguments->count != 2) {
interpreter->errorOutput("Incorrect number of arguments passed to getNode\n");
return -1;
}
Literal index = popLiteralArray(arguments);
Literal parent = popLiteralArray(arguments);
Literal parentIdn = parent;
if (IS_IDENTIFIER(parent) && parseIdentifierToValue(interpreter, &parent)) {
freeLiteral(parentIdn);
}
if (!IS_OPAQUE(parent) || !IS_INTEGER(index)) {
interpreter->errorOutput("Incorrect argument type passed to getNode\n");
freeLiteral(parent);
freeLiteral(index);
return -1;
}
//push the node
EngineNode* parentNode = AS_OPAQUE(parent);
int intIndex = AS_INTEGER(index);
if (intIndex < 0 || intIndex >= parentNode->count) {
interpreter->errorOutput("index out of bounds in getNode\n");
freeLiteral(parent);
freeLiteral(index);
return -1;
}
EngineNode* childNode = parentNode->children[intIndex];
Literal child = TO_OPAQUE_LITERAL(childNode, childNode->tag);
pushLiteralArray(&interpreter->stack, child);
//no return value
freeLiteral(parent);
freeLiteral(child);
freeLiteral(index);
return 1;
}
static int nativeGetNodeParent(Interpreter* interpreter, LiteralArray* arguments) {
//checks
if (arguments->count != 1) {
interpreter->errorOutput("Incorrect number of arguments passed to getNodeParent\n");
return -1;
}
Literal nodeLiteral = popLiteralArray(arguments);
Literal nodeIdn = nodeLiteral;
if (IS_IDENTIFIER(nodeLiteral) && parseIdentifierToValue(interpreter, &nodeLiteral)) {
freeLiteral(nodeIdn);
}
if (!IS_OPAQUE(nodeLiteral)) {
interpreter->errorOutput("Incorrect argument type passed to getNodeParent\n");
freeLiteral(nodeLiteral);
return -1;
}
//push the node
EngineNode* node = AS_OPAQUE(nodeLiteral);
EngineNode* parent = node->parent;
Literal parentLiteral = TO_NULL_LITERAL;
if (parent != NULL) {
parentLiteral = TO_OPAQUE_LITERAL(parent, parent->tag);
}
pushLiteralArray(&interpreter->stack, parentLiteral);
//cleanup
freeLiteral(parentLiteral);
freeLiteral(nodeLiteral);
return 1;
}
static int nativeGetNodeTag(Interpreter* interpreter, LiteralArray* arguments) {
//checks
if (arguments->count != 1) {
interpreter->errorOutput("Incorrect number of arguments passed to getNodeTag\n");
return -1;
}
Literal nodeLiteral = popLiteralArray(arguments);
Literal nodeIdn = nodeLiteral;
if (IS_IDENTIFIER(nodeLiteral) && parseIdentifierToValue(interpreter, &nodeLiteral)) {
freeLiteral(nodeIdn);
}
if (!IS_OPAQUE(nodeLiteral)) {
interpreter->errorOutput("Incorrect argument type passed to getNodeTag\n");
freeLiteral(nodeLiteral);
return -1;
}
//push the tag
Literal tagLiteral = TO_INTEGER_LITERAL( ((EngineNode*)AS_OPAQUE(nodeLiteral))->tag );
pushLiteralArray(&interpreter->stack, tagLiteral);
//cleanup
freeLiteral(nodeLiteral);
freeLiteral(tagLiteral);
return 1;
}
//call the hook
typedef struct Natives {
char* name;
@@ -488,14 +158,6 @@ int hookEngine(Interpreter* interpreter, Literal identifier, Literal alias) {
Natives natives[] = {
{"initWindow", nativeInitWindow},
{"loadRootNode", nativeLoadRootNode},
{"loadNode", nativeLoadNode},
{"_initNode", nativeInitNode},
// {"freeNode", nativeFreeNode},
{"_freeChildNode", nativeFreeChildNode},
{"_pushNode", nativePushNode},
{"_getNode", nativeGetNode},
{"_getNodeParent", nativeGetNodeParent},
{"_getNodeTag", nativeGetNodeTag},
{NULL, NULL}
};