mirror of
https://github.com/krgamestudios/Toy.git
synced 2026-04-15 14:54:07 +10:00
Adjusted how AST Nodes are generated
This commit is contained in:
@@ -5,106 +5,134 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
void freeNodeCustom(ASTNode* node, bool freeSelf) {
|
void freeASTNodeCustom(ASTNode* node, bool freeSelf) {
|
||||||
//don't free a NULL node
|
//don't free a NULL node
|
||||||
if (node == NULL) {
|
if (node == NULL) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch(node->type) {
|
switch(node->type) {
|
||||||
case AST_NODEERROR:
|
case AST_NODE_ERROR:
|
||||||
//NO-OP
|
//NO-OP
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AST_NODELITERAL:
|
case AST_NODE_LITERAL:
|
||||||
freeLiteral(node->atomic.literal);
|
freeLiteral(node->atomic.literal);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AST_NODEUNARY:
|
case AST_NODE_UNARY:
|
||||||
freeNode(node->unary.child);
|
freeASTNode(node->unary.child);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AST_NODEBINARY:
|
case AST_NODE_BINARY:
|
||||||
freeNode(node->binary.left);
|
freeASTNode(node->binary.left);
|
||||||
freeNode(node->binary.right);
|
freeASTNode(node->binary.right);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AST_NODEGROUPING:
|
case AST_NODE_GROUPING:
|
||||||
freeNode(node->grouping.child);
|
freeASTNode(node->grouping.child);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AST_NODEBLOCK:
|
case AST_NODE_BLOCK:
|
||||||
for (int i = 0; i < node->block.count; i++) {
|
for (int i = 0; i < node->block.count; i++) {
|
||||||
freeNodeCustom(node->block.nodes + i, false);
|
freeASTNodeCustom(node->block.nodes + i, false);
|
||||||
}
|
}
|
||||||
FREE_ARRAY(ASTNode, node->block.nodes, node->block.capacity);
|
FREE_ARRAY(ASTNode, node->block.nodes, node->block.capacity);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AST_NODECOMPOUND:
|
case AST_NODE_COMPOUND:
|
||||||
for (int i = 0; i < node->compound.count; i++) {
|
for (int i = 0; i < node->compound.count; i++) {
|
||||||
freeNodeCustom(node->compound.nodes + i, false);
|
freeASTNodeCustom(node->compound.nodes + i, false);
|
||||||
}
|
}
|
||||||
FREE_ARRAY(ASTNode, node->compound.nodes, node->compound.capacity);
|
FREE_ARRAY(ASTNode, node->compound.nodes, node->compound.capacity);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AST_NODEPAIR:
|
case AST_NODE_PAIR:
|
||||||
freeNode(node->pair.left);
|
freeASTNode(node->pair.left);
|
||||||
freeNode(node->pair.right);
|
freeASTNode(node->pair.right);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AST_NODEVAR_DECL:
|
case AST_NODE_INDEX:
|
||||||
|
freeASTNode(node->index.first);
|
||||||
|
freeASTNode(node->index.second);
|
||||||
|
freeASTNode(node->index.third);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AST_NODE_VAR_DECL:
|
||||||
freeLiteral(node->varDecl.identifier);
|
freeLiteral(node->varDecl.identifier);
|
||||||
freeLiteral(node->varDecl.typeLiteral);
|
freeLiteral(node->varDecl.typeLiteral);
|
||||||
freeNode(node->varDecl.expression);
|
freeASTNode(node->varDecl.expression);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AST_NODEFN_DECL:
|
case AST_NODE_FN_COLLECTION:
|
||||||
freeLiteral(node->fnDecl.identifier);
|
|
||||||
freeNode(node->fnDecl.arguments);
|
|
||||||
freeNode(node->fnDecl.returns);
|
|
||||||
freeNode(node->fnDecl.block);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case AST_NODEFN_COLLECTION:
|
|
||||||
for (int i = 0; i < node->fnCollection.count; i++) {
|
for (int i = 0; i < node->fnCollection.count; i++) {
|
||||||
freeNodeCustom(node->fnCollection.nodes + i, false);
|
freeASTNodeCustom(node->fnCollection.nodes + i, false);
|
||||||
}
|
}
|
||||||
FREE_ARRAY(ASTNode, node->fnCollection.nodes, node->fnCollection.capacity);
|
FREE_ARRAY(ASTNode, node->fnCollection.nodes, node->fnCollection.capacity);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AST_NODEFN_CALL:
|
case AST_NODE_FN_DECL:
|
||||||
freeNode(node->fnCall.arguments);
|
freeLiteral(node->fnDecl.identifier);
|
||||||
|
freeASTNode(node->fnDecl.arguments);
|
||||||
|
freeASTNode(node->fnDecl.returns);
|
||||||
|
freeASTNode(node->fnDecl.block);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AST_NODEPATH_IF:
|
case AST_NODE_FN_CALL:
|
||||||
case AST_NODEPATH_WHILE:
|
freeASTNode(node->fnCall.arguments);
|
||||||
case AST_NODEPATH_FOR:
|
|
||||||
case AST_NODEPATH_BREAK:
|
|
||||||
case AST_NODEPATH_CONTINUE:
|
|
||||||
case AST_NODEPATH_RETURN:
|
|
||||||
freeNode(node->path.preClause);
|
|
||||||
freeNode(node->path.postClause);
|
|
||||||
freeNode(node->path.condition);
|
|
||||||
freeNode(node->path.thenPath);
|
|
||||||
freeNode(node->path.elsePath);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AST_NODEINCREMENT_PREFIX:
|
case AST_NODE_FN_RETURN:
|
||||||
case AST_NODEINCREMENT_POSTFIX:
|
freeASTNode(node->returns.returns);
|
||||||
freeLiteral(node->increment.identifier);
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AST_NODEIMPORT:
|
case AST_NODE_IF:
|
||||||
case AST_NODEEXPORT:
|
freeASTNode(node->pathIf.condition);
|
||||||
|
freeASTNode(node->pathIf.thenPath);
|
||||||
|
freeASTNode(node->pathIf.elsePath);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AST_NODE_WHILE:
|
||||||
|
freeASTNode(node->pathWhile.condition);
|
||||||
|
freeASTNode(node->pathWhile.thenPath);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AST_NODE_FOR:
|
||||||
|
freeASTNode(node->pathFor.preClause);
|
||||||
|
freeASTNode(node->pathFor.postClause);
|
||||||
|
freeASTNode(node->pathFor.condition);
|
||||||
|
freeASTNode(node->pathFor.thenPath);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AST_NODE_BREAK:
|
||||||
|
//NO-OP
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AST_NODE_CONTINUE:
|
||||||
|
//NO-OP
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AST_NODE_PREFIX_INCREMENT:
|
||||||
|
freeLiteral(node->prefixIncrement.identifier);
|
||||||
|
break;
|
||||||
|
case AST_NODE_PREFIX_DECREMENT:
|
||||||
|
freeLiteral(node->prefixDecrement.identifier);
|
||||||
|
break;
|
||||||
|
case AST_NODE_POSTFIX_INCREMENT:
|
||||||
|
freeLiteral(node->postfixIncrement.identifier);
|
||||||
|
break;
|
||||||
|
case AST_NODE_POSTFIX_DECREMENT:
|
||||||
|
freeLiteral(node->postfixDecrement.identifier);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case AST_NODE_IMPORT:
|
||||||
freeLiteral(node->import.identifier);
|
freeLiteral(node->import.identifier);
|
||||||
freeLiteral(node->import.alias);
|
freeLiteral(node->import.alias);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case AST_NODEINDEX:
|
case AST_NODE_EXPORT:
|
||||||
case AST_NODEDOT:
|
freeLiteral(node->export.identifier);
|
||||||
freeNode(node->index.first);
|
freeLiteral(node->export.alias);
|
||||||
freeNode(node->index.second);
|
|
||||||
freeNode(node->index.third);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -113,15 +141,16 @@ void freeNodeCustom(ASTNode* node, bool freeSelf) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void freeNode(ASTNode* node) {
|
void freeASTNode(ASTNode* node) {
|
||||||
freeNodeCustom(node, true);
|
freeASTNodeCustom(node, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//various emitters
|
||||||
void emitASTNodeLiteral(ASTNode** nodeHandle, Literal literal) {
|
void emitASTNodeLiteral(ASTNode** nodeHandle, Literal literal) {
|
||||||
//allocate a new node
|
//allocate a new node
|
||||||
*nodeHandle = ALLOCATE(ASTNode, 1);
|
*nodeHandle = ALLOCATE(ASTNode, 1);
|
||||||
|
|
||||||
(*nodeHandle)->type = AST_NODELITERAL;
|
(*nodeHandle)->type = AST_NODE_LITERAL;
|
||||||
(*nodeHandle)->atomic.literal = copyLiteral(literal);
|
(*nodeHandle)->atomic.literal = copyLiteral(literal);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,7 +158,7 @@ void emitASTNodeUnary(ASTNode** nodeHandle, Opcode opcode, ASTNode* child) {
|
|||||||
//allocate a new node
|
//allocate a new node
|
||||||
*nodeHandle = ALLOCATE(ASTNode, 1);
|
*nodeHandle = ALLOCATE(ASTNode, 1);
|
||||||
|
|
||||||
(*nodeHandle)->type = AST_NODEUNARY;
|
(*nodeHandle)->type = AST_NODE_UNARY;
|
||||||
(*nodeHandle)->unary.opcode = opcode;
|
(*nodeHandle)->unary.opcode = opcode;
|
||||||
(*nodeHandle)->unary.child = child;
|
(*nodeHandle)->unary.child = child;
|
||||||
}
|
}
|
||||||
@@ -137,7 +166,7 @@ void emitASTNodeUnary(ASTNode** nodeHandle, Opcode opcode, ASTNode* child) {
|
|||||||
void emitASTNodeBinary(ASTNode** nodeHandle, ASTNode* rhs, Opcode opcode) {
|
void emitASTNodeBinary(ASTNode** nodeHandle, ASTNode* rhs, Opcode opcode) {
|
||||||
ASTNode* tmp = ALLOCATE(ASTNode, 1);
|
ASTNode* tmp = ALLOCATE(ASTNode, 1);
|
||||||
|
|
||||||
tmp->type = AST_NODEBINARY;
|
tmp->type = AST_NODE_BINARY;
|
||||||
tmp->binary.opcode = opcode;
|
tmp->binary.opcode = opcode;
|
||||||
tmp->binary.left = *nodeHandle;
|
tmp->binary.left = *nodeHandle;
|
||||||
tmp->binary.right = rhs;
|
tmp->binary.right = rhs;
|
||||||
@@ -148,7 +177,7 @@ void emitASTNodeBinary(ASTNode** nodeHandle, ASTNode* rhs, Opcode opcode) {
|
|||||||
void emitASTNodeGrouping(ASTNode** nodeHandle) {
|
void emitASTNodeGrouping(ASTNode** nodeHandle) {
|
||||||
ASTNode* tmp = ALLOCATE(ASTNode, 1);
|
ASTNode* tmp = ALLOCATE(ASTNode, 1);
|
||||||
|
|
||||||
tmp->type = AST_NODEGROUPING;
|
tmp->type = AST_NODE_GROUPING;
|
||||||
tmp->grouping.child = *nodeHandle;
|
tmp->grouping.child = *nodeHandle;
|
||||||
|
|
||||||
*nodeHandle = tmp;
|
*nodeHandle = tmp;
|
||||||
@@ -157,8 +186,8 @@ void emitASTNodeGrouping(ASTNode** nodeHandle) {
|
|||||||
void emitASTNodeBlock(ASTNode** nodeHandle) {
|
void emitASTNodeBlock(ASTNode** nodeHandle) {
|
||||||
ASTNode* tmp = ALLOCATE(ASTNode, 1);
|
ASTNode* tmp = ALLOCATE(ASTNode, 1);
|
||||||
|
|
||||||
tmp->type = AST_NODEBLOCK;
|
tmp->type = AST_NODE_BLOCK;
|
||||||
tmp->block.nodes = NULL;
|
tmp->block.nodes = NULL; //NOTE: appended by the parser
|
||||||
tmp->block.capacity = 0;
|
tmp->block.capacity = 0;
|
||||||
tmp->block.count = 0;
|
tmp->block.count = 0;
|
||||||
|
|
||||||
@@ -168,7 +197,7 @@ void emitASTNodeBlock(ASTNode** nodeHandle) {
|
|||||||
void emitASTNodeCompound(ASTNode** nodeHandle, LiteralType literalType) {
|
void emitASTNodeCompound(ASTNode** nodeHandle, LiteralType literalType) {
|
||||||
ASTNode* tmp = ALLOCATE(ASTNode, 1);
|
ASTNode* tmp = ALLOCATE(ASTNode, 1);
|
||||||
|
|
||||||
tmp->type = AST_NODECOMPOUND;
|
tmp->type = AST_NODE_COMPOUND;
|
||||||
tmp->compound.literalType = literalType;
|
tmp->compound.literalType = literalType;
|
||||||
tmp->compound.nodes = NULL;
|
tmp->compound.nodes = NULL;
|
||||||
tmp->compound.capacity = 0;
|
tmp->compound.capacity = 0;
|
||||||
@@ -178,16 +207,27 @@ void emitASTNodeCompound(ASTNode** nodeHandle, LiteralType literalType) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
void setASTNodePair(ASTNode* node, ASTNode* left, ASTNode* right) {
|
void setASTNodePair(ASTNode* node, ASTNode* left, ASTNode* right) {
|
||||||
//assume the node has already been allocated
|
//set - assume the node has already been allocated
|
||||||
node->type = AST_NODEPAIR;
|
node->type = AST_NODE_PAIR;
|
||||||
node->pair.left = left;
|
node->pair.left = left;
|
||||||
node->pair.right = right;
|
node->pair.right = right;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void emitASTNodeIndex(ASTNode** nodeHandle, ASTNode* first, ASTNode* second, ASTNode* third) {
|
||||||
|
ASTNode* tmp = ALLOCATE(ASTNode, 1);
|
||||||
|
|
||||||
|
tmp->type = AST_NODE_INDEX;
|
||||||
|
tmp->index.first = first;
|
||||||
|
tmp->index.second = second;
|
||||||
|
tmp->index.third = third;
|
||||||
|
|
||||||
|
*nodeHandle = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
void emitASTNodeVarDecl(ASTNode** nodeHandle, Literal identifier, Literal typeLiteral, ASTNode* expression) {
|
void emitASTNodeVarDecl(ASTNode** nodeHandle, Literal identifier, Literal typeLiteral, ASTNode* expression) {
|
||||||
ASTNode* tmp = ALLOCATE(ASTNode, 1);
|
ASTNode* tmp = ALLOCATE(ASTNode, 1);
|
||||||
|
|
||||||
tmp->type = AST_NODEVAR_DECL;
|
tmp->type = AST_NODE_VAR_DECL;
|
||||||
tmp->varDecl.identifier = identifier;
|
tmp->varDecl.identifier = identifier;
|
||||||
tmp->varDecl.typeLiteral = typeLiteral;
|
tmp->varDecl.typeLiteral = typeLiteral;
|
||||||
tmp->varDecl.expression = expression;
|
tmp->varDecl.expression = expression;
|
||||||
@@ -195,10 +235,21 @@ void emitASTNodeVarDecl(ASTNode** nodeHandle, Literal identifier, Literal typeLi
|
|||||||
*nodeHandle = tmp;
|
*nodeHandle = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void emitASTNodeFnCollection(ASTNode** nodeHandle) { //a collection of nodes, intended for use with functions
|
||||||
|
ASTNode* tmp = ALLOCATE(ASTNode, 1);
|
||||||
|
|
||||||
|
tmp->type = AST_NODE_FN_COLLECTION;
|
||||||
|
tmp->fnCollection.nodes = NULL;
|
||||||
|
tmp->fnCollection.capacity = 0;
|
||||||
|
tmp->fnCollection.count = 0;
|
||||||
|
|
||||||
|
*nodeHandle = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
void emitASTNodeFnDecl(ASTNode** nodeHandle, Literal identifier, ASTNode* arguments, ASTNode* returns, ASTNode* block) {
|
void emitASTNodeFnDecl(ASTNode** nodeHandle, Literal identifier, ASTNode* arguments, ASTNode* returns, ASTNode* block) {
|
||||||
ASTNode* tmp = ALLOCATE(ASTNode, 1);
|
ASTNode* tmp = ALLOCATE(ASTNode, 1);
|
||||||
|
|
||||||
tmp->type = AST_NODEFN_DECL;
|
tmp->type = AST_NODE_FN_DECL;
|
||||||
tmp->fnDecl.identifier = identifier;
|
tmp->fnDecl.identifier = identifier;
|
||||||
tmp->fnDecl.arguments = arguments;
|
tmp->fnDecl.arguments = arguments;
|
||||||
tmp->fnDecl.returns = returns;
|
tmp->fnDecl.returns = returns;
|
||||||
@@ -210,85 +261,123 @@ void emitASTNodeFnDecl(ASTNode** nodeHandle, Literal identifier, ASTNode* argume
|
|||||||
void emitASTFnCall(ASTNode** nodeHandle, ASTNode* arguments, int argumentCount) {
|
void emitASTFnCall(ASTNode** nodeHandle, ASTNode* arguments, int argumentCount) {
|
||||||
ASTNode* tmp = ALLOCATE(ASTNode, 1);
|
ASTNode* tmp = ALLOCATE(ASTNode, 1);
|
||||||
|
|
||||||
tmp->type = AST_NODEFN_CALL;
|
tmp->type = AST_NODE_FN_CALL;
|
||||||
tmp->fnCall.arguments = arguments;
|
tmp->fnCall.arguments = arguments;
|
||||||
tmp->fnCall.argumentCount = argumentCount;
|
tmp->fnCall.argumentCount = argumentCount;
|
||||||
|
|
||||||
*nodeHandle = tmp;
|
*nodeHandle = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void emitASTNodeFnCollection(ASTNode** nodeHandle) { //a collection of nodes, intended for use with functions
|
void emitASTNodeFnReturn(ASTNode** nodeHandle, ASTNode* returns) {
|
||||||
ASTNode* tmp = ALLOCATE(ASTNode, 1);
|
ASTNode* tmp = ALLOCATE(ASTNode, 1);
|
||||||
|
|
||||||
tmp->type = AST_NODEFN_COLLECTION;
|
tmp->type = AST_NODE_FN_RETURN;
|
||||||
tmp->fnCollection.nodes = NULL;
|
tmp->returns.returns = returns;
|
||||||
tmp->fnCollection.capacity = 0;
|
|
||||||
tmp->fnCollection.count = 0;
|
|
||||||
|
|
||||||
*nodeHandle = tmp;
|
*nodeHandle = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void emitASTNodePath(ASTNode** nodeHandle, ASTNodeType type, ASTNode* preClause, ASTNode* postClause, ASTNode* condition, ASTNode* thenPath, ASTNode* elsePath) {
|
void emitASTNodeIf(ASTNode** nodeHandle, ASTNode* condition, ASTNode* thenPath, ASTNode* elsePath) {
|
||||||
ASTNode* tmp = ALLOCATE(ASTNode, 1);
|
ASTNode* tmp = ALLOCATE(ASTNode, 1);
|
||||||
|
|
||||||
tmp->type = type;
|
tmp->type = AST_NODE_IF;
|
||||||
tmp->path.preClause = preClause;
|
tmp->pathIf.condition = condition;
|
||||||
tmp->path.postClause = postClause;
|
tmp->pathIf.thenPath = thenPath;
|
||||||
tmp->path.condition = condition;
|
tmp->pathIf.elsePath = elsePath;
|
||||||
tmp->path.thenPath = thenPath;
|
|
||||||
tmp->path.elsePath = elsePath;
|
|
||||||
|
|
||||||
*nodeHandle = tmp;
|
*nodeHandle = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void emitASTNodePrefixIncrement(ASTNode** nodeHandle, Literal identifier, int increment) {
|
void emitASTNodeWhile(ASTNode** nodeHandle, ASTNode* condition, ASTNode* thenPath) {
|
||||||
ASTNode* tmp = ALLOCATE(ASTNode, 1);
|
ASTNode* tmp = ALLOCATE(ASTNode, 1);
|
||||||
|
|
||||||
tmp->type = AST_NODEINCREMENT_PREFIX;
|
tmp->type = AST_NODE_WHILE;
|
||||||
tmp->increment.identifier = copyLiteral(identifier);
|
tmp->pathWhile.condition = condition;
|
||||||
tmp->increment.increment = increment;
|
tmp->pathWhile.thenPath = thenPath;
|
||||||
|
|
||||||
*nodeHandle = tmp;
|
*nodeHandle = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void emitASTNodePostfixIncrement(ASTNode** nodeHandle, Literal identifier, int increment) {
|
void emitASTNodeFor(ASTNode** nodeHandle, ASTNode* preClause, ASTNode* condition, ASTNode* postClause, ASTNode* thenPath) {
|
||||||
ASTNode* tmp = ALLOCATE(ASTNode, 1);
|
ASTNode* tmp = ALLOCATE(ASTNode, 1);
|
||||||
|
|
||||||
tmp->type = AST_NODEINCREMENT_POSTFIX;
|
tmp->type = AST_NODE_FOR;
|
||||||
tmp->increment.identifier = copyLiteral(identifier);
|
tmp->pathFor.preClause = preClause;
|
||||||
tmp->increment.increment = increment;
|
tmp->pathFor.condition = condition;
|
||||||
|
tmp->pathFor.postClause = postClause;
|
||||||
|
tmp->pathFor.thenPath = thenPath;
|
||||||
|
|
||||||
*nodeHandle = tmp;
|
*nodeHandle = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void emitASTNodeImport(ASTNode** nodeHandle, ASTNodeType mode, Literal identifier, Literal alias) {
|
void emitASTNodeBreak(ASTNode** nodeHandle) {
|
||||||
ASTNode* tmp = ALLOCATE(ASTNode, 1);
|
ASTNode* tmp = ALLOCATE(ASTNode, 1);
|
||||||
|
|
||||||
tmp->type = mode;
|
tmp->type = AST_NODE_BREAK;
|
||||||
|
|
||||||
|
*nodeHandle = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void emitASTNodeContinue(ASTNode** nodeHandle) {
|
||||||
|
ASTNode* tmp = ALLOCATE(ASTNode, 1);
|
||||||
|
|
||||||
|
tmp->type = AST_NODE_CONTINUE;
|
||||||
|
|
||||||
|
*nodeHandle = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void emitASTNodePrefixIncrement(ASTNode** nodeHandle, Literal identifier) {
|
||||||
|
ASTNode* tmp = ALLOCATE(ASTNode, 1);
|
||||||
|
|
||||||
|
tmp->type = AST_NODE_PREFIX_INCREMENT;
|
||||||
|
tmp->prefixIncrement.identifier = copyLiteral(identifier);
|
||||||
|
|
||||||
|
*nodeHandle = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void emitASTNodePrefixDecrement(ASTNode** nodeHandle, Literal identifier) {
|
||||||
|
ASTNode* tmp = ALLOCATE(ASTNode, 1);
|
||||||
|
|
||||||
|
tmp->type = AST_NODE_PREFIX_DECREMENT;
|
||||||
|
tmp->prefixDecrement.identifier = copyLiteral(identifier);
|
||||||
|
|
||||||
|
*nodeHandle = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void emitASTNodePostfixIncrement(ASTNode** nodeHandle, Literal identifier) {
|
||||||
|
ASTNode* tmp = ALLOCATE(ASTNode, 1);
|
||||||
|
|
||||||
|
tmp->type = AST_NODE_POSTFIX_INCREMENT;
|
||||||
|
tmp->postfixIncrement.identifier = copyLiteral(identifier);
|
||||||
|
|
||||||
|
*nodeHandle = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void emitASTNodePostfixDecrement(ASTNode** nodeHandle, Literal identifier) {
|
||||||
|
ASTNode* tmp = ALLOCATE(ASTNode, 1);
|
||||||
|
|
||||||
|
tmp->type = AST_NODE_POSTFIX_DECREMENT;
|
||||||
|
tmp->postfixDecrement.identifier = copyLiteral(identifier);
|
||||||
|
|
||||||
|
*nodeHandle = tmp;
|
||||||
|
}
|
||||||
|
|
||||||
|
void emitASTNodeImport(ASTNode** nodeHandle, Literal identifier, Literal alias) {
|
||||||
|
ASTNode* tmp = ALLOCATE(ASTNode, 1);
|
||||||
|
|
||||||
|
tmp->type = AST_NODE_IMPORT;
|
||||||
tmp->import.identifier = copyLiteral(identifier);
|
tmp->import.identifier = copyLiteral(identifier);
|
||||||
tmp->import.alias = copyLiteral(alias);
|
tmp->import.alias = copyLiteral(alias);
|
||||||
|
|
||||||
*nodeHandle = tmp;
|
*nodeHandle = tmp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void emitASTNodeIndex(ASTNode** nodeHandle, ASTNode* first, ASTNode* second, ASTNode* third) {
|
void emitASTNodeExport(ASTNode** nodeHandle, Literal identifier, Literal alias) {
|
||||||
ASTNode* tmp = ALLOCATE(ASTNode, 1);
|
ASTNode* tmp = ALLOCATE(ASTNode, 1);
|
||||||
|
|
||||||
tmp->type = AST_NODEINDEX;
|
tmp->type = AST_NODE_EXPORT;
|
||||||
tmp->index.first = first;
|
tmp->export.identifier = copyLiteral(identifier);
|
||||||
tmp->index.second = second;
|
tmp->export.alias = copyLiteral(alias);
|
||||||
tmp->index.third = third;
|
|
||||||
|
|
||||||
*nodeHandle = tmp;
|
|
||||||
}
|
|
||||||
|
|
||||||
void emitASTNodeDot(ASTNode** nodeHandle, ASTNode* first) {
|
|
||||||
ASTNode* tmp = ALLOCATE(ASTNode, 1);
|
|
||||||
|
|
||||||
tmp->type = AST_NODEDOT;
|
|
||||||
tmp->index.first = first;
|
|
||||||
tmp->index.second = NULL;
|
|
||||||
tmp->index.third = NULL;
|
|
||||||
|
|
||||||
*nodeHandle = tmp;
|
*nodeHandle = tmp;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,43 +9,53 @@
|
|||||||
typedef union _node ASTNode;
|
typedef union _node ASTNode;
|
||||||
|
|
||||||
typedef enum ASTNodeType {
|
typedef enum ASTNodeType {
|
||||||
AST_NODEERROR,
|
AST_NODE_ERROR,
|
||||||
AST_NODELITERAL, //a simple value
|
AST_NODE_LITERAL, //a simple value
|
||||||
AST_NODEUNARY, //one child + opcode
|
AST_NODE_UNARY, //one child + opcode
|
||||||
AST_NODEBINARY, //two children, left and right + opcode
|
AST_NODE_BINARY, //two children, left and right + opcode
|
||||||
AST_NODEGROUPING, //one child
|
AST_NODE_GROUPING, //one child
|
||||||
AST_NODEBLOCK, //contains a sub-node array
|
AST_NODE_BLOCK, //contains a sub-node array
|
||||||
AST_NODECOMPOUND, //contains a sub-node array
|
AST_NODE_COMPOUND, //contains a sub-node array
|
||||||
AST_NODEPAIR, //contains a left and right
|
AST_NODE_PAIR, //contains a left and right
|
||||||
AST_NODEVAR_DECL, //contains identifier literal, typenode, expression definition
|
AST_NODE_INDEX, //index a variable
|
||||||
AST_NODEFN_DECL, //containd identifier literal, arguments node, returns node, block node
|
AST_NODE_VAR_DECL, //contains identifier literal, typenode, expression definition
|
||||||
AST_NODEFN_COLLECTION, //parts of a function
|
AST_NODE_FN_DECL, //containd identifier literal, arguments node, returns node, block node
|
||||||
AST_NODEFN_CALL,
|
AST_NODE_FN_COLLECTION, //parts of a function
|
||||||
AST_NODEPATH_IF, //for control flow
|
AST_NODE_FN_CALL, //call a function
|
||||||
AST_NODEPATH_WHILE, //for control flow
|
AST_NODE_FN_RETURN, //for control flow
|
||||||
AST_NODEPATH_FOR, //for control flow
|
AST_NODE_IF, //for control flow
|
||||||
AST_NODEPATH_BREAK, //for control flow
|
AST_NODE_WHILE, //for control flow
|
||||||
AST_NODEPATH_CONTINUE, //for control flow
|
AST_NODE_FOR, //for control flow
|
||||||
AST_NODEPATH_RETURN,
|
AST_NODE_BREAK, //for control flow
|
||||||
AST_NODEINCREMENT_PREFIX,
|
AST_NODE_CONTINUE, //for control flow
|
||||||
AST_NODEINCREMENT_POSTFIX,
|
AST_NODE_PREFIX_INCREMENT, //increment a variable
|
||||||
AST_NODEIMPORT,
|
AST_NODE_POSTFIX_INCREMENT, //increment a variable
|
||||||
AST_NODEEXPORT,
|
AST_NODE_PREFIX_DECREMENT, //decrement a variable
|
||||||
AST_NODEINDEX,
|
AST_NODE_POSTFIX_DECREMENT, //decrement a variable
|
||||||
AST_NODEDOT,
|
AST_NODE_IMPORT, //import a variable
|
||||||
|
AST_NODE_EXPORT, //export a variable
|
||||||
} ASTNodeType;
|
} ASTNodeType;
|
||||||
|
|
||||||
|
//literals
|
||||||
|
void emitASTNodeLiteral(ASTNode** nodeHandle, Literal literal);
|
||||||
|
|
||||||
typedef struct NodeLiteral {
|
typedef struct NodeLiteral {
|
||||||
ASTNodeType type;
|
ASTNodeType type;
|
||||||
Literal literal;
|
Literal literal;
|
||||||
} NodeLiteral;
|
} NodeLiteral;
|
||||||
|
|
||||||
|
//unary operator
|
||||||
|
void emitASTNodeUnary(ASTNode** nodeHandle, Opcode opcode, ASTNode* child);
|
||||||
|
|
||||||
typedef struct NodeUnary {
|
typedef struct NodeUnary {
|
||||||
ASTNodeType type;
|
ASTNodeType type;
|
||||||
Opcode opcode;
|
Opcode opcode;
|
||||||
ASTNode* child;
|
ASTNode* child;
|
||||||
} NodeUnary;
|
} NodeUnary;
|
||||||
|
|
||||||
|
//binary operator
|
||||||
|
void emitASTNodeBinary(ASTNode** nodeHandle, ASTNode* rhs, Opcode opcode); //handled node becomes lhs
|
||||||
|
|
||||||
typedef struct NodeBinary {
|
typedef struct NodeBinary {
|
||||||
ASTNodeType type;
|
ASTNodeType type;
|
||||||
Opcode opcode;
|
Opcode opcode;
|
||||||
@@ -53,11 +63,17 @@ typedef struct NodeBinary {
|
|||||||
ASTNode* right;
|
ASTNode* right;
|
||||||
} NodeBinary;
|
} NodeBinary;
|
||||||
|
|
||||||
|
//grouping of other AST nodes
|
||||||
|
void emitASTNodeGrouping(ASTNode** nodeHandle);
|
||||||
|
|
||||||
typedef struct NodeGrouping {
|
typedef struct NodeGrouping {
|
||||||
ASTNodeType type;
|
ASTNodeType type;
|
||||||
ASTNode* child;
|
ASTNode* child;
|
||||||
} NodeGrouping;
|
} NodeGrouping;
|
||||||
|
|
||||||
|
//block of statement nodes
|
||||||
|
void emitASTNodeBlock(ASTNode** nodeHandle);
|
||||||
|
|
||||||
typedef struct NodeBlock {
|
typedef struct NodeBlock {
|
||||||
ASTNodeType type;
|
ASTNodeType type;
|
||||||
ASTNode* nodes;
|
ASTNode* nodes;
|
||||||
@@ -65,6 +81,9 @@ typedef struct NodeBlock {
|
|||||||
int count;
|
int count;
|
||||||
} NodeBlock;
|
} NodeBlock;
|
||||||
|
|
||||||
|
//compound literals (array, dictionary)
|
||||||
|
void emitASTNodeCompound(ASTNode** nodeHandle, LiteralType literalType);
|
||||||
|
|
||||||
typedef struct NodeCompound {
|
typedef struct NodeCompound {
|
||||||
ASTNodeType type;
|
ASTNodeType type;
|
||||||
LiteralType literalType;
|
LiteralType literalType;
|
||||||
@@ -73,12 +92,26 @@ typedef struct NodeCompound {
|
|||||||
int count;
|
int count;
|
||||||
} NodeCompound;
|
} NodeCompound;
|
||||||
|
|
||||||
|
void setASTNodePair(ASTNode* node, ASTNode* left, ASTNode* right); //NOTE: this is a set function, not an emit function
|
||||||
|
|
||||||
typedef struct NodePair {
|
typedef struct NodePair {
|
||||||
ASTNodeType type;
|
ASTNodeType type;
|
||||||
ASTNode* left;
|
ASTNode* left;
|
||||||
ASTNode* right;
|
ASTNode* right;
|
||||||
} NodePair;
|
} NodePair;
|
||||||
|
|
||||||
|
void emitASTNodeIndex(ASTNode** nodeHandle, ASTNode* first, ASTNode* second, ASTNode* third);
|
||||||
|
|
||||||
|
typedef struct NodeIndex {
|
||||||
|
ASTNodeType type;
|
||||||
|
ASTNode* first;
|
||||||
|
ASTNode* second;
|
||||||
|
ASTNode* third;
|
||||||
|
} NodeIndex;
|
||||||
|
|
||||||
|
//variable declaration
|
||||||
|
void emitASTNodeVarDecl(ASTNode** nodeHandle, Literal identifier, Literal type, ASTNode* expression);
|
||||||
|
|
||||||
typedef struct NodeVarDecl {
|
typedef struct NodeVarDecl {
|
||||||
ASTNodeType type;
|
ASTNodeType type;
|
||||||
Literal identifier;
|
Literal identifier;
|
||||||
@@ -86,6 +119,19 @@ typedef struct NodeVarDecl {
|
|||||||
ASTNode* expression;
|
ASTNode* expression;
|
||||||
} NodeVarDecl;
|
} NodeVarDecl;
|
||||||
|
|
||||||
|
//NOTE: fnCollection is used by fnDecl, fnCall and fnReturn
|
||||||
|
void emitASTNodeFnCollection(ASTNode** nodeHandle);
|
||||||
|
|
||||||
|
typedef struct NodeFnCollection {
|
||||||
|
ASTNodeType type;
|
||||||
|
ASTNode* nodes;
|
||||||
|
int capacity;
|
||||||
|
int count;
|
||||||
|
} NodeFnCollection;
|
||||||
|
|
||||||
|
//function declaration
|
||||||
|
void emitASTNodeFnDecl(ASTNode** nodeHandle, Literal identifier, ASTNode* arguments, ASTNode* returns, ASTNode* block);
|
||||||
|
|
||||||
typedef struct NodeFnDecl {
|
typedef struct NodeFnDecl {
|
||||||
ASTNodeType type;
|
ASTNodeType type;
|
||||||
Literal identifier;
|
Literal identifier;
|
||||||
@@ -94,12 +140,8 @@ typedef struct NodeFnDecl {
|
|||||||
ASTNode* block;
|
ASTNode* block;
|
||||||
} NodeFnDecl;
|
} NodeFnDecl;
|
||||||
|
|
||||||
typedef struct NodeFnCollection {
|
//function call
|
||||||
ASTNodeType type;
|
void emitASTFnCall(ASTNode** nodeHandle, ASTNode* arguments, int argumentCount);
|
||||||
ASTNode* nodes;
|
|
||||||
int capacity;
|
|
||||||
int count;
|
|
||||||
} NodeFnCollection;
|
|
||||||
|
|
||||||
typedef struct NodeFnCall {
|
typedef struct NodeFnCall {
|
||||||
ASTNodeType type;
|
ASTNodeType type;
|
||||||
@@ -107,20 +149,79 @@ typedef struct NodeFnCall {
|
|||||||
int argumentCount;
|
int argumentCount;
|
||||||
} NodeFnCall;
|
} NodeFnCall;
|
||||||
|
|
||||||
typedef struct NodePath {
|
//function return
|
||||||
|
void emitASTFnReturn(ASTNode* nodeHandle, ASTNode* returns);
|
||||||
|
|
||||||
|
typedef struct NodeFnReturn {
|
||||||
|
ASTNodeType type;
|
||||||
|
ASTNode* returns;
|
||||||
|
} NodeFnReturn;
|
||||||
|
|
||||||
|
//control flow path - if-else, while, for, break, continue, return
|
||||||
|
void emitASTNodeIf(ASTNode** nodeHandle, ASTNode* condition, ASTNode* thenPath, ASTNode* elsePath);
|
||||||
|
void emitASTNodeWhile(ASTNode** nodeHandle, ASTNode* condition, ASTNode* thenPath);
|
||||||
|
void emitASTNodeFor(ASTNode** nodeHandle, ASTNode* preClause, ASTNode* condition, ASTNode* postClause, ASTNode* thenPath);
|
||||||
|
void emitASTNodeBreak(ASTNode** nodeHandle);
|
||||||
|
void emitASTNodeContinue(ASTNode** nodeHandle);
|
||||||
|
|
||||||
|
typedef struct NodeIf {
|
||||||
ASTNodeType type;
|
ASTNodeType type;
|
||||||
ASTNode* preClause;
|
|
||||||
ASTNode* postClause;
|
|
||||||
ASTNode* condition;
|
ASTNode* condition;
|
||||||
ASTNode* thenPath;
|
ASTNode* thenPath;
|
||||||
ASTNode* elsePath;
|
ASTNode* elsePath;
|
||||||
} NodePath;
|
} NodeIf;
|
||||||
|
|
||||||
typedef struct NodeIncrement {
|
typedef struct NodeWhile {
|
||||||
|
ASTNodeType type;
|
||||||
|
ASTNode* condition;
|
||||||
|
ASTNode* thenPath;
|
||||||
|
} NodeWhile;
|
||||||
|
|
||||||
|
typedef struct NodeFor {
|
||||||
|
ASTNodeType type;
|
||||||
|
ASTNode* preClause;
|
||||||
|
ASTNode* condition;
|
||||||
|
ASTNode* postClause;
|
||||||
|
ASTNode* thenPath;
|
||||||
|
} NodeFor;
|
||||||
|
|
||||||
|
typedef struct NodeBreak {
|
||||||
|
ASTNodeType type;
|
||||||
|
} NodeBreak;
|
||||||
|
|
||||||
|
typedef struct NodeContinue {
|
||||||
|
ASTNodeType type;
|
||||||
|
} NodeContinue;
|
||||||
|
|
||||||
|
//pre-post increment/decrement
|
||||||
|
void emitASTNodePrefixIncrement(ASTNode** nodeHandle, Literal identifier);
|
||||||
|
void emitASTNodePrefixDecrement(ASTNode** nodeHandle, Literal identifier);
|
||||||
|
void emitASTNodePostfixIncrement(ASTNode** nodeHandle, Literal identifier);
|
||||||
|
void emitASTNodePostfixDecrement(ASTNode** nodeHandle, Literal identifier);
|
||||||
|
|
||||||
|
typedef struct NodePrefixIncrement {
|
||||||
ASTNodeType type;
|
ASTNodeType type;
|
||||||
Literal identifier;
|
Literal identifier;
|
||||||
int increment;
|
} NodePrefixIncrement;
|
||||||
} NodeIncrement;
|
|
||||||
|
typedef struct NodePrefixDecrement {
|
||||||
|
ASTNodeType type;
|
||||||
|
Literal identifier;
|
||||||
|
} NodePrefixDecrement;
|
||||||
|
|
||||||
|
typedef struct NodePostfixIncrement {
|
||||||
|
ASTNodeType type;
|
||||||
|
Literal identifier;
|
||||||
|
} NodePostfixIncrement;
|
||||||
|
|
||||||
|
typedef struct NodePostfixDecrement {
|
||||||
|
ASTNodeType type;
|
||||||
|
Literal identifier;
|
||||||
|
} NodePostfixDecrement;
|
||||||
|
|
||||||
|
//import/export a variable
|
||||||
|
void emitASTNodeImport(ASTNode** nodeHandle, Literal identifier, Literal alias);
|
||||||
|
void emitASTNodeExport(ASTNode** nodeHandle, Literal identifier, Literal alias);
|
||||||
|
|
||||||
typedef struct NodeImport {
|
typedef struct NodeImport {
|
||||||
ASTNodeType type;
|
ASTNodeType type;
|
||||||
@@ -128,12 +229,11 @@ typedef struct NodeImport {
|
|||||||
Literal alias;
|
Literal alias;
|
||||||
} NodeImport;
|
} NodeImport;
|
||||||
|
|
||||||
typedef struct NodeIndex {
|
typedef struct NodeExport {
|
||||||
ASTNodeType type;
|
ASTNodeType type;
|
||||||
ASTNode* first;
|
Literal identifier;
|
||||||
ASTNode* second;
|
Literal alias;
|
||||||
ASTNode* third;
|
} NodeExport;
|
||||||
} NodeIndex;
|
|
||||||
|
|
||||||
union _node {
|
union _node {
|
||||||
ASTNodeType type;
|
ASTNodeType type;
|
||||||
@@ -144,32 +244,23 @@ union _node {
|
|||||||
NodeBlock block;
|
NodeBlock block;
|
||||||
NodeCompound compound;
|
NodeCompound compound;
|
||||||
NodePair pair;
|
NodePair pair;
|
||||||
NodeVarDecl varDecl;
|
|
||||||
NodeFnDecl fnDecl;
|
|
||||||
NodeFnCollection fnCollection;
|
|
||||||
NodeFnCall fnCall;
|
|
||||||
NodePath path;
|
|
||||||
NodeIncrement increment;
|
|
||||||
NodeImport import;
|
|
||||||
NodeIndex index;
|
NodeIndex index;
|
||||||
|
NodeVarDecl varDecl;
|
||||||
|
NodeFnCollection fnCollection;
|
||||||
|
NodeFnDecl fnDecl;
|
||||||
|
NodeFnCall fnCall;
|
||||||
|
NodeFnReturn returns;
|
||||||
|
NodeIf pathIf;
|
||||||
|
NodeWhile pathWhile;
|
||||||
|
NodeFor pathFor;
|
||||||
|
NodeBreak pathBreak;
|
||||||
|
NodeContinue pathContinue;
|
||||||
|
NodePrefixIncrement prefixIncrement;
|
||||||
|
NodePrefixDecrement prefixDecrement;
|
||||||
|
NodePostfixIncrement postfixIncrement;
|
||||||
|
NodePostfixDecrement postfixDecrement;
|
||||||
|
NodeImport import;
|
||||||
|
NodeExport export;
|
||||||
};
|
};
|
||||||
|
|
||||||
TOY_API void freeNode(ASTNode* node);
|
TOY_API void freeASTNode(ASTNode* node);
|
||||||
|
|
||||||
void emitASTNodeLiteral(ASTNode** nodeHandle, Literal literal);
|
|
||||||
void emitASTNodeUnary(ASTNode** nodeHandle, Opcode opcode, ASTNode* child);
|
|
||||||
void emitASTNodeBinary(ASTNode** nodeHandle, ASTNode* rhs, Opcode opcode); //handled node becomes lhs
|
|
||||||
void emitASTNodeGrouping(ASTNode** nodeHandle);
|
|
||||||
void emitASTNodeBlock(ASTNode** nodeHandle);
|
|
||||||
void emitASTNodeCompound(ASTNode** nodeHandle, LiteralType literalType);
|
|
||||||
void setASTNodePair(ASTNode* node, ASTNode* left, ASTNode* right);
|
|
||||||
void emitASTNodeVarDecl(ASTNode** nodeHandle, Literal identifier, Literal type, ASTNode* expression);
|
|
||||||
void emitASTNodeFnDecl(ASTNode** nodeHandle, Literal identifier, ASTNode* arguments, ASTNode* returns, ASTNode* block);
|
|
||||||
void emitASTFnCall(ASTNode** nodeHandle, ASTNode* arguments, int argumentCount);
|
|
||||||
void emitASTNodeFnCollection(ASTNode** nodeHandle);
|
|
||||||
void emitASTNodePath(ASTNode** nodeHandle, ASTNodeType type, ASTNode* preClause, ASTNode* postClause, ASTNode* condition, ASTNode* thenPath, ASTNode* elsePath);
|
|
||||||
void emitASTNodePrefixIncrement(ASTNode** nodeHandle, Literal identifier, int increment);
|
|
||||||
void emitASTNodePostfixIncrement(ASTNode** nodeHandle, Literal identifier, int increment);
|
|
||||||
void emitASTNodeImport(ASTNode** nodeHandle, ASTNodeType mode, Literal identifier, Literal alias);
|
|
||||||
void emitASTNodeIndex(ASTNode** nodeHandle, ASTNode* first, ASTNode* second, ASTNode* third);
|
|
||||||
void emitASTNodeDot(ASTNode** nodeHandle, ASTNode* first);
|
|
||||||
|
|||||||
@@ -1170,7 +1170,7 @@ static void blockStmt(Parser* parser, ASTNode** nodeHandle) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
//BUGFIX: statements no longer require an existing node
|
//BUGFIX: statements no longer require the existing node
|
||||||
((*nodeHandle)->block.nodes[(*nodeHandle)->block.count++]) = *node;
|
((*nodeHandle)->block.nodes[(*nodeHandle)->block.count++]) = *node;
|
||||||
FREE(ASTNode, node); //simply free the tmp node
|
FREE(ASTNode, node); //simply free the tmp node
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -21,6 +21,10 @@ void setRefStringAllocatorFn(RefStringAllocatorFn allocator) {
|
|||||||
RefString* createRefString(char* cstring) {
|
RefString* createRefString(char* cstring) {
|
||||||
int length = strlen(cstring);
|
int length = strlen(cstring);
|
||||||
|
|
||||||
|
return createRefStringLength(cstring, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
RefString* createRefStringLength(char* cstring, int length) {
|
||||||
//allocate the memory area (including metadata space)
|
//allocate the memory area (including metadata space)
|
||||||
RefString* refString = (RefString*)allocate(NULL, 0, sizeof(int) * 2 + sizeof(char) * length + 1);
|
RefString* refString = (RefString*)allocate(NULL, 0, sizeof(int) * 2 + sizeof(char) * length + 1);
|
||||||
|
|
||||||
@@ -84,3 +88,16 @@ bool equalsRefString(RefString* lhs, RefString* rhs) {
|
|||||||
//same string
|
//same string
|
||||||
return strncmp(lhs->data, rhs->data, lhs->length) == 0;
|
return strncmp(lhs->data, rhs->data, lhs->length) == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool equalsRefStringCString(RefString* lhs, char* cstring) {
|
||||||
|
//get the rhs length
|
||||||
|
int length = strlen(cstring);
|
||||||
|
|
||||||
|
//different length
|
||||||
|
if (lhs->length != length) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//same string
|
||||||
|
return strncmp(lhs->data, cstring, lhs->length) == 0;
|
||||||
|
}
|
||||||
@@ -16,6 +16,7 @@ typedef struct RefString {
|
|||||||
|
|
||||||
//API
|
//API
|
||||||
RefString* createRefString(char* cstring);
|
RefString* createRefString(char* cstring);
|
||||||
|
RefString* createRefStringLength(char* cstring, int length);
|
||||||
void deleteRefString(RefString* refString);
|
void deleteRefString(RefString* refString);
|
||||||
int countRefString(RefString* refString);
|
int countRefString(RefString* refString);
|
||||||
int lengthRefString(RefString* refString);
|
int lengthRefString(RefString* refString);
|
||||||
@@ -23,3 +24,4 @@ RefString* copyRefString(RefString* refString);
|
|||||||
RefString* deepCopyRefString(RefString* refString);
|
RefString* deepCopyRefString(RefString* refString);
|
||||||
char* toCString(RefString* refString);
|
char* toCString(RefString* refString);
|
||||||
bool equalsRefString(RefString* lhs, RefString* rhs);
|
bool equalsRefString(RefString* lhs, RefString* rhs);
|
||||||
|
bool equalsRefStringCString(RefString* lhs, char* cstring);
|
||||||
|
|||||||
@@ -7,12 +7,15 @@ LIBS +=
|
|||||||
ODIR = obj
|
ODIR = obj
|
||||||
#TARGETS = $(wildcard ../source/*.c) $(wildcard ../repl/lib_*.c)
|
#TARGETS = $(wildcard ../source/*.c) $(wildcard ../repl/lib_*.c)
|
||||||
|
|
||||||
#literal primitive
|
#literal primitives
|
||||||
TARGETS+=../source/memory.c ../source/refstring.c ../source/literal.c ../source/literal_array.c ../source/literal_dictionary.c ../source/scope.c
|
TARGETS+=../source/memory.c ../source/refstring.c ../source/literal.c ../source/literal_array.c ../source/literal_dictionary.c ../source/scope.c
|
||||||
|
|
||||||
#lexer
|
#lexer
|
||||||
TARGETS+=../source/toy_common.c ../source/keyword_types.c ../source/lexer.c
|
TARGETS+=../source/toy_common.c ../source/keyword_types.c ../source/lexer.c
|
||||||
|
|
||||||
|
#ast primitives
|
||||||
|
TARGETS+=../source/ast_node.c
|
||||||
|
|
||||||
#parser
|
#parser
|
||||||
#TARGETS+=
|
#TARGETS+=
|
||||||
|
|
||||||
|
|||||||
116
test/test_ast_node.c
Normal file
116
test/test_ast_node.c
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
#include "ast_node.h"
|
||||||
|
|
||||||
|
#include "memory.h"
|
||||||
|
#include "console_colors.h"
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
//lazy
|
||||||
|
#define ASSERT(test_for_true) if (!(test_for_true)) {\
|
||||||
|
fprintf(stderr, ERROR "assert failed: %s\n" RESET, #test_for_true); \
|
||||||
|
exit(-1); \
|
||||||
|
}
|
||||||
|
|
||||||
|
int main() {
|
||||||
|
//test literals
|
||||||
|
{
|
||||||
|
//test literals
|
||||||
|
char* str = "foobar";
|
||||||
|
Literal literal = TO_STRING_LITERAL(createRefString(str));
|
||||||
|
|
||||||
|
//generate the node
|
||||||
|
ASTNode* node = NULL;
|
||||||
|
emitASTNodeLiteral(&node, literal);
|
||||||
|
|
||||||
|
//check node type
|
||||||
|
ASSERT(node->type == AST_NODE_LITERAL);
|
||||||
|
|
||||||
|
//cleanup
|
||||||
|
freeLiteral(literal);
|
||||||
|
freeASTNode(node);
|
||||||
|
}
|
||||||
|
|
||||||
|
//test unary
|
||||||
|
{
|
||||||
|
//generate the child node
|
||||||
|
char* str = "foobar";
|
||||||
|
Literal literal = TO_STRING_LITERAL(createRefString(str));
|
||||||
|
ASTNode* childNode = NULL;
|
||||||
|
emitASTNodeLiteral(&childNode, literal);
|
||||||
|
|
||||||
|
//generate the unary node
|
||||||
|
ASTNode* unary = NULL;
|
||||||
|
emitASTNodeUnary(&unary, OP_PRINT, childNode);
|
||||||
|
|
||||||
|
//check node type
|
||||||
|
ASSERT(unary->type == AST_NODE_UNARY);
|
||||||
|
|
||||||
|
//cleanup
|
||||||
|
freeLiteral(literal);
|
||||||
|
freeASTNode(unary);
|
||||||
|
}
|
||||||
|
|
||||||
|
//test binary
|
||||||
|
{
|
||||||
|
//generate the child node
|
||||||
|
char* str = "foobar";
|
||||||
|
Literal literal = TO_STRING_LITERAL(createRefString(str));
|
||||||
|
ASTNode* nodeHandle = NULL;
|
||||||
|
emitASTNodeLiteral(&nodeHandle, literal);
|
||||||
|
|
||||||
|
ASTNode* rhsChildNode = NULL;
|
||||||
|
emitASTNodeLiteral(&rhsChildNode, literal);
|
||||||
|
|
||||||
|
//generate the unary node
|
||||||
|
emitASTNodeBinary(&nodeHandle, rhsChildNode, OP_PRINT);
|
||||||
|
|
||||||
|
//check node type
|
||||||
|
ASSERT(nodeHandle->type == AST_NODE_BINARY);
|
||||||
|
ASSERT(nodeHandle->binary.opcode == OP_PRINT);
|
||||||
|
|
||||||
|
//cleanup
|
||||||
|
freeLiteral(literal);
|
||||||
|
freeASTNode(nodeHandle);
|
||||||
|
}
|
||||||
|
|
||||||
|
//TODO: more tests for other AST node types
|
||||||
|
|
||||||
|
//test compounds
|
||||||
|
{
|
||||||
|
//test compound (dictionary)
|
||||||
|
char* idn = "foobar";
|
||||||
|
char* str = "hello world";
|
||||||
|
|
||||||
|
ASTNode* dictionary;
|
||||||
|
ASTNode* left;
|
||||||
|
ASTNode* right;
|
||||||
|
|
||||||
|
Literal identifier = TO_IDENTIFIER_LITERAL(createRefString(idn));
|
||||||
|
Literal string = TO_STRING_LITERAL(createRefString(str));
|
||||||
|
|
||||||
|
emitASTNodeCompound(&dictionary, LITERAL_DICTIONARY);
|
||||||
|
emitASTNodeLiteral(&left, identifier);
|
||||||
|
emitASTNodeLiteral(&right, string);
|
||||||
|
|
||||||
|
//grow the node if needed
|
||||||
|
if (dictionary->compound.capacity < dictionary->compound.count + 1) {
|
||||||
|
int oldCapacity = dictionary->compound.capacity;
|
||||||
|
|
||||||
|
dictionary->compound.capacity = GROW_CAPACITY(oldCapacity);
|
||||||
|
dictionary->compound.nodes = GROW_ARRAY(ASTNode, dictionary->compound.nodes, oldCapacity, dictionary->compound.capacity);
|
||||||
|
}
|
||||||
|
|
||||||
|
//store the left and right in the node
|
||||||
|
setASTNodePair(&dictionary->compound.nodes[dictionary->compound.count++], left, right);
|
||||||
|
|
||||||
|
//the real test
|
||||||
|
freeASTNode(dictionary);
|
||||||
|
freeLiteral(identifier);
|
||||||
|
freeLiteral(string);
|
||||||
|
}
|
||||||
|
|
||||||
|
printf(NOTICE "All good\n" RESET);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -1,57 +0,0 @@
|
|||||||
#include "ast_node.h"
|
|
||||||
|
|
||||||
#include "memory.h"
|
|
||||||
#include "console_colors.h"
|
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
|
|
||||||
int main() {
|
|
||||||
{
|
|
||||||
//test literals
|
|
||||||
char* str = "foobar";
|
|
||||||
|
|
||||||
Literal literal = TO_STRING_LITERAL(copyString(str, strlen(str)), strlen(str));
|
|
||||||
|
|
||||||
ASTNode* node;
|
|
||||||
emitASTNodeLiteral(&node, literal);
|
|
||||||
freeLiteral(literal);
|
|
||||||
freeNode(node);
|
|
||||||
}
|
|
||||||
|
|
||||||
{
|
|
||||||
//test compound (dictionary)
|
|
||||||
char* idn = "foobar";
|
|
||||||
char* str = "hello world";
|
|
||||||
|
|
||||||
ASTNode* dictionary;
|
|
||||||
ASTNode* left;
|
|
||||||
ASTNode* right;
|
|
||||||
|
|
||||||
Literal identifier = TO_IDENTIFIER_LITERAL(copyString(idn, strlen(idn)), strlen(idn));
|
|
||||||
Literal string = TO_STRING_LITERAL(copyString(str, strlen(str)), strlen(str));
|
|
||||||
|
|
||||||
emitASTNodeCompound(&dictionary, LITERAL_DICTIONARY);
|
|
||||||
emitASTNodeLiteral(&left, identifier);
|
|
||||||
emitASTNodeLiteral(&right, string);
|
|
||||||
|
|
||||||
//grow the node if needed
|
|
||||||
if (dictionary->compound.capacity < dictionary->compound.count + 1) {
|
|
||||||
int oldCapacity = dictionary->compound.capacity;
|
|
||||||
|
|
||||||
dictionary->compound.capacity = GROW_CAPACITY(oldCapacity);
|
|
||||||
dictionary->compound.nodes = GROW_ARRAY(ASTNode, dictionary->compound.nodes, oldCapacity, dictionary->compound.capacity);
|
|
||||||
}
|
|
||||||
|
|
||||||
//store the left and right in the node
|
|
||||||
setASTNodePair(&dictionary->compound.nodes[dictionary->compound.count++], left, right);
|
|
||||||
|
|
||||||
//the real test
|
|
||||||
freeNode(dictionary);
|
|
||||||
freeLiteral(identifier);
|
|
||||||
freeLiteral(string);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf(NOTICE "All good\n" RESET);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
Reference in New Issue
Block a user