diff --git a/source/ast_node.c b/source/ast_node.c index d41922b..fb6284e 100644 --- a/source/ast_node.c +++ b/source/ast_node.c @@ -5,106 +5,134 @@ #include #include -void freeNodeCustom(ASTNode* node, bool freeSelf) { +void freeASTNodeCustom(ASTNode* node, bool freeSelf) { //don't free a NULL node if (node == NULL) { return; } switch(node->type) { - case AST_NODEERROR: + case AST_NODE_ERROR: //NO-OP break; - case AST_NODELITERAL: + case AST_NODE_LITERAL: freeLiteral(node->atomic.literal); break; - case AST_NODEUNARY: - freeNode(node->unary.child); + case AST_NODE_UNARY: + freeASTNode(node->unary.child); break; - case AST_NODEBINARY: - freeNode(node->binary.left); - freeNode(node->binary.right); + case AST_NODE_BINARY: + freeASTNode(node->binary.left); + freeASTNode(node->binary.right); break; - case AST_NODEGROUPING: - freeNode(node->grouping.child); + case AST_NODE_GROUPING: + freeASTNode(node->grouping.child); break; - case AST_NODEBLOCK: + case AST_NODE_BLOCK: 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); break; - case AST_NODECOMPOUND: + case AST_NODE_COMPOUND: 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); break; - case AST_NODEPAIR: - freeNode(node->pair.left); - freeNode(node->pair.right); + case AST_NODE_PAIR: + freeASTNode(node->pair.left); + freeASTNode(node->pair.right); 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.typeLiteral); - freeNode(node->varDecl.expression); + freeASTNode(node->varDecl.expression); break; - case AST_NODEFN_DECL: - freeLiteral(node->fnDecl.identifier); - freeNode(node->fnDecl.arguments); - freeNode(node->fnDecl.returns); - freeNode(node->fnDecl.block); - break; - - case AST_NODEFN_COLLECTION: + case AST_NODE_FN_COLLECTION: 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); break; - case AST_NODEFN_CALL: - freeNode(node->fnCall.arguments); + case AST_NODE_FN_DECL: + freeLiteral(node->fnDecl.identifier); + freeASTNode(node->fnDecl.arguments); + freeASTNode(node->fnDecl.returns); + freeASTNode(node->fnDecl.block); break; - case AST_NODEPATH_IF: - case AST_NODEPATH_WHILE: - 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); + case AST_NODE_FN_CALL: + freeASTNode(node->fnCall.arguments); break; - case AST_NODEINCREMENT_PREFIX: - case AST_NODEINCREMENT_POSTFIX: - freeLiteral(node->increment.identifier); + case AST_NODE_FN_RETURN: + freeASTNode(node->returns.returns); break; - case AST_NODEIMPORT: - case AST_NODEEXPORT: + case AST_NODE_IF: + 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.alias); break; - case AST_NODEINDEX: - case AST_NODEDOT: - freeNode(node->index.first); - freeNode(node->index.second); - freeNode(node->index.third); + case AST_NODE_EXPORT: + freeLiteral(node->export.identifier); + freeLiteral(node->export.alias); break; } @@ -113,15 +141,16 @@ void freeNodeCustom(ASTNode* node, bool freeSelf) { } } -void freeNode(ASTNode* node) { - freeNodeCustom(node, true); +void freeASTNode(ASTNode* node) { + freeASTNodeCustom(node, true); } +//various emitters void emitASTNodeLiteral(ASTNode** nodeHandle, Literal literal) { //allocate a new node *nodeHandle = ALLOCATE(ASTNode, 1); - (*nodeHandle)->type = AST_NODELITERAL; + (*nodeHandle)->type = AST_NODE_LITERAL; (*nodeHandle)->atomic.literal = copyLiteral(literal); } @@ -129,7 +158,7 @@ void emitASTNodeUnary(ASTNode** nodeHandle, Opcode opcode, ASTNode* child) { //allocate a new node *nodeHandle = ALLOCATE(ASTNode, 1); - (*nodeHandle)->type = AST_NODEUNARY; + (*nodeHandle)->type = AST_NODE_UNARY; (*nodeHandle)->unary.opcode = opcode; (*nodeHandle)->unary.child = child; } @@ -137,7 +166,7 @@ void emitASTNodeUnary(ASTNode** nodeHandle, Opcode opcode, ASTNode* child) { void emitASTNodeBinary(ASTNode** nodeHandle, ASTNode* rhs, Opcode opcode) { ASTNode* tmp = ALLOCATE(ASTNode, 1); - tmp->type = AST_NODEBINARY; + tmp->type = AST_NODE_BINARY; tmp->binary.opcode = opcode; tmp->binary.left = *nodeHandle; tmp->binary.right = rhs; @@ -148,7 +177,7 @@ void emitASTNodeBinary(ASTNode** nodeHandle, ASTNode* rhs, Opcode opcode) { void emitASTNodeGrouping(ASTNode** nodeHandle) { ASTNode* tmp = ALLOCATE(ASTNode, 1); - tmp->type = AST_NODEGROUPING; + tmp->type = AST_NODE_GROUPING; tmp->grouping.child = *nodeHandle; *nodeHandle = tmp; @@ -157,8 +186,8 @@ void emitASTNodeGrouping(ASTNode** nodeHandle) { void emitASTNodeBlock(ASTNode** nodeHandle) { ASTNode* tmp = ALLOCATE(ASTNode, 1); - tmp->type = AST_NODEBLOCK; - tmp->block.nodes = NULL; + tmp->type = AST_NODE_BLOCK; + tmp->block.nodes = NULL; //NOTE: appended by the parser tmp->block.capacity = 0; tmp->block.count = 0; @@ -168,7 +197,7 @@ void emitASTNodeBlock(ASTNode** nodeHandle) { void emitASTNodeCompound(ASTNode** nodeHandle, LiteralType literalType) { ASTNode* tmp = ALLOCATE(ASTNode, 1); - tmp->type = AST_NODECOMPOUND; + tmp->type = AST_NODE_COMPOUND; tmp->compound.literalType = literalType; tmp->compound.nodes = NULL; tmp->compound.capacity = 0; @@ -178,16 +207,27 @@ void emitASTNodeCompound(ASTNode** nodeHandle, LiteralType literalType) { } void setASTNodePair(ASTNode* node, ASTNode* left, ASTNode* right) { - //assume the node has already been allocated - node->type = AST_NODEPAIR; + //set - assume the node has already been allocated + node->type = AST_NODE_PAIR; node->pair.left = left; 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) { ASTNode* tmp = ALLOCATE(ASTNode, 1); - tmp->type = AST_NODEVAR_DECL; + tmp->type = AST_NODE_VAR_DECL; tmp->varDecl.identifier = identifier; tmp->varDecl.typeLiteral = typeLiteral; tmp->varDecl.expression = expression; @@ -195,10 +235,21 @@ void emitASTNodeVarDecl(ASTNode** nodeHandle, Literal identifier, Literal typeLi *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) { ASTNode* tmp = ALLOCATE(ASTNode, 1); - tmp->type = AST_NODEFN_DECL; + tmp->type = AST_NODE_FN_DECL; tmp->fnDecl.identifier = identifier; tmp->fnDecl.arguments = arguments; tmp->fnDecl.returns = returns; @@ -210,85 +261,123 @@ void emitASTNodeFnDecl(ASTNode** nodeHandle, Literal identifier, ASTNode* argume void emitASTFnCall(ASTNode** nodeHandle, ASTNode* arguments, int argumentCount) { ASTNode* tmp = ALLOCATE(ASTNode, 1); - tmp->type = AST_NODEFN_CALL; + tmp->type = AST_NODE_FN_CALL; tmp->fnCall.arguments = arguments; tmp->fnCall.argumentCount = argumentCount; *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); - tmp->type = AST_NODEFN_COLLECTION; - tmp->fnCollection.nodes = NULL; - tmp->fnCollection.capacity = 0; - tmp->fnCollection.count = 0; + tmp->type = AST_NODE_FN_RETURN; + tmp->returns.returns = returns; *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); - tmp->type = type; - tmp->path.preClause = preClause; - tmp->path.postClause = postClause; - tmp->path.condition = condition; - tmp->path.thenPath = thenPath; - tmp->path.elsePath = elsePath; + tmp->type = AST_NODE_IF; + tmp->pathIf.condition = condition; + tmp->pathIf.thenPath = thenPath; + tmp->pathIf.elsePath = elsePath; *nodeHandle = tmp; } -void emitASTNodePrefixIncrement(ASTNode** nodeHandle, Literal identifier, int increment) { +void emitASTNodeWhile(ASTNode** nodeHandle, ASTNode* condition, ASTNode* thenPath) { ASTNode* tmp = ALLOCATE(ASTNode, 1); - tmp->type = AST_NODEINCREMENT_PREFIX; - tmp->increment.identifier = copyLiteral(identifier); - tmp->increment.increment = increment; + tmp->type = AST_NODE_WHILE; + tmp->pathWhile.condition = condition; + tmp->pathWhile.thenPath = thenPath; *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); - tmp->type = AST_NODEINCREMENT_POSTFIX; - tmp->increment.identifier = copyLiteral(identifier); - tmp->increment.increment = increment; + tmp->type = AST_NODE_FOR; + tmp->pathFor.preClause = preClause; + tmp->pathFor.condition = condition; + tmp->pathFor.postClause = postClause; + tmp->pathFor.thenPath = thenPath; *nodeHandle = tmp; } -void emitASTNodeImport(ASTNode** nodeHandle, ASTNodeType mode, Literal identifier, Literal alias) { +void emitASTNodeBreak(ASTNode** nodeHandle) { 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.alias = copyLiteral(alias); *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); - tmp->type = AST_NODEINDEX; - tmp->index.first = first; - tmp->index.second = second; - 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; + tmp->type = AST_NODE_EXPORT; + tmp->export.identifier = copyLiteral(identifier); + tmp->export.alias = copyLiteral(alias); *nodeHandle = tmp; } diff --git a/source/ast_node.h b/source/ast_node.h index 9aef7ae..8bb9470 100644 --- a/source/ast_node.h +++ b/source/ast_node.h @@ -9,43 +9,53 @@ typedef union _node ASTNode; typedef enum ASTNodeType { - AST_NODEERROR, - AST_NODELITERAL, //a simple value - AST_NODEUNARY, //one child + opcode - AST_NODEBINARY, //two children, left and right + opcode - AST_NODEGROUPING, //one child - AST_NODEBLOCK, //contains a sub-node array - AST_NODECOMPOUND, //contains a sub-node array - AST_NODEPAIR, //contains a left and right - AST_NODEVAR_DECL, //contains identifier literal, typenode, expression definition - AST_NODEFN_DECL, //containd identifier literal, arguments node, returns node, block node - AST_NODEFN_COLLECTION, //parts of a function - AST_NODEFN_CALL, - AST_NODEPATH_IF, //for control flow - AST_NODEPATH_WHILE, //for control flow - AST_NODEPATH_FOR, //for control flow - AST_NODEPATH_BREAK, //for control flow - AST_NODEPATH_CONTINUE, //for control flow - AST_NODEPATH_RETURN, - AST_NODEINCREMENT_PREFIX, - AST_NODEINCREMENT_POSTFIX, - AST_NODEIMPORT, - AST_NODEEXPORT, - AST_NODEINDEX, - AST_NODEDOT, + AST_NODE_ERROR, + AST_NODE_LITERAL, //a simple value + AST_NODE_UNARY, //one child + opcode + AST_NODE_BINARY, //two children, left and right + opcode + AST_NODE_GROUPING, //one child + AST_NODE_BLOCK, //contains a sub-node array + AST_NODE_COMPOUND, //contains a sub-node array + AST_NODE_PAIR, //contains a left and right + AST_NODE_INDEX, //index a variable + AST_NODE_VAR_DECL, //contains identifier literal, typenode, expression definition + AST_NODE_FN_DECL, //containd identifier literal, arguments node, returns node, block node + AST_NODE_FN_COLLECTION, //parts of a function + AST_NODE_FN_CALL, //call a function + AST_NODE_FN_RETURN, //for control flow + AST_NODE_IF, //for control flow + AST_NODE_WHILE, //for control flow + AST_NODE_FOR, //for control flow + AST_NODE_BREAK, //for control flow + AST_NODE_CONTINUE, //for control flow + AST_NODE_PREFIX_INCREMENT, //increment a variable + AST_NODE_POSTFIX_INCREMENT, //increment a variable + AST_NODE_PREFIX_DECREMENT, //decrement a variable + AST_NODE_POSTFIX_DECREMENT, //decrement a variable + AST_NODE_IMPORT, //import a variable + AST_NODE_EXPORT, //export a variable } ASTNodeType; +//literals +void emitASTNodeLiteral(ASTNode** nodeHandle, Literal literal); + typedef struct NodeLiteral { ASTNodeType type; Literal literal; } NodeLiteral; +//unary operator +void emitASTNodeUnary(ASTNode** nodeHandle, Opcode opcode, ASTNode* child); + typedef struct NodeUnary { ASTNodeType type; Opcode opcode; ASTNode* child; } NodeUnary; +//binary operator +void emitASTNodeBinary(ASTNode** nodeHandle, ASTNode* rhs, Opcode opcode); //handled node becomes lhs + typedef struct NodeBinary { ASTNodeType type; Opcode opcode; @@ -53,11 +63,17 @@ typedef struct NodeBinary { ASTNode* right; } NodeBinary; +//grouping of other AST nodes +void emitASTNodeGrouping(ASTNode** nodeHandle); + typedef struct NodeGrouping { ASTNodeType type; ASTNode* child; } NodeGrouping; +//block of statement nodes +void emitASTNodeBlock(ASTNode** nodeHandle); + typedef struct NodeBlock { ASTNodeType type; ASTNode* nodes; @@ -65,6 +81,9 @@ typedef struct NodeBlock { int count; } NodeBlock; +//compound literals (array, dictionary) +void emitASTNodeCompound(ASTNode** nodeHandle, LiteralType literalType); + typedef struct NodeCompound { ASTNodeType type; LiteralType literalType; @@ -73,12 +92,26 @@ typedef struct NodeCompound { int count; } NodeCompound; +void setASTNodePair(ASTNode* node, ASTNode* left, ASTNode* right); //NOTE: this is a set function, not an emit function + typedef struct NodePair { ASTNodeType type; ASTNode* left; ASTNode* right; } 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 { ASTNodeType type; Literal identifier; @@ -86,6 +119,19 @@ typedef struct NodeVarDecl { ASTNode* expression; } 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 { ASTNodeType type; Literal identifier; @@ -94,12 +140,8 @@ typedef struct NodeFnDecl { ASTNode* block; } NodeFnDecl; -typedef struct NodeFnCollection { - ASTNodeType type; - ASTNode* nodes; - int capacity; - int count; -} NodeFnCollection; +//function call +void emitASTFnCall(ASTNode** nodeHandle, ASTNode* arguments, int argumentCount); typedef struct NodeFnCall { ASTNodeType type; @@ -107,20 +149,79 @@ typedef struct NodeFnCall { int argumentCount; } 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; - ASTNode* preClause; - ASTNode* postClause; ASTNode* condition; ASTNode* thenPath; 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; Literal identifier; - int increment; -} NodeIncrement; +} NodePrefixIncrement; + +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 { ASTNodeType type; @@ -128,12 +229,11 @@ typedef struct NodeImport { Literal alias; } NodeImport; -typedef struct NodeIndex { +typedef struct NodeExport { ASTNodeType type; - ASTNode* first; - ASTNode* second; - ASTNode* third; -} NodeIndex; + Literal identifier; + Literal alias; +} NodeExport; union _node { ASTNodeType type; @@ -144,32 +244,23 @@ union _node { NodeBlock block; NodeCompound compound; NodePair pair; - NodeVarDecl varDecl; - NodeFnDecl fnDecl; - NodeFnCollection fnCollection; - NodeFnCall fnCall; - NodePath path; - NodeIncrement increment; - NodeImport import; 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); - -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); +TOY_API void freeASTNode(ASTNode* node); diff --git a/source/parser.c b/source/parser.c index 81c0969..cb089fd 100644 --- a/source/parser.c +++ b/source/parser.c @@ -1170,7 +1170,7 @@ static void blockStmt(Parser* parser, ASTNode** nodeHandle) { return; } - //BUGFIX: statements no longer require an existing node + //BUGFIX: statements no longer require the existing node ((*nodeHandle)->block.nodes[(*nodeHandle)->block.count++]) = *node; FREE(ASTNode, node); //simply free the tmp node } diff --git a/source/refstring.c b/source/refstring.c index b522f8d..cbc74f1 100644 --- a/source/refstring.c +++ b/source/refstring.c @@ -21,6 +21,10 @@ void setRefStringAllocatorFn(RefStringAllocatorFn allocator) { RefString* createRefString(char* cstring) { int length = strlen(cstring); + return createRefStringLength(cstring, length); +} + +RefString* createRefStringLength(char* cstring, int length) { //allocate the memory area (including metadata space) 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 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; +} \ No newline at end of file diff --git a/source/refstring.h b/source/refstring.h index a56ef6c..a09ce8f 100644 --- a/source/refstring.h +++ b/source/refstring.h @@ -16,6 +16,7 @@ typedef struct RefString { //API RefString* createRefString(char* cstring); +RefString* createRefStringLength(char* cstring, int length); void deleteRefString(RefString* refString); int countRefString(RefString* refString); int lengthRefString(RefString* refString); @@ -23,3 +24,4 @@ RefString* copyRefString(RefString* refString); RefString* deepCopyRefString(RefString* refString); char* toCString(RefString* refString); bool equalsRefString(RefString* lhs, RefString* rhs); +bool equalsRefStringCString(RefString* lhs, char* cstring); diff --git a/test/makefile b/test/makefile index 7618e5b..6af66bf 100644 --- a/test/makefile +++ b/test/makefile @@ -7,12 +7,15 @@ LIBS += ODIR = obj #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 #lexer TARGETS+=../source/toy_common.c ../source/keyword_types.c ../source/lexer.c +#ast primitives +TARGETS+=../source/ast_node.c + #parser #TARGETS+= diff --git a/test/test_ast_node.c b/test/test_ast_node.c new file mode 100644 index 0000000..5245362 --- /dev/null +++ b/test/test_ast_node.c @@ -0,0 +1,116 @@ +#include "ast_node.h" + +#include "memory.h" +#include "console_colors.h" + +#include +#include + +//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; +} + diff --git a/test/xtest_ast_node.c b/test/xtest_ast_node.c deleted file mode 100644 index ef1ee37..0000000 --- a/test/xtest_ast_node.c +++ /dev/null @@ -1,57 +0,0 @@ -#include "ast_node.h" - -#include "memory.h" -#include "console_colors.h" - -#include - -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; -} -