Adjusted how AST Nodes are generated

This commit is contained in:
2022-11-25 12:29:35 +00:00
parent 130ac980fe
commit 30c3a890ee
8 changed files with 491 additions and 230 deletions

View File

@@ -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;
} }

View File

@@ -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);

View File

@@ -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
} }

View File

@@ -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;
}

View File

@@ -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);

View File

@@ -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
View 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;
}

View File

@@ -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;
}