clang-format config
							parent
							
								
									876e8deb6e
								
							
						
					
					
						commit
						473b706ad9
					
				| 
						 | 
				
			
			@ -0,0 +1,166 @@
 | 
			
		|||
---
 | 
			
		||||
Language:        Cpp
 | 
			
		||||
# BasedOnStyle:  LLVM
 | 
			
		||||
AccessModifierOffset: -2
 | 
			
		||||
AlignAfterOpenBracket: AlwaysBreak
 | 
			
		||||
AlignConsecutiveMacros: None
 | 
			
		||||
AlignConsecutiveAssignments: None
 | 
			
		||||
AlignConsecutiveBitFields: None
 | 
			
		||||
AlignConsecutiveDeclarations: None
 | 
			
		||||
AlignEscapedNewlines: Right
 | 
			
		||||
AlignOperands:   Align
 | 
			
		||||
AlignTrailingComments: true
 | 
			
		||||
AllowAllArgumentsOnNextLine: false
 | 
			
		||||
AllowAllConstructorInitializersOnNextLine: true
 | 
			
		||||
AllowAllParametersOfDeclarationOnNextLine: false
 | 
			
		||||
AllowShortEnumsOnASingleLine: true
 | 
			
		||||
AllowShortBlocksOnASingleLine: Never
 | 
			
		||||
AllowShortCaseLabelsOnASingleLine: false
 | 
			
		||||
AllowShortFunctionsOnASingleLine: All
 | 
			
		||||
AllowShortLambdasOnASingleLine: All
 | 
			
		||||
AllowShortIfStatementsOnASingleLine: Never
 | 
			
		||||
AllowShortLoopsOnASingleLine: false
 | 
			
		||||
AlwaysBreakAfterDefinitionReturnType: None
 | 
			
		||||
AlwaysBreakAfterReturnType: None
 | 
			
		||||
AlwaysBreakBeforeMultilineStrings: false
 | 
			
		||||
AlwaysBreakTemplateDeclarations: MultiLine
 | 
			
		||||
AttributeMacros:
 | 
			
		||||
  - __capability
 | 
			
		||||
BinPackArguments: false
 | 
			
		||||
BinPackParameters: false
 | 
			
		||||
BraceWrapping:
 | 
			
		||||
  AfterCaseLabel:  false
 | 
			
		||||
  AfterClass:      false
 | 
			
		||||
  AfterControlStatement: Never
 | 
			
		||||
  AfterEnum:       false
 | 
			
		||||
  AfterFunction:   false
 | 
			
		||||
  AfterNamespace:  false
 | 
			
		||||
  AfterObjCDeclaration: false
 | 
			
		||||
  AfterStruct:     false
 | 
			
		||||
  AfterUnion:      false
 | 
			
		||||
  AfterExternBlock: false
 | 
			
		||||
  BeforeCatch:     false
 | 
			
		||||
  BeforeElse:      false
 | 
			
		||||
  BeforeLambdaBody: false
 | 
			
		||||
  BeforeWhile:     false
 | 
			
		||||
  IndentBraces:    false
 | 
			
		||||
  SplitEmptyFunction: true
 | 
			
		||||
  SplitEmptyRecord: true
 | 
			
		||||
  SplitEmptyNamespace: true
 | 
			
		||||
BreakBeforeBinaryOperators: None
 | 
			
		||||
BreakBeforeConceptDeclarations: true
 | 
			
		||||
BreakBeforeBraces: Allman
 | 
			
		||||
BreakBeforeInheritanceComma: false
 | 
			
		||||
BreakInheritanceList: BeforeColon
 | 
			
		||||
BreakBeforeTernaryOperators: true
 | 
			
		||||
BreakConstructorInitializersBeforeComma: false
 | 
			
		||||
BreakConstructorInitializers: BeforeColon
 | 
			
		||||
BreakAfterJavaFieldAnnotations: false
 | 
			
		||||
BreakStringLiterals: true
 | 
			
		||||
ColumnLimit:     80
 | 
			
		||||
CommentPragmas:  '^ IWYU pragma:'
 | 
			
		||||
CompactNamespaces: false
 | 
			
		||||
ConstructorInitializerAllOnOneLineOrOnePerLine: false
 | 
			
		||||
ConstructorInitializerIndentWidth: 4
 | 
			
		||||
ContinuationIndentWidth: 4
 | 
			
		||||
Cpp11BracedListStyle: true
 | 
			
		||||
DeriveLineEnding: true
 | 
			
		||||
DerivePointerAlignment: false
 | 
			
		||||
DisableFormat:   false
 | 
			
		||||
EmptyLineBeforeAccessModifier: LogicalBlock
 | 
			
		||||
ExperimentalAutoDetectBinPacking: false
 | 
			
		||||
FixNamespaceComments: true
 | 
			
		||||
ForEachMacros:
 | 
			
		||||
  - foreach
 | 
			
		||||
  - Q_FOREACH
 | 
			
		||||
  - BOOST_FOREACH
 | 
			
		||||
StatementAttributeLikeMacros:
 | 
			
		||||
  - Q_EMIT
 | 
			
		||||
IncludeBlocks:   Preserve
 | 
			
		||||
IncludeCategories:
 | 
			
		||||
  - Regex:           '^"(llvm|llvm-c|clang|clang-c)/'
 | 
			
		||||
    Priority:        2
 | 
			
		||||
    SortPriority:    0
 | 
			
		||||
    CaseSensitive:   false
 | 
			
		||||
  - Regex:           '^(<|"(gtest|gmock|isl|json)/)'
 | 
			
		||||
    Priority:        3
 | 
			
		||||
    SortPriority:    0
 | 
			
		||||
    CaseSensitive:   false
 | 
			
		||||
  - Regex:           '.*'
 | 
			
		||||
    Priority:        1
 | 
			
		||||
    SortPriority:    0
 | 
			
		||||
    CaseSensitive:   false
 | 
			
		||||
IncludeIsMainRegex: '(Test)?$'
 | 
			
		||||
IncludeIsMainSourceRegex: ''
 | 
			
		||||
IndentCaseLabels: false
 | 
			
		||||
IndentCaseBlocks: false
 | 
			
		||||
IndentGotoLabels: true
 | 
			
		||||
IndentPPDirectives: None
 | 
			
		||||
IndentExternBlock: AfterExternBlock
 | 
			
		||||
IndentRequires:  false
 | 
			
		||||
IndentWidth:     4
 | 
			
		||||
IndentWrappedFunctionNames: false
 | 
			
		||||
InsertTrailingCommas: None
 | 
			
		||||
JavaScriptQuotes: Leave
 | 
			
		||||
JavaScriptWrapImports: true
 | 
			
		||||
KeepEmptyLinesAtTheStartOfBlocks: true
 | 
			
		||||
MacroBlockBegin: ''
 | 
			
		||||
MacroBlockEnd:   ''
 | 
			
		||||
MaxEmptyLinesToKeep: 1
 | 
			
		||||
NamespaceIndentation: None
 | 
			
		||||
ObjCBinPackProtocolList: Auto
 | 
			
		||||
ObjCBlockIndentWidth: 4
 | 
			
		||||
ObjCBreakBeforeNestedBlockParam: true
 | 
			
		||||
ObjCSpaceAfterProperty: false
 | 
			
		||||
ObjCSpaceBeforeProtocolList: true
 | 
			
		||||
PenaltyBreakAssignment: 2
 | 
			
		||||
PenaltyBreakBeforeFirstCallParameter: 19
 | 
			
		||||
PenaltyBreakComment: 300
 | 
			
		||||
PenaltyBreakFirstLessLess: 120
 | 
			
		||||
PenaltyBreakString: 1000
 | 
			
		||||
PenaltyBreakTemplateDeclaration: 10
 | 
			
		||||
PenaltyExcessCharacter: 1000000
 | 
			
		||||
PenaltyReturnTypeOnItsOwnLine: 1000000
 | 
			
		||||
PenaltyIndentedWhitespace: 0
 | 
			
		||||
PointerAlignment: Right
 | 
			
		||||
ReflowComments:  true
 | 
			
		||||
SortIncludes:    true
 | 
			
		||||
SortJavaStaticImport: Before
 | 
			
		||||
