#ifndef WRAITH_AST_H #define WRAITH_AST_H #include /* -Wpedantic nameless union/struct silencing */ #ifndef WRAITHNAMELESS #ifdef __GNUC__ #define WRAITHNAMELESS __extension__ #else #define WRAITHNAMELESS #endif /* __GNUC__ */ #endif /* WRAITHNAMELESS */ typedef enum { AccessExpression, AllocExpression, Assignment, BinaryExpression, Comment, ConcreteGenericTypeNode, CustomTypeNode, Declaration, DeclarationSequence, ForLoop, FunctionArgumentSequence, FunctionCallExpression, FunctionDeclaration, FunctionModifiers, FunctionSignature, FunctionSignatureArguments, GenericArgument, GenericArguments, GenericDeclaration, GenericDeclarations, GenericTypeNode, Identifier, IfStatement, IfElseStatement, Number, PrimitiveTypeNode, ReferenceTypeNode, Return, ReturnVoid, StatementSequence, StaticModifier, StringLiteral, StructDeclaration, SystemCall, Type, UnaryExpression } SyntaxKind; typedef enum { Negate } UnaryOperator; typedef enum { Add, Subtract, Multiply, Mod, Equal, LessThan, GreaterThan, LogicalOr } BinaryOperator; typedef enum { Void, Bool, Int, UInt, Float, Double, String, MemoryAddress } PrimitiveType; typedef union { UnaryOperator unaryOperator; BinaryOperator binaryOperator; } Operator; typedef struct TypeTag TypeTag; typedef struct ConcreteGenericTypeTag { char *name; TypeTag **genericArguments; uint32_t genericArgumentCount; } ConcreteGenericTypeTag; struct TypeTag { enum Type { Unknown, Primitive, Reference, Custom, Generic, ConcreteGeneric } type; union { /* Valid when type = Primitive. */ PrimitiveType primitiveType; /* Valid when type = Reference. */ struct TypeTag *referenceType; /* Valid when type = Custom. */ char *customType; /* Valid when type = Generic. */ char *genericType; /* Valid when type = ConcreteGeneric */ ConcreteGenericTypeTag concreteGenericType; } value; }; typedef struct Node Node; struct Node { Node *parent; SyntaxKind syntaxKind; WRAITHNAMELESS union { struct { Node *accessee; Node *accessor; } accessExpression; struct { Node *type; } allocExpression; struct { Node *left; Node *right; } assignmentStatement; struct { Node *left; Node *right; BinaryOperator operator; } binaryExpression; struct { } comment; struct { char *name; Node *genericArguments; } concreteGenericType; struct { char *name; } customType; struct { Node *type; Node *identifier; } declaration; struct { Node **sequence; uint32_t count; } declarationSequence; struct { Node *declaration; Node *startNumber; Node *endNumber; Node *statementSequence; } forLoop; struct { Node **sequence; uint32_t count; } functionArgumentSequence; struct { Node *identifier; /* FIXME: need better name */ Node *argumentSequence; Node *genericArguments; } functionCallExpression; struct { Node *functionSignature; Node *functionBody; } functionDeclaration; struct { Node **sequence; uint32_t count; } functionModifiers; struct { Node *identifier; Node *type; Node *arguments; Node *modifiers; Node *genericDeclarations; } functionSignature; struct { Node **sequence; uint32_t count; } functionSignatureArguments; struct { Node *type; } genericArgument; struct { Node **arguments; uint32_t count; } genericArguments; struct { Node *identifier; Node *constraint; } genericDeclaration; struct { Node **declarations; uint32_t count; } genericDeclarations; struct { char *name; } genericType; struct { char *name; } identifier; struct { Node *expression; Node *statementSequence; } ifStatement; struct { Node *ifStatement; Node *elseStatement; } ifElseStatement; struct { uint64_t value; } number; struct { PrimitiveType type; } primitiveType; struct { Node *type; } referenceType; struct { Node *expression; } returnStatement; struct { } returnVoidStatement; struct { Node **sequence; uint32_t count; } statementSequence; struct { } staticModifier; /* FIXME: modifiers should just be an enum */ struct { char *string; } stringLiteral; struct { Node *identifier; Node *declarationSequence; Node *genericDeclarations; } structDeclaration; struct { Node *identifier; Node *argumentSequence; Node *genericArguments; } systemCall; struct { Node *typeNode; } type; /* FIXME: this needs a refactor */ struct { Node *child; UnaryOperator operator; } unaryExpression; }; TypeTag *typeTag; }; const char *SyntaxKindString(SyntaxKind syntaxKind); uint8_t IsPrimitiveType(Node *typeNode); Node *MakePrimitiveTypeNode(PrimitiveType type); Node *MakeCustomTypeNode(Node *identifierNode); Node *MakeReferenceTypeNode(Node *typeNode); Node *MakeConcreteGenericTypeNode( Node *identifierNode, Node *genericArgumentsNode); 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 *identifierNode, Node *typeNode, Node *argumentsNode, Node *modifiersNode, Node *genericArgumentsNode); Node *MakeFunctionDeclarationNode( Node *functionSignatureNode, Node *functionBodyNode); Node *MakeGenericDeclarationNode(Node *identifierNode, Node *constraintNode); Node *MakeEmptyGenericDeclarationsNode(); Node *StartGenericDeclarationsNode(Node *genericDeclarationNode); Node *AddGenericDeclaration( Node *genericDeclarationsNode, Node *genericDeclarationNode); Node *MakeGenericArgumentNode(Node *typeNode); Node *MakeEmptyGenericArgumentsNode(); Node *StartGenericArgumentsNode(Node *genericArgumentNode); Node *AddGenericArgument(Node *genericArgumentsNode, Node *genericArgumentNode); Node *MakeGenericTypeNode(char *name); Node *MakeStructDeclarationNode( Node *identifierNode, Node *declarationSequenceNode, Node *genericArgumentsNode); 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 *identifierNode, Node *argumentSequenceNode, Node *genericArgumentsNode); Node *MakeSystemCallExpressionNode( Node *identifierNode, Node *argumentSequenceNode, Node *genericArgumentsNode); 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 *identifierNode, Node *startNumberNode, Node *endNumberNode, Node *statementSequenceNode); void PrintNode(Node *node, uint32_t tabCount); const char *SyntaxKindString(SyntaxKind syntaxKind); /* Helper function for applying a void function generically over the children of * an AST node. Used for functions that need to traverse the entire tree but * only perform operations on a subset of node types. Such functions can match * the syntaxKinds relevant to their purpose and invoke this function in all * other cases. */ void Recurse(Node *node, void (*func)(Node *)); void LinkParentPointers(Node *node, Node *prev); TypeTag *MakeTypeTag(Node *node); char *TypeTagToString(TypeTag *tag); Node *LookupIdNode(Node *current, Node *prev, char *target); #endif /* WRAITH_AST_H */