#include #include #include typedef enum { Assignment, BinaryExpression, Boolean, Comment, Expression, ForLoop, Identifier, Number, Return, String, UnaryExpression } SyntaxKind; typedef enum { Negate } UnaryOperator; typedef enum { Add, Subtract } BinaryOperator; typedef union { UnaryOperator unaryOperator; BinaryOperator binaryOperator; } Operator; typedef union { const char *string; uint64_t number; } Value; typedef struct Node { SyntaxKind syntaxKind; struct Node **children; uint32_t childCount; union { UnaryOperator unaryOperator; BinaryOperator binaryOperator; } operator; Value value; } Node; const char* SyntaxKindString(SyntaxKind syntaxKind) { switch(syntaxKind) { case Assignment: return "Assignment"; case BinaryExpression: return "BinaryExpression"; case Identifier: return "Identifier"; case Number: return "Number"; case String: return "String"; case UnaryExpression: return "UnaryExpression"; default: return "Unknown"; } } Node* MakeIdentifierNode( const char *id ) { Node* node = (Node*) malloc(sizeof(Node)); node->syntaxKind = Identifier; node->value.string = id; node->childCount = 0; return node; } Node* MakeNumberNode( const char *numberString ) { char *ptr; Node* node = (Node*) malloc(sizeof(Node)); node->syntaxKind = Number; node->value.number = strtoul(numberString, &ptr, 10); node->childCount = 0; return node; } Node* MakeStringNode( const char *string ) { Node* node = (Node*) malloc(sizeof(Node)); node->syntaxKind = String; node->value.string = string; node->childCount = 0; return node; } Node* MakeUnaryNode( UnaryOperator operator, Node *child ) { Node* node = (Node*) malloc(sizeof(Node)); node->syntaxKind = UnaryExpression; node->operator.unaryOperator = operator; node->children = malloc(sizeof(Node*)); node->children[0] = child; node->childCount = 1; return node; } Node* MakeBinaryNode( BinaryOperator operator, Node *left, Node *right ) { Node* node = (Node*) malloc(sizeof(Node)); node->syntaxKind = BinaryExpression; node->operator.binaryOperator = operator; node->children = malloc(sizeof(Node*) * 2); node->children[0] = left; node->children[1] = right; node->childCount = 2; return node; } static void PrintBinaryOperator(BinaryOperator expression) { switch (expression) { case Add: printf("+"); break; case Subtract: printf("-"); break; } printf("\n"); } static void PrintNode(Node *node) { printf("%s\n", SyntaxKindString(node->syntaxKind)); switch (node->syntaxKind) { case BinaryExpression: PrintBinaryOperator(node->operator.binaryOperator); break; case Number: printf("%lu\n", node->value.number); break; } } void PrintTree(Node *node) { uint32_t i; PrintNode(node); for (i = 0; i < node->childCount; i += 1) { PrintTree(node->children[i]); } }