SortUsingDeclarations: true
 | 
			
		||||
SpaceAfterCStyleCast: false
 | 
			
		||||
SpaceAfterLogicalNot: false
 | 
			
		||||
SpaceAfterTemplateKeyword: true
 | 
			
		||||
SpaceBeforeAssignmentOperators: true
 | 
			
		||||
SpaceBeforeCaseColon: false
 | 
			
		||||
SpaceBeforeCpp11BracedList: false
 | 
			
		||||
SpaceBeforeCtorInitializerColon: true
 | 
			
		||||
SpaceBeforeInheritanceColon: true
 | 
			
		||||
SpaceBeforeParens: ControlStatements
 | 
			
		||||
SpaceAroundPointerQualifiers: Default
 | 
			
		||||
SpaceBeforeRangeBasedForLoopColon: true
 | 
			
		||||
SpaceInEmptyBlock: false
 | 
			
		||||
SpaceInEmptyParentheses: false
 | 
			
		||||
SpacesBeforeTrailingComments: 1
 | 
			
		||||
SpacesInAngles:  false
 | 
			
		||||
SpacesInConditionalStatement: false
 | 
			
		||||
SpacesInContainerLiterals: true
 | 
			
		||||
SpacesInCStyleCastParentheses: false
 | 
			
		||||
SpacesInParentheses: false
 | 
			
		||||
SpacesInSquareBrackets: false
 | 
			
		||||
SpaceBeforeSquareBrackets: false
 | 
			
		||||
BitFieldColonSpacing: Both
 | 
			
		||||
Standard:        Latest
 | 
			
		||||
StatementMacros:
 | 
			
		||||
  - Q_UNUSED
 | 
			
		||||
  - QT_REQUIRE_VERSION
 | 
			
		||||
TabWidth:        8
 | 
			
		||||
UseCRLF:         false
 | 
			
		||||
UseTab:          Never
 | 
			
		||||
WhitespaceSensitiveMacros:
 | 
			
		||||
  - STRINGIZE
 | 
			
		||||
  - PP_STRINGIZE
 | 
			
		||||
  - BOOST_PP_STRINGIZE
 | 
			
		||||
  - NS_SWIFT_NAME
 | 
			
		||||
  - CF_SWIFT_NAME
 | 
			
		||||
...
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										155
									
								
								src/ast.h
								
								
								
								
							
							
						
						
									
										155
									
								
								src/ast.h
								
								
								
								
							| 
						 | 
				
			
			@ -1,8 +1,8 @@
 | 
			
		|||
#ifndef WRAITH_AST_H
 | 
			
		||||
#define WRAITH_AST_H
 | 
			
		||||
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include "identcheck.h"
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
 | 
			
		||||
/* -Wpedantic nameless union/struct silencing */
 | 
			
		||||
#ifndef WRAITHNAMELESS
 | 
			
		||||
| 
						 | 
				
			
			@ -279,130 +279,65 @@ struct Node
 | 
			
		|||
    IdNode *idLink;
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
const char* SyntaxKindString(SyntaxKind syntaxKind);
 | 
			
		||||
const char *SyntaxKindString(SyntaxKind syntaxKind);
 | 
			
		||||
 | 
			
		||||
uint8_t IsPrimitiveType(Node *typeNode);
 | 
			
		||||
Node* MakePrimitiveTypeNode(
 | 
			
		||||
    PrimitiveType type
 | 
			
		||||
);
 | 
			
		||||
Node* MakeCustomTypeNode(
 | 
			
		||||
    char *string
 | 
			
		||||
);
 | 
			
		||||
Node* MakeReferenceTypeNode(
 | 
			
		||||
    Node *typeNode
 | 
			
		||||
);
 | 
			
		||||
Node* MakeTypeNode(
 | 
			
		||||
    Node *typeNode /* can be primitive, custom, or reference */
 | 
			
		||||
);
 | 
			
		||||
Node* MakeIdentifierNode(
 | 
			
		||||
    const char *id
 | 
			
		||||
);
 | 
			
		||||
Node* MakeNumberNode(
 | 
			
		||||
    const char *numberString
 | 
			
		||||
);
 | 
			
		||||
Node* MakeStringNode(
 | 
			
		||||
    const char *string
 | 
			
		||||
);
 | 
			
		||||
Node* MakeStaticNode();
 | 
			
		||||
Node* MakeFunctionModifiersNode(
 | 
			
		||||
    Node **pModifierNodes,
 | 
			
		||||
    uint32_t modifierCount
 | 
			
		||||
);
 | 
			
		||||
Node* MakeUnaryNode(
 | 
			
		||||
    UnaryOperator operator,
 | 
			
		||||
    Node *child
 | 
			
		||||
);
 | 
			
		||||
Node* MakeBinaryNode(
 | 
			
		||||
    BinaryOperator operator,
 | 
			
		||||
    Node *left,
 | 
			
		||||
    Node *right
 | 
			
		||||
);
 | 
			
		||||
Node* MakeDeclarationNode(
 | 
			
		||||
    Node* typeNode,
 | 
			
		||||
    Node* identifierNode
 | 
			
		||||
);
 | 
			
		||||
Node* MakeAssignmentNode(
 | 
			
		||||
    Node *left,
 | 
			
		||||
    Node *right
 | 
			
		||||
);
 | 
			
		||||
Node* StartStatementSequenceNode(
 | 
			
		||||
    Node* statementNode
 | 
			
		||||
);
 | 
			
		||||
Node* AddStatement(
 | 
			
		||||
    Node* statementSequenceNode,
 | 
			
		||||
    Node *statementNode
 | 
			
		||||
);
 | 
			
		||||
Node* MakeReturnStatementNode(
 | 
			
		||||
    Node *expressionNode
 | 
			
		||||
);
 | 
			
		||||
Node* MakeReturnVoidStatementNode();
 | 
			
		||||
Node* StartFunctionSignatureArgumentsNode(
 | 
			
		||||
    Node *argumentNode
 | 
			
		||||
);
 | 
			
		||||
Node* AddFunctionSignatureArgumentNode(
 | 
			
		||||
    Node *argumentsNode,
 | 
			
		||||
    Node *argumentNode
 | 
			
		||||
);
 | 
			
		||||
Node *MakePrimitiveTypeNode(PrimitiveType type);
 | 
			
		||||
Node *MakeCustomTypeNode(char *string);
 | 
			
		||||
Node *MakeReferenceTypeNode(Node *typeNode);
 | 
			
		||||
Node *MakeTypeNode(Node *typeNode);
 | 
			
		||||
Node *MakeIdentifierNode(const char *id);
 | 
			
		||||
Node *MakeNumberNode(const char *numberString);
 | 
			
		||||
Node *MakeStringNode(const char *string);
 | 
			
		||||
Node *MakeStaticNode();
 | 
			
		||||
Node *MakeFunctionModifiersNode(Node **pModifierNodes, uint32_t modifierCount);
 | 
			
		||||
Node *MakeUnaryNode(UnaryOperator operator, Node * child);
 | 
			
		||||
Node *MakeBinaryNode(BinaryOperator operator, Node * left, Node *right);
 | 
			
		||||
Node *MakeDeclarationNode(Node *typeNode, Node *identifierNode);
 | 
			
		||||
Node *MakeAssignmentNode(Node *left, Node *right);
 | 
			
		||||
Node *StartStatementSequenceNode(Node *statementNode);
 | 
			
		||||
Node *AddStatement(Node *statementSequenceNode, Node *statementNode);
 | 
			
		||||
Node *MakeReturnStatementNode(Node *expressionNode);
 | 
			
		||||
Node *MakeReturnVoidStatementNode();
 | 
			
		||||
Node *StartFunctionSignatureArgumentsNode(Node *argumentNode);
 | 
			
		||||
Node *AddFunctionSignatureArgumentNode(Node *argumentsNode, Node *argumentNode);
 | 
			
		||||
Node *MakeEmptyFunctionSignatureArgumentsNode();
 | 
			
		||||
Node* MakeFunctionSignatureNode(
 | 
			
		||||
Node *MakeFunctionSignatureNode(
 | 
			
		||||
    Node *identifierNode,
 | 
			
		||||
    Node* typeNode,
 | 
			
		||||
    Node* argumentsNode,
 | 
			
		||||
    Node* modifiersNode
 | 
			
		||||
);
 | 
			
		||||
Node* MakeFunctionDeclarationNode(
 | 
			
		||||
    Node* functionSignatureNode,
 | 
			
		||||
    Node* functionBodyNode
 | 
			
		||||
);
 | 
			
		||||
Node* MakeStructDeclarationNode(
 | 
			
		||||
    Node *typeNode,
 | 
			
		||||
    Node *argumentsNode,
 | 
			
		||||
    Node *modifiersNode);
 | 
			
		||||
Node *MakeFunctionDeclarationNode(
 | 
			
		||||
    Node *functionSignatureNode,
 | 
			
		||||
    Node *functionBodyNode);
 | 
			
		||||
Node *MakeStructDeclarationNode(
 | 
			
		||||
    Node *identifierNode,
 | 
			
		||||
    Node *declarationSequenceNode
 | 
			
		||||
);
 | 
			
		||||
Node* StartDeclarationSequenceNode(
 | 
			
		||||
    Node *declarationNode
 | 
			
		||||
);
 | 
			
		||||
Node* AddDeclarationNode(
 | 
			
		||||
    Node *declarationSequenceNode,
 | 
			
		||||
    Node *declarationNode
 | 
			
		||||
);
 | 
			
		||||
Node *StartFunctionArgumentSequenceNode(
 | 
			
		||||
    Node *argumentNode
 | 
			
		||||
);
 | 
			
		||||
Node *AddFunctionArgumentNode(
 | 
			
		||||
    Node *argumentSequenceNode,
 | 
			
		||||
    Node *argumentNode
 | 
			
		||||
);
 | 
			
		||||
    Node *declarationSequenceNode);
 | 
			
		||||
Node *StartDeclarationSequenceNode(Node *declarationNode);
 | 
			
		||||
Node *AddDeclarationNode(Node *declarationSequenceNode, Node *declarationNode);
 | 
			
		||||
Node *StartFunctionArgumentSequenceNode(Node *argumentNode);
 | 
			
		||||
Node *AddFunctionArgumentNode(Node *argumentSequenceNode, Node *argumentNode);
 | 
			
		||||
Node *MakeEmptyFunctionArgumentSequenceNode();
 | 
			
		||||
Node* MakeFunctionCallExpressionNode(
 | 
			
		||||
Node *MakeFunctionCallExpressionNode(
 | 
			
		||||
    Node *identifierNode,
 | 
			
		||||
    Node *argumentSequenceNode
 | 
			
		||||
);
 | 
			
		||||
Node* MakeAccessExpressionNode(
 | 
			
		||||
    Node *accessee,
 | 
			
		||||
    Node *accessor
 | 
			
		||||
);
 | 
			
		||||
Node* MakeAllocNode(
 | 
			
		||||
    Node *typeNode
 | 
			
		||||
);
 | 
			
		||||
Node* MakeIfNode(
 | 
			
		||||
    Node *expressionNode,
 | 
			
		||||
    Node *statementSequenceNode
 | 
			
		||||
);
 | 
			
		||||
Node* MakeIfElseNode(
 | 
			
		||||
    Node *argumentSequenceNode);
 | 
			
		||||
Node *MakeAccessExpressionNode(Node *accessee, Node *accessor);
 | 
			
		||||
Node *MakeAllocNode(Node *typeNode);
 | 
			
		||||
Node *MakeIfNode(Node *expressionNode, Node *statementSequenceNode);
 | 
			
		||||
Node *MakeIfElseNode(
 | 
			
		||||
    Node *ifNode,
 | 
			
		||||
    Node *elseNode /* can be a conditional or a statement sequence */
 | 
			
		||||
);
 | 
			
		||||
Node* MakeForLoopNode(
 | 
			
		||||
Node *MakeForLoopNode(
 | 
			
		||||
    Node *identifierNode,
 | 
			
		||||
    Node *startNumberNode,
 | 
			
		||||
    Node *endNumberNode,
 | 
			
		||||
    Node *statementSequenceNode
 | 
			
		||||
);
 | 
			
		||||
    Node *statementSequenceNode);
 | 
			
		||||
 | 
			
		||||
void PrintNode(Node *node, uint32_t tabCount);
 | 
			
		||||
const char* SyntaxKindString(SyntaxKind syntaxKind);
 | 
			
		||||
const char *SyntaxKindString(SyntaxKind syntaxKind);
 | 
			
		||||
 | 
			
		||||
TypeTag* MakeTypeTag(Node *node);
 | 
			
		||||
char* TypeTagToString(TypeTag *tag);
 | 
			
		||||
TypeTag *MakeTypeTag(Node *node);
 | 
			
		||||
char *TypeTagToString(TypeTag *tag);
 | 
			
		||||
 | 
			
		||||
#endif /* WRAITH_AST_H */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										735
									
								
								src/codegen.c
								
								
								
								
							
							
						
						
									
										735
									
								
								src/codegen.c
								
								
								
								
							
										
											
												File diff suppressed because it is too large
												Load Diff
											
										
									
								
							
							
								
								
									
										564
									
								
								src/identcheck.c
								
								
								
								
							
							
						
						
									
										564
									
								
								src/identcheck.c
								
								
								
								
							| 
						 | 
				
			
			@ -1,14 +1,15 @@
 | 
			
		|||
#include <stdbool.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <stdio.h>
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <stdint.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
#include "ast.h"
 | 
			
		||||
#include "identcheck.h"
 | 
			
		||||
 | 
			
		||||
IdNode* MakeIdNode(NodeType type, char *name, IdNode *parent) {
 | 
			
		||||
    IdNode *node = (IdNode*)malloc(sizeof(IdNode));
 | 
			
		||||
IdNode *MakeIdNode(NodeType type, char *name, IdNode *parent)
 | 
			
		||||
{
 | 
			
		||||
    IdNode *node = (IdNode *)malloc(sizeof(IdNode));
 | 
			
		||||
    node->type = type;
 | 
			
		||||
    node->name = strdup(name);
 | 
			
		||||
    node->parent = parent;
 | 
			
		||||
| 
						 | 
				
			
			@ -19,283 +20,369 @@ IdNode* MakeIdNode(NodeType type, char *name, IdNode *parent) {
 | 
			
		|||
    return node;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void AddChildToNode(IdNode *node, IdNode *child) {
 | 
			
		||||
    if (child == NULL) return;
 | 
			
		||||
void AddChildToNode(IdNode *node, IdNode *child)
 | 
			
		||||
{
 | 
			
		||||
    if (child == NULL)
 | 
			
		||||
        return;
 | 
			
		||||
 | 
			
		||||
    if (node->children == NULL) {
 | 
			
		||||
    if (node->children == NULL)
 | 
			
		||||
    {
 | 
			
		||||
        node->childCapacity = 2;
 | 
			
		||||
        node->children = (IdNode**) malloc(sizeof(IdNode*) * node->childCapacity);
 | 
			
		||||
    } else if (node->childCount == node->childCapacity) {
 | 
			
		||||
        node->children =
 | 
			
		||||
            (IdNode **)malloc(sizeof(IdNode *) * node->childCapacity);
 | 
			
		||||
    }
 | 
			
		||||
    else if (node->childCount == node->childCapacity)
 | 
			
		||||
    {
 | 
			
		||||
        node->childCapacity *= 2;
 | 
			
		||||
        node->children = (IdNode**) realloc(node->children, sizeof(IdNode*) * node->childCapacity);
 | 
			
		||||
        node->children = (IdNode **)realloc(
 | 
			
		||||
            node->children,
 | 
			
		||||
            sizeof(IdNode *) * node->childCapacity);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    node->children[node->childCount] = child;
 | 
			
		||||
    node->childCount += 1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
IdNode* MakeIdTree(Node *astNode, IdNode *parent) {
 | 
			
		||||
IdNode *MakeIdTree(Node *astNode, IdNode *parent)
 | 
			
		||||
{
 | 
			
		||||
    uint32_t i;
 | 
			
		||||
    IdNode *mainNode;
 | 
			
		||||
    switch (astNode->syntaxKind) {
 | 
			
		||||
        case AccessExpression:
 | 
			
		||||
            AddChildToNode(parent, MakeIdTree(astNode->accessExpression.accessee, parent));
 | 
			
		||||
            AddChildToNode(parent, MakeIdTree(astNode->accessExpression.accessor, parent));
 | 
			
		||||
            return NULL;
 | 
			
		||||
    switch (astNode->syntaxKind)
 | 
			
		||||
    {
 | 
			
		||||
    case AccessExpression:
 | 
			
		||||
        AddChildToNode(
 | 
			
		||||
            parent,
 | 
			
		||||
            MakeIdTree(astNode->accessExpression.accessee, parent));
 | 
			
		||||
        AddChildToNode(
 | 
			
		||||
            parent,
 | 
			
		||||
            MakeIdTree(astNode->accessExpression.accessor, parent));
 | 
			
		||||
        return NULL;
 | 
			
		||||
 | 
			
		||||
        case AllocExpression:
 | 
			
		||||
            AddChildToNode(parent, MakeIdTree(astNode->allocExpression.type, parent));
 | 
			
		||||
            return NULL;
 | 
			
		||||
    case AllocExpression:
 | 
			
		||||
        AddChildToNode(
 | 
			
		||||
            parent,
 | 
			
		||||
            MakeIdTree(astNode->allocExpression.type, parent));
 | 
			
		||||
        return NULL;
 | 
			
		||||
 | 
			
		||||
        case Assignment: {
 | 
			
		||||
            if (astNode->assignmentStatement.left->syntaxKind == Declaration) {
 | 
			
		||||
                return MakeIdTree(astNode->assignmentStatement.left, parent);
 | 
			
		||||
            } else {
 | 
			
		||||
                AddChildToNode(parent, MakeIdTree(astNode->assignmentStatement.left, parent));
 | 
			
		||||
                AddChildToNode(parent, MakeIdTree(astNode->assignmentStatement.right, parent));
 | 
			
		||||
                return NULL;
 | 
			
		||||
            }
 | 
			
		||||
    case Assignment:
 | 
			
		||||
    {
 | 
			
		||||
        if (astNode->assignmentStatement.left->syntaxKind == Declaration)
 | 
			
		||||
        {
 | 
			
		||||
            return MakeIdTree(astNode->assignmentStatement.left, parent);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        case BinaryExpression:
 | 
			
		||||
            AddChildToNode(parent, MakeIdTree(astNode->binaryExpression.left, parent));
 | 
			
		||||
            AddChildToNode(parent, MakeIdTree(astNode->binaryExpression.right, parent));
 | 
			
		||||
            return NULL;
 | 
			
		||||
 | 
			
		||||
        case Declaration: {
 | 
			
		||||
            Node *idNode = astNode->declaration.identifier;
 | 
			
		||||
            mainNode = MakeIdNode(Variable, idNode->identifier.name, parent);
 | 
			
		||||
            mainNode->typeTag = MakeTypeTag(astNode);
 | 
			
		||||
            idNode->typeTag = mainNode->typeTag;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        case DeclarationSequence: {
 | 
			
		||||
            mainNode = MakeIdNode(UnorderedScope, "", parent);
 | 
			
		||||
            for (i = 0; i < astNode->declarationSequence.count; i++) {
 | 
			
		||||
                AddChildToNode(
 | 
			
		||||
                    mainNode, MakeIdTree(astNode->declarationSequence.sequence[i], mainNode));
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        case ForLoop: {
 | 
			
		||||
            Node *loopDecl = astNode->forLoop.declaration;
 | 
			
		||||
            Node *loopBody = astNode->forLoop.statementSequence;
 | 
			
		||||
            mainNode = MakeIdNode(OrderedScope, "for-loop", parent);
 | 
			
		||||
            AddChildToNode(mainNode, MakeIdTree(loopDecl, mainNode));
 | 
			
		||||
            AddChildToNode(mainNode, MakeIdTree(loopBody, mainNode));
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        case FunctionArgumentSequence:
 | 
			
		||||
            for (i = 0; i < astNode->functionArgumentSequence.count; i++) {
 | 
			
		||||
                AddChildToNode(
 | 
			
		||||
                    parent, MakeIdTree(astNode->functionArgumentSequence.sequence[i], parent));
 | 
			
		||||
            }
 | 
			
		||||
            return NULL;
 | 
			
		||||
 | 
			
		||||
        case FunctionCallExpression:
 | 
			
		||||
            AddChildToNode(parent, MakeIdTree(astNode->functionCallExpression.identifier, parent));
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            AddChildToNode(
 | 
			
		||||
                parent, MakeIdTree(astNode->functionCallExpression.argumentSequence, parent));
 | 
			
		||||
            return NULL;
 | 
			
		||||
 | 
			
		||||
        case FunctionDeclaration: {
 | 
			
		||||
            Node *sigNode = astNode->functionDeclaration.functionSignature;
 | 
			
		||||
            Node *idNode = sigNode->functionSignature.identifier;
 | 
			
		||||
            char *funcName = idNode->identifier.name;
 | 
			
		||||
            mainNode = MakeIdNode(Function, funcName, parent);
 | 
			
		||||
            mainNode->typeTag = MakeTypeTag(astNode);
 | 
			
		||||
            idNode->typeTag = mainNode->typeTag;
 | 
			
		||||
            MakeIdTree(sigNode->functionSignature.arguments, mainNode);
 | 
			
		||||
            MakeIdTree(astNode->functionDeclaration.functionBody, mainNode);
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        case FunctionSignatureArguments: {
 | 
			
		||||
            for (i = 0; i < astNode->functionSignatureArguments.count; i++) {
 | 
			
		||||
                Node *argNode = astNode->functionSignatureArguments.sequence[i];
 | 
			
		||||
                AddChildToNode(parent, MakeIdTree(argNode, parent));
 | 
			
		||||
            }
 | 
			
		||||
                parent,
 | 
			
		||||
                MakeIdTree(astNode->assignmentStatement.left, parent));
 | 
			
		||||
            AddChildToNode(
 | 
			
		||||
                parent,
 | 
			
		||||
                MakeIdTree(astNode->assignmentStatement.right, parent));
 | 
			
		||||
            return NULL;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
        case Identifier: {
 | 
			
		||||
            char *name = astNode->identifier.name;
 | 
			
		||||
            mainNode = MakeIdNode(Placeholder, name, parent);
 | 
			
		||||
            IdNode *lookupNode = LookupId(mainNode, NULL, name);
 | 
			
		||||
            if (lookupNode == NULL) {
 | 
			
		||||
                fprintf(stderr, "wraith: Could not find IdNode for id %s\n", name);
 | 
			
		||||
                TypeTag *tag = (TypeTag*)malloc(sizeof(TypeTag));
 | 
			
		||||
                tag->type = Unknown;
 | 
			
		||||
                astNode->typeTag = tag;
 | 
			
		||||
            } else {
 | 
			
		||||
                astNode->typeTag = lookupNode->typeTag;
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
    case BinaryExpression:
 | 
			
		||||
        AddChildToNode(
 | 
			
		||||
            parent,
 | 
			
		||||
            MakeIdTree(astNode->binaryExpression.left, parent));
 | 
			
		||||
        AddChildToNode(
 | 
			
		||||
            parent,
 | 
			
		||||
            MakeIdTree(astNode->binaryExpression.right, parent));
 | 
			
		||||
        return NULL;
 | 
			
		||||
 | 
			
		||||
    case Declaration:
 | 
			
		||||
    {
 | 
			
		||||
        Node *idNode = astNode->declaration.identifier;
 | 
			
		||||
        mainNode = MakeIdNode(Variable, idNode->identifier.name, parent);
 | 
			
		||||
        mainNode->typeTag = MakeTypeTag(astNode);
 | 
			
		||||
        idNode->typeTag = mainNode->typeTag;
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    case DeclarationSequence:
 | 
			
		||||
    {
 | 
			
		||||
        mainNode = MakeIdNode(UnorderedScope, "", parent);
 | 
			
		||||
        for (i = 0; i < astNode->declarationSequence.count; i++)
 | 
			
		||||
        {
 | 
			
		||||
            AddChildToNode(
 | 
			
		||||
                mainNode,
 | 
			
		||||
                MakeIdTree(astNode->declarationSequence.sequence[i], mainNode));
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
        case IfStatement: {
 | 
			
		||||
            Node *clause = astNode->ifStatement.expression;
 | 
			
		||||
            Node *stmtSeq = astNode->ifStatement.statementSequence;
 | 
			
		||||
            mainNode = MakeIdNode(OrderedScope, "if", parent);
 | 
			
		||||
            MakeIdTree(clause, mainNode);
 | 
			
		||||
            MakeIdTree(stmtSeq, mainNode);
 | 
			
		||||
            break;
 | 
			
		||||
    case ForLoop:
 | 
			
		||||
    {
 | 
			
		||||
        Node *loopDecl = astNode->forLoop.declaration;
 | 
			
		||||
        Node *loopBody = astNode->forLoop.statementSequence;
 | 
			
		||||
        mainNode = MakeIdNode(OrderedScope, "for-loop", parent);
 | 
			
		||||
        AddChildToNode(mainNode, MakeIdTree(loopDecl, mainNode));
 | 
			
		||||
        AddChildToNode(mainNode, MakeIdTree(loopBody, mainNode));
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    case FunctionArgumentSequence:
 | 
			
		||||
        for (i = 0; i < astNode->functionArgumentSequence.count; i++)
 | 
			
		||||
        {
 | 
			
		||||
            AddChildToNode(
 | 
			
		||||
                parent,
 | 
			
		||||
                MakeIdTree(
 | 
			
		||||
                    astNode->functionArgumentSequence.sequence[i],
 | 
			
		||||
                    parent));
 | 
			
		||||
        }
 | 
			
		||||
        return NULL;
 | 
			
		||||
 | 
			
		||||
        case IfElseStatement: {
 | 
			
		||||
            Node *ifNode = astNode->ifElseStatement.ifStatement;
 | 
			
		||||
            Node *elseStmts = astNode->ifElseStatement.elseStatement;
 | 
			
		||||
            mainNode = MakeIdNode(OrderedScope, "if-else", parent);
 | 
			
		||||
            IdNode *ifBranch = MakeIdTree(ifNode, mainNode);
 | 
			
		||||
            AddChildToNode(mainNode, ifBranch);
 | 
			
		||||
            IdNode *elseScope = MakeIdNode(OrderedScope, "else", mainNode);
 | 
			
		||||
            MakeIdTree(elseStmts, elseScope);
 | 
			
		||||
            AddChildToNode(mainNode, elseScope);
 | 
			
		||||
            break;
 | 
			
		||||
    case FunctionCallExpression:
 | 
			
		||||
        AddChildToNode(
 | 
			
		||||
            parent,
 | 
			
		||||
            MakeIdTree(astNode->functionCallExpression.identifier, parent));
 | 
			
		||||
        AddChildToNode(
 | 
			
		||||
            parent,
 | 
			
		||||
            MakeIdTree(
 | 
			
		||||
                astNode->functionCallExpression.argumentSequence,
 | 
			
		||||
                parent));
 | 
			
		||||
        return NULL;
 | 
			
		||||
 | 
			
		||||
    case FunctionDeclaration:
 | 
			
		||||
    {
 | 
			
		||||
        Node *sigNode = astNode->functionDeclaration.functionSignature;
 | 
			
		||||
        Node *idNode = sigNode->functionSignature.identifier;
 | 
			
		||||
        char *funcName = idNode->identifier.name;
 | 
			
		||||
        mainNode = MakeIdNode(Function, funcName, parent);
 | 
			
		||||
        mainNode->typeTag = MakeTypeTag(astNode);
 | 
			
		||||
        idNode->typeTag = mainNode->typeTag;
 | 
			
		||||
        MakeIdTree(sigNode->functionSignature.arguments, mainNode);
 | 
			
		||||
        MakeIdTree(astNode->functionDeclaration.functionBody, mainNode);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    case FunctionSignatureArguments:
 | 
			
		||||
    {
 | 
			
		||||
        for (i = 0; i < astNode->functionSignatureArguments.count; i++)
 | 
			
		||||
        {
 | 
			
		||||
            Node *argNode = astNode->functionSignatureArguments.sequence[i];
 | 
			
		||||
            AddChildToNode(parent, MakeIdTree(argNode, parent));
 | 
			
		||||
        }
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
        case ReferenceTypeNode:
 | 
			
		||||
            AddChildToNode(parent, MakeIdTree(astNode->referenceType.type, parent));
 | 
			
		||||
            return NULL;
 | 
			
		||||
 | 
			
		||||
        case Return:
 | 
			
		||||
            AddChildToNode(parent, MakeIdTree(astNode->returnStatement.expression, parent));
 | 
			
		||||
            return NULL;
 | 
			
		||||
 | 
			
		||||
        case StatementSequence: {
 | 
			
		||||
            for (i = 0; i < astNode->statementSequence.count; i++) {
 | 
			
		||||
                Node *argNode = astNode->statementSequence.sequence[i];
 | 
			
		||||
                AddChildToNode(parent, MakeIdTree(argNode, parent));
 | 
			
		||||
            }
 | 
			
		||||
            return NULL;
 | 
			
		||||
    case Identifier:
 | 
			
		||||
    {
 | 
			
		||||
        char *name = astNode->identifier.name;
 | 
			
		||||
        mainNode = MakeIdNode(Placeholder, name, parent);
 | 
			
		||||
        IdNode *lookupNode = LookupId(mainNode, NULL, name);
 | 
			
		||||
        if (lookupNode == NULL)
 | 
			
		||||
        {
 | 
			
		||||
            fprintf(stderr, "wraith: Could not find IdNode for id %s\n", name);
 | 
			
		||||
            TypeTag *tag = (TypeTag *)malloc(sizeof(TypeTag));
 | 
			
		||||
            tag->type = Unknown;
 | 
			
		||||
            astNode->typeTag = tag;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        case StructDeclaration: {
 | 
			
		||||
            Node *idNode = astNode->structDeclaration.identifier;
 | 
			
		||||
            Node *declsNode = astNode->structDeclaration.declarationSequence;
 | 
			
		||||
            mainNode = MakeIdNode(Struct, idNode->identifier.name, parent);
 | 
			
		||||
            mainNode->typeTag = MakeTypeTag(astNode);
 | 
			
		||||
            for (i = 0; i < declsNode->declarationSequence.count; i++) {
 | 
			
		||||
                Node *decl = declsNode->declarationSequence.sequence[i];
 | 
			
		||||
                AddChildToNode(mainNode, MakeIdTree(decl, mainNode));
 | 
			
		||||
            }
 | 
			
		||||
            break;
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            astNode->typeTag = lookupNode->typeTag;
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
        case Type:
 | 
			
		||||
            AddChildToNode(parent, MakeIdTree(astNode->type.typeNode, parent));
 | 
			
		||||
            return NULL;
 | 
			
		||||
    case IfStatement:
 | 
			
		||||
    {
 | 
			
		||||
        Node *clause = astNode->ifStatement.expression;
 | 
			
		||||
        Node *stmtSeq = astNode->ifStatement.statementSequence;
 | 
			
		||||
        mainNode = MakeIdNode(OrderedScope, "if", parent);
 | 
			
		||||
        MakeIdTree(clause, mainNode);
 | 
			
		||||
        MakeIdTree(stmtSeq, mainNode);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
        case UnaryExpression:
 | 
			
		||||
            AddChildToNode(parent, MakeIdTree(astNode->unaryExpression.child, parent));
 | 
			
		||||
            return NULL;
 | 
			
		||||
    case IfElseStatement:
 | 
			
		||||
    {
 | 
			
		||||
        Node *ifNode = astNode->ifElseStatement.ifStatement;
 | 
			
		||||
        Node *elseStmts = astNode->ifElseStatement.elseStatement;
 | 
			
		||||
        mainNode = MakeIdNode(OrderedScope, "if-else", parent);
 | 
			
		||||
        IdNode *ifBranch = MakeIdTree(ifNode, mainNode);
 | 
			
		||||
        AddChildToNode(mainNode, ifBranch);
 | 
			
		||||
        IdNode *elseScope = MakeIdNode(OrderedScope, "else", mainNode);
 | 
			
		||||
        MakeIdTree(elseStmts, elseScope);
 | 
			
		||||
        AddChildToNode(mainNode, elseScope);
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
        case Comment:
 | 
			
		||||
        case CustomTypeNode:
 | 
			
		||||
        case FunctionModifiers:
 | 
			
		||||
        case FunctionSignature:
 | 
			
		||||
        case Number:
 | 
			
		||||
        case PrimitiveTypeNode:
 | 
			
		||||
        case ReturnVoid:
 | 
			
		||||
        case StaticModifier:
 | 
			
		||||
        case StringLiteral:
 | 
			
		||||
            return NULL;
 | 
			
		||||
    case ReferenceTypeNode:
 | 
			
		||||
        AddChildToNode(parent, MakeIdTree(astNode->referenceType.type, parent));
 | 
			
		||||
        return NULL;
 | 
			
		||||
 | 
			
		||||
    case Return:
 | 
			
		||||
        AddChildToNode(
 | 
			
		||||
            parent,
 | 
			
		||||
            MakeIdTree(astNode->returnStatement.expression, parent));
 | 
			
		||||
        return NULL;
 | 
			
		||||
 | 
			
		||||
    case StatementSequence:
 | 
			
		||||
    {
 | 
			
		||||
        for (i = 0; i < astNode->statementSequence.count; i++)
 | 
			
		||||
        {
 | 
			
		||||
            Node *argNode = astNode->statementSequence.sequence[i];
 | 
			
		||||
            AddChildToNode(parent, MakeIdTree(argNode, parent));
 | 
			
		||||
        }
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    case StructDeclaration:
 | 
			
		||||
    {
 | 
			
		||||
        Node *idNode = astNode->structDeclaration.identifier;
 | 
			
		||||
        Node *declsNode = astNode->structDeclaration.declarationSequence;
 | 
			
		||||
        mainNode = MakeIdNode(Struct, idNode->identifier.name, parent);
 | 
			
		||||
        mainNode->typeTag = MakeTypeTag(astNode);
 | 
			
		||||
        for (i = 0; i < declsNode->declarationSequence.count; i++)
 | 
			
		||||
        {
 | 
			
		||||
            Node *decl = declsNode->declarationSequence.sequence[i];
 | 
			
		||||
            AddChildToNode(mainNode, MakeIdTree(decl, mainNode));
 | 
			
		||||
        }
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    case Type:
 | 
			
		||||
        AddChildToNode(parent, MakeIdTree(astNode->type.typeNode, parent));
 | 
			
		||||
        return NULL;
 | 
			
		||||
 | 
			
		||||
    case UnaryExpression:
 | 
			
		||||
        AddChildToNode(
 | 
			
		||||
            parent,
 | 
			
		||||
            MakeIdTree(astNode->unaryExpression.child, parent));
 | 
			
		||||
        return NULL;
 | 
			
		||||
 | 
			
		||||
    case Comment:
 | 
			
		||||
    case CustomTypeNode:
 | 
			
		||||
    case FunctionModifiers:
 | 
			
		||||
    case FunctionSignature:
 | 
			
		||||
    case Number:
 | 
			
		||||
    case PrimitiveTypeNode:
 | 
			
		||||
    case ReturnVoid:
 | 
			
		||||
    case StaticModifier:
 | 
			
		||||
    case StringLiteral:
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    astNode->idLink = mainNode;
 | 
			
		||||
    return mainNode;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PrintIdNode(IdNode *node) {
 | 
			
		||||
    if (node == NULL) {
 | 
			
		||||
        fprintf(stderr, "wraith: Attempted to call PrintIdNode with null value.\n");
 | 
			
		||||
void PrintIdNode(IdNode *node)
 | 
			
		||||
{
 | 
			
		||||
    if (node == NULL)
 | 
			
		||||
    {
 | 
			
		||||
        fprintf(
 | 
			
		||||
            stderr,
 | 
			
		||||
            "wraith: Attempted to call PrintIdNode with null value.\n");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    switch(node->type) {
 | 
			
		||||
        case Placeholder:
 | 
			
		||||
            printf("Placeholder (%s)\n", node->name);
 | 
			
		||||
            break;
 | 
			
		||||
        case OrderedScope:
 | 
			
		||||
            printf("OrderedScope (%s)\n", node->name);
 | 
			
		||||
            break;
 | 
			
		||||
        case UnorderedScope:
 | 
			
		||||
            printf("UnorderedScope (%s)\n", node->name);
 | 
			
		||||
            break;
 | 
			
		||||
        case Struct:
 | 
			
		||||
            printf("%s : %s\n", node->name, TypeTagToString(node->typeTag));
 | 
			
		||||
            break;
 | 
			
		||||
        case Function:
 | 
			
		||||
            printf("%s : Function<%s>\n", node->name, TypeTagToString(node->typeTag));
 | 
			
		||||
            break;
 | 
			
		||||
        case Variable:
 | 
			
		||||
            printf("%s : %s\n", node->name, TypeTagToString(node->typeTag));
 | 
			
		||||
            break;
 | 
			
		||||
    switch (node->type)
 | 
			
		||||
    {
 | 
			
		||||
    case Placeholder:
 | 
			
		||||
        printf("Placeholder (%s)\n", node->name);
 | 
			
		||||
        break;
 | 
			
		||||
    case OrderedScope:
 | 
			
		||||
        printf("OrderedScope (%s)\n", node->name);
 | 
			
		||||
        break;
 | 
			
		||||
    case UnorderedScope:
 | 
			
		||||
        printf("UnorderedScope (%s)\n", node->name);
 | 
			
		||||
        break;
 | 
			
		||||
    case Struct:
 | 
			
		||||
        printf("%s : %s\n", node->name, TypeTagToString(node->typeTag));
 | 
			
		||||
        break;
 | 
			
		||||
    case Function:
 | 
			
		||||
        printf(
 | 
			
		||||
            "%s : Function<%s>\n",
 | 
			
		||||
            node->name,
 | 
			
		||||
            TypeTagToString(node->typeTag));
 | 
			
		||||
        break;
 | 
			
		||||
    case Variable:
 | 
			
		||||
        printf("%s : %s\n", node->name, TypeTagToString(node->typeTag));
 | 
			
		||||
        break;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void PrintIdTree(IdNode *tree, uint32_t tabCount) {
 | 
			
		||||
    if (tree == NULL) {
 | 
			
		||||
        fprintf(stderr, "wraith: Attempted to call PrintIdTree on a null value.\n");
 | 
			
		||||
void PrintIdTree(IdNode *tree, uint32_t tabCount)
 | 
			
		||||
{
 | 
			
		||||
    if (tree == NULL)
 | 
			
		||||
    {
 | 
			
		||||
        fprintf(
 | 
			
		||||
            stderr,
 | 
			
		||||
            "wraith: Attempted to call PrintIdTree on a null value.\n");
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uint32_t i;
 | 
			
		||||
    for (i = 0; i < tabCount; i++) {
 | 
			
		||||
    for (i = 0; i < tabCount; i++)
 | 
			
		||||
    {
 | 
			
		||||
        printf("| ");
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    PrintIdNode(tree);
 | 
			
		||||
 | 
			
		||||
    for (i = 0; i < tree->childCount; i++) {
 | 
			
		||||
    for (i = 0; i < tree->childCount; i++)
 | 
			
		||||
    {
 | 
			
		||||
        PrintIdTree(tree->children[i], tabCount + 1);
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int PrintAncestors(IdNode *node) {
 | 
			
		||||
    if (node == NULL) return -1;
 | 
			
		||||
int PrintAncestors(IdNode *node)
 | 
			
		||||
{
 | 
			
		||||
    if (node == NULL)
 | 
			
		||||
        return -1;
 | 
			
		||||
 | 
			
		||||
    int i;
 | 
			
		||||
    int indent = 1;
 | 
			
		||||
    indent += PrintAncestors(node->parent);
 | 
			
		||||
    for (i = 0; i < indent; i++) {
 | 
			
		||||
    for (i = 0; i < indent; i++)
 | 
			
		||||
    {
 | 
			
		||||
        printf(" ");
 | 
			
		||||
    }
 | 
			
		||||
    PrintIdNode(node);
 | 
			
		||||
    return indent;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
IdNode* LookdownId(IdNode *root, NodeType targetType, char *targetName) {
 | 
			
		||||
    if (root == NULL) {
 | 
			
		||||
        fprintf(stderr, "wraith: Attempted to call LookdownId on a null value.\n");
 | 
			
		||||
IdNode *LookdownId(IdNode *root, NodeType targetType, char *targetName)
 | 
			
		||||
{
 | 
			
		||||
    if (root == NULL)
 | 
			
		||||
    {
 | 
			
		||||
        fprintf(
 | 
			
		||||
            stderr,
 | 
			
		||||
            "wraith: Attempted to call LookdownId on a null value.\n");
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    IdNode *result = NULL;
 | 
			
		||||
    IdNode **frontier = (IdNode**)malloc(sizeof(IdNode*));
 | 
			
		||||
    IdNode **frontier = (IdNode **)malloc(sizeof(IdNode *));
 | 
			
		||||
    frontier[0] = root;
 | 
			
		||||
    uint32_t frontierCount = 1;
 | 
			
		||||
 | 
			
		||||
    while (frontierCount > 0) {
 | 
			
		||||
    while (frontierCount > 0)
 | 
			
		||||
    {
 | 
			
		||||
        IdNode *current = frontier[0];
 | 
			
		||||
 | 
			
		||||
        if (current->type == targetType && strcmp(current->name, targetName) == 0) {
 | 
			
		||||
        if (current->type == targetType &&
 | 
			
		||||
            strcmp(current->name, targetName) == 0)
 | 
			
		||||
        {
 | 
			
		||||
            result = current;
 | 
			
		||||
            break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        uint32_t i;
 | 
			
		||||
        for(i = 1; i < frontierCount; i++) {
 | 
			
		||||
            frontier[i-1] = frontier[i];
 | 
			
		||||
        for (i = 1; i < frontierCount; i++)
 | 
			
		||||
        {
 | 
			
		||||
            frontier[i - 1] = frontier[i];
 | 
			
		||||
        }
 | 
			
		||||
        size_t newSize = frontierCount + current->childCount - 1;
 | 
			
		||||
        if (frontierCount != newSize) {
 | 
			
		||||
            frontier = (IdNode**) realloc(frontier, sizeof(IdNode*) * newSize);
 | 
			
		||||
        if (frontierCount != newSize)
 | 
			
		||||
        {
 | 
			
		||||
            frontier = (IdNode **)realloc(frontier, sizeof(IdNode *) * newSize);
 | 
			
		||||
        }
 | 
			
		||||
        for (i = 0; i < current->childCount; i++) {
 | 
			
		||||
        for (i = 0; i < current->childCount; i++)
 | 
			
		||||
        {
 | 
			
		||||
            frontier[frontierCount + i - 1] = current->children[i];
 | 
			
		||||
        }
 | 
			
		||||
        frontierCount = newSize;
 | 
			
		||||
| 
						 | 
				
			
			@ -305,70 +392,89 @@ IdNode* LookdownId(IdNode *root, NodeType targetType, char *targetName) {
 | 
			
		|||
    return result;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool ScopeHasOrdering(IdNode *node) {
 | 
			
		||||
    switch (node->type) {
 | 
			
		||||
        case OrderedScope:
 | 
			
		||||
        case Function:
 | 
			
		||||
        case Variable: /* this is only technically true */
 | 
			
		||||
            return true;
 | 
			
		||||
        default:
 | 
			
		||||
            return false;
 | 
			
		||||
bool ScopeHasOrdering(IdNode *node)
 | 
			
		||||
{
 | 
			
		||||
    switch (node->type)
 | 
			
		||||
    {
 | 
			
		||||
    case OrderedScope:
 | 
			
		||||
    case Function:
 | 
			
		||||
    case Variable: /* this is only technically true */
 | 
			
		||||
        return true;
 | 
			
		||||
    default:
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
IdNode* LookupId(IdNode *node, IdNode *prev, char *target) {
 | 
			
		||||
    if (node == NULL) {
 | 
			
		||||
IdNode *LookupId(IdNode *node, IdNode *prev, char *target)
 | 
			
		||||
{
 | 
			
		||||
    if (node == NULL)
 | 
			
		||||
    {
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (strcmp(node->name, target) == 0 && node->type != Placeholder) {
 | 
			
		||||
    if (strcmp(node->name, target) == 0 && node->type != Placeholder)
 | 
			
		||||
    {
 | 
			
		||||
        return node;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* If this is the start of our search, we should not attempt to look at child nodes. Only
 | 
			
		||||
     * looking up the scope tree is valid at this point.
 | 
			
		||||
    /* If this is the start of our search, we should not attempt to look at
 | 
			
		||||
     * child nodes. Only looking up the scope tree is valid at this point.
 | 
			
		||||
     *
 | 
			
		||||
     * This has the notable side-effect that this function will return NULL if you attempt to look
 | 
			
		||||
     * up a struct's internals starting from the node representing the struct itself. This is
 | 
			
		||||
     * because an IdNode corresponds to the location *where an identifier is first declared.* Thus,
 | 
			
		||||
     * an identifier has no knowledge of identifiers declared "inside" of it.
 | 
			
		||||
     * This has the notable side-effect that this function will return NULL if
 | 
			
		||||
     * you attempt to look up a struct's internals starting from the node
 | 
			
		||||
     * representing the struct itself. This is because an IdNode corresponds to
 | 
			
		||||
     * the location *where an identifier is first declared.* Thus, an identifier
 | 
			
		||||
     * has no knowledge of identifiers declared "inside" of it.
 | 
			
		||||
     */
 | 
			
		||||
    if (prev == NULL) {
 | 
			
		||||
    if (prev == NULL)
 | 
			
		||||
    {
 | 
			
		||||
        return LookupId(node->parent, node, target);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    /* If the current node forms an ordered scope then we want to prevent ourselves from looking
 | 
			
		||||
     * up identifiers declared after the scope we have just come from.
 | 
			
		||||
    /* If the current node forms an ordered scope then we want to prevent
 | 
			
		||||
     * ourselves from looking up identifiers declared after the scope we have
 | 
			
		||||
     * just come from.
 | 
			
		||||
     */
 | 
			
		||||
    uint32_t idxLimit;
 | 
			
		||||
    if (ScopeHasOrdering(node)) {
 | 
			
		||||
    if (ScopeHasOrdering(node))
 | 
			
		||||
    {
 | 
			
		||||
        uint32_t i;
 | 
			
		||||
        for (i = 0, idxLimit = 0; i < node->childCount; i++, idxLimit++) {
 | 
			
		||||
            if (node->children[i] == prev) {
 | 
			
		||||
        for (i = 0, idxLimit = 0; i < node->childCount; i++, idxLimit++)
 | 
			
		||||
        {
 | 
			
		||||
            if (node->children[i] == prev)
 | 
			
		||||
            {
 | 
			
		||||
                break;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    } else {
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        idxLimit = node->childCount;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    uint32_t i;
 | 
			
		||||
    for (i = 0; i < idxLimit; i++) {
 | 
			
		||||
    for (i = 0; i < idxLimit; i++)
 | 
			
		||||
    {
 | 
			
		||||
        IdNode *child = node->children[i];
 | 
			
		||||
        if (child == prev || child->type == Placeholder) {
 | 
			
		||||
        if (child == prev || child->type == Placeholder)
 | 
			
		||||
        {
 | 
			
		||||
            /* Do not inspect the node we just came from or placeholders. */
 | 
			
		||||
            continue;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (strcmp(child->name, target) == 0) {
 | 
			
		||||
        if (strcmp(child->name, target) == 0)
 | 
			
		||||
        {
 | 
			
		||||
            return child;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (child->type == Struct) {
 | 
			
		||||
        if (child->type == Struct)
 | 
			
		||||
        {
 | 
			
		||||
            uint32_t j;
 | 
			
		||||
            for (j = 0; j < child->childCount; j++) {
 | 
			
		||||
            for (j = 0; j < child->childCount; j++)
 | 
			
		||||
            {
 | 
			
		||||
                IdNode *grandchild = child->children[j];
 | 
			
		||||
                if (strcmp(grandchild->name, target) == 0) {
 | 
			
		||||
                if (strcmp(grandchild->name, target) == 0)
 | 
			
		||||
                {
 | 
			
		||||
                    return grandchild;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -10,7 +10,8 @@
 | 
			
		|||
struct TypeTag;
 | 
			
		||||
struct Node;
 | 
			
		||||
 | 
			
		||||
typedef enum NodeType {
 | 
			
		||||
typedef enum NodeType
 | 
			
		||||
{
 | 
			
		||||
    Placeholder,
 | 
			
		||||
    UnorderedScope,
 | 
			
		||||
    OrderedScope,
 | 
			
		||||
| 
						 | 
				
			
			@ -19,7 +20,8 @@ typedef enum NodeType {
 | 
			
		|||
    Variable
 | 
			
		||||
} NodeType;
 | 
			
		||||
 | 
			
		||||
typedef struct IdNode {
 | 
			
		||||
typedef struct IdNode
 | 
			
		||||
{
 | 
			
		||||
    NodeType type;
 | 
			
		||||
    char *name;
 | 
			
		||||
    struct TypeTag *typeTag;
 | 
			
		||||
| 
						 | 
				
			
			@ -29,18 +31,19 @@ typedef struct IdNode {
 | 
			
		|||
    uint32_t childCapacity;
 | 
			
		||||
} IdNode;
 | 
			
		||||
 | 
			
		||||
typedef struct IdStatus {
 | 
			
		||||
    enum StatusCode {
 | 
			
		||||
typedef struct IdStatus
 | 
			
		||||
{
 | 
			
		||||
    enum StatusCode
 | 
			
		||||
    {
 | 
			
		||||
        Valid,
 | 
			
		||||
    } StatusCode;
 | 
			
		||||
} IdStatus;
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
IdNode* MakeIdTree(struct Node *astNode, IdNode *parent);
 | 
			
		||||
IdNode *MakeIdTree(struct Node *astNode, IdNode *parent);
 | 
			
		||||
void PrintIdNode(IdNode *node);
 | 
			
		||||
void PrintIdTree(IdNode *tree, uint32_t tabCount);
 | 
			
		||||
int PrintAncestors(IdNode *node);
 | 
			
		||||
IdNode* LookdownId(IdNode *root, NodeType targetType, char *targetName);
 | 
			
		||||
IdNode* LookupId(IdNode *node, IdNode *prev, char* target);
 | 
			
		||||
IdNode *LookdownId(IdNode *root, NodeType targetType, char *targetName);
 | 
			
		||||
IdNode *LookupId(IdNode *node, IdNode *prev, char *target);
 | 
			
		||||
 | 
			
		||||
#endif /* WRAITH_IDENTCHECK_H */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										36
									
								
								src/main.c
								
								
								
								
							
							
						
						
									
										36
									
								
								src/main.c
								
								
								
								
							| 
						 | 
				
			
			@ -1,9 +1,9 @@
 | 
			
		|||
#include <stdlib.h>
 | 
			
		||||
#include "../lib/dropt/dropt.h"
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
 | 
			
		||||
#include "parser.h"
 | 
			
		||||
#include "codegen.h"
 | 
			
		||||
#include "identcheck.h"
 | 
			
		||||
#include "parser.h"
 | 
			
		||||
 | 
			
		||||
int main(int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
| 
						 | 
				
			
			@ -14,10 +14,27 @@ int main(int argc, char *argv[])
 | 
			
		|||
    int exitCode = EXIT_SUCCESS;
 | 
			
		||||
 | 
			
		||||
    dropt_option options[] = {
 | 
			
		||||
        { 'h', "help", "Shows help.", NULL, dropt_handle_bool, &showHelp, dropt_attr_halt },
 | 
			
		||||
        { 'v', "parse-verbose", "Shows verbose parser output.", NULL, dropt_handle_bool, &parseVerbose },
 | 
			
		||||
        { 'O', "optimize", "Sets optimization level of the output IR. Must be a value between 0 and 3.", "number", dropt_handle_uint, &optimizationLevel },
 | 
			
		||||
        { 0 } /* Required sentinel value. */
 | 
			
		||||
        {'h',
 | 
			
		||||
         "help",
 | 
			
		||||
         "Shows help.",
 | 
			
		||||
         NULL,
 | 
			
		||||
         dropt_handle_bool,
 | 
			
		||||
         &showHelp,
 | 
			
		||||
         dropt_attr_halt},
 | 
			
		||||
        {'v',
 | 
			
		||||
         "parse-verbose",
 | 
			
		||||
         "Shows verbose parser output.",
 | 
			
		||||
         NULL,
 | 
			
		||||
         dropt_handle_bool,
 | 
			
		||||
         &parseVerbose},
 | 
			
		||||
        {'O',
 | 
			
		||||
         "optimize",
 | 
			
		||||
         "Sets optimization level of the output IR. Must be a value between 0 "
 | 
			
		||||
         "and 3.",
 | 
			
		||||
         "number",
 | 
			
		||||
         dropt_handle_uint,
 | 
			
		||||
         &optimizationLevel},
 | 
			
		||||
        {0} /* Required sentinel value. */
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    dropt_context *droptContext = dropt_new_context(options);
 | 
			
		||||
| 
						 | 
				
			
			@ -33,10 +50,13 @@ int main(int argc, char *argv[])
 | 
			
		|||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        char** rest = dropt_parse(droptContext, -1, &argv[1]);
 | 
			
		||||
        char **rest = dropt_parse(droptContext, -1, &argv[1]);
 | 
			
		||||
        if (dropt_get_error(droptContext) != dropt_error_none)
 | 
			
		||||
        {
 | 
			
		||||
            fprintf(stderr, "wraith: %s\n", dropt_get_error_message(droptContext));
 | 
			
		||||
            fprintf(
 | 
			
		||||
                stderr,
 | 
			
		||||
                "wraith: %s\n",
 | 
			
		||||
                dropt_get_error_message(droptContext));
 | 
			
		||||
            exitCode = EXIT_FAILURE;
 | 
			
		||||
        }
 | 
			
		||||
        else if (showHelp)
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1,7 +1,7 @@
 | 
			
		|||
#include <stdio.h>
 | 
			
		||||
 | 
			
		||||
#include "y.tab.h"
 | 
			
		||||
#include "ast.h"
 | 
			
		||||
#include "y.tab.h"
 | 
			
		||||
 | 
			
		||||
extern FILE *yyin;
 | 
			
		||||
extern int yydebug;
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
							
								
								
									
										21
									
								
								src/util.c
								
								
								
								
							
							
						
						
									
										21
									
								
								src/util.c
								
								
								
								
							| 
						 | 
				
			
			@ -1,16 +1,17 @@
 | 
			
		|||
#include "util.h"
 | 
			
		||||
 | 
			
		||||
#include <stdlib.h>
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
char* strdup (const char* s)
 | 
			
		||||
char *strdup(const char *s)
 | 
			
		||||
{
 | 
			
		||||
  size_t slen = strlen(s);
 | 
			
		||||
  char* result = malloc(slen + 1);
 | 
			
		||||
  if(result == NULL)
 | 
			
		||||
  {
 | 
			
		||||
    return NULL;
 | 
			
		||||
  }
 | 
			
		||||
    size_t slen = strlen(s);
 | 
			
		||||
    char *result = (char *)malloc(slen + 1);
 | 
			
		||||
    if (result == NULL)
 | 
			
		||||
    {
 | 
			
		||||
        return NULL;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
  memcpy(result, s, slen+1);
 | 
			
		||||
  return result;
 | 
			
		||||
}
 | 
			
		||||
    memcpy(result, s, slen + 1);
 | 
			
		||||
    return result;
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -3,6 +3,6 @@
 | 
			
		|||
 | 
			
		||||
#include <string.h>
 | 
			
		||||
 | 
			
		||||
char* strdup (const char* s);
 | 
			
		||||
char *strdup(const char *s);
 | 
			
		||||
 | 
			
		||||
#endif /* WRAITH_UTIL_H */
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue