#pragma once #include #include #include #include "TocParser.h" using namespace std; // This contains a 1 to 1 representation of the defined language struct Type; struct Variable; struct Body; struct Function; struct Struct; struct Namespace; struct Program; struct FuncExpr; struct MethodExpr; struct LitExpr; struct ParenExpr; struct DotExpr; struct PrefixOperatorExpr; struct PostfixOperatorExpr; struct BinaryOperatorExpr; struct TernaryOperatorExpr; struct BracketsExpr; struct IdentifierExpr; struct Expr; struct IfStmt; struct SwitchStmt; struct ForStmt; struct WhileStmt; struct AssignStmt; struct ReturnStmt; struct Stmt; // Context is a collection of everything that can be defined in a namespace // that is reused for bodies so that the hierarchy can be walked uniformly // both up and down using the parent variable struct Context { std::optional name; std::shared_ptr parent; std::vector variables; std::vector functions; std::vector structs; std::vector namespaces; }; enum class TypeModifierType { Pointer, Array }; struct TypeModifier { TypeModifierType type; bool _staticArray; int _arraySize; }; struct Type { std::vector namespacePrefixes; std::string name; std::vector modifiers; std::vector genericInstantiation; bool operator!=(const Type & that) { if (this->name != that.name) return true; for (int i = 0; i < this->modifiers.size(); i++) if (this->modifiers[i].type != that.modifiers[i].type) return true; for (int i = 0; i < this->namespacePrefixes.size(); i++) if (this->namespacePrefixes[i] != that.namespacePrefixes[i]) return true; return false; } }; struct Variable { std::string name; Type type; }; struct Body { std::shared_ptr ctx; std::vector statements; }; struct Function { std::string name; Type returnType; std::vector parameters; bool defined; std::vector genericTypeNames; std::vector> genericInstantiations; Body body; }; template struct StructMember { T t; bool isPublic; operator T() { return t; } }; struct Struct { std::string name; std::vector genericTypeNames; std::vector> genericInstantiations; std::vector> members; std::vector> methods; }; struct Namespace { std::string name; std::shared_ptr ctx; }; struct Program { std::shared_ptr ctx; }; enum class ExprType { Func, Method, Lit, Paren, Dot, PrefixOp, PostfixOp, BinaryOp, TernaryOp, Bracket, Identifier }; struct FuncExpr { std::vector namespacePrefixes; std::string functionName; std::vector arguments; std::vector genericInstantiation; }; struct MethodExpr { std::shared_ptr expr; std::string methodName; std::vector arguments; std::vector genericInstantiation; }; enum class LitType { Int, Decimal, String, Bool }; struct LitExpr { LitType type; int _int; double _decimal; std::string _string; bool _bool; }; struct ParenExpr { std::shared_ptr expr; }; struct DotExpr { bool isPointer; std::shared_ptr expr; std::string identifier; }; // OperatorType enum with corresponding string array to lookup // enum from string and the other way round enum class PrefixOperatorType { Plus, Minus, Increment, Decrement, LogicalNot, BitwiseNot, Dereference, AddressOf, COUNT }; static std::string PrefixOperatorTypeStrings[] = { "+", "-", "++", "--", "!", "~", "*", "&" }; struct PrefixOperatorExpr { PrefixOperatorType type; std::shared_ptr expr; }; enum class PostfixOperatorType { Increment, Decrement, COUNT }; static std::string PostfixOperatorTypeStrings[] = { "++", "--" }; struct PostfixOperatorExpr { PostfixOperatorType type; std::shared_ptr expr; }; enum class BinaryOperatorType { Plus, Minus, Multiply, Divide, Modulo, BitwiseAnd, BitwiseOr, BitwiseXor, LessThan, GreaterThan, LeftShift, RightShift, LogicalAnd, LogicalOr, Equals, NotEquals, LessThanEquals, GreaterThanEquals, BitwiseAndEquals, BitwiseOrEquals, BitwiseXorEquals, PlusEquals, MinusEquals, MultiplyEquals, DivideEquals, ModuloEquals, LeftShiftEquals, RightShiftEquals, COUNT }; static std::string BinaryOperatorTypeStrings[] = { "+", "-", "*", "/", "%", "&", "|", "^", "<", ">", "<<",">>","&&","||","==","!=","<=",">=","&=","|=","^=", "+=","-=","*=","/=","%=", "<<=",">>=" }; struct BinaryOperatorExpr { BinaryOperatorType type; std::shared_ptr lexpr; std::shared_ptr rexpr; }; struct TernaryOperatorExpr { std::shared_ptr lexpr; std::shared_ptr rexprTrue; std::shared_ptr rexprFalse; }; struct BracketsExpr { std::shared_ptr lexpr; std::shared_ptr rexpr; }; struct IdentifierExpr { std::vector namespacePrefixes; std::string identifier; }; struct Expr { ExprType type; FuncExpr _func; MethodExpr _method; LitExpr _lit; ParenExpr _paren; DotExpr _dot; PrefixOperatorExpr _prefixOp; PostfixOperatorExpr _postfixOp; BinaryOperatorExpr _binaryOp; TernaryOperatorExpr _ternaryOp; BracketsExpr _brackets; IdentifierExpr _identifier; }; enum class StmtType { If, Switch, For, While, Assign, Return, Expr }; struct ElseStmt { bool _if; std::shared_ptr expr; Body body; }; struct IfStmt { Expr condition; Body body; std::vector elses; }; struct SwitchCase { std::shared_ptr expr; Body body; }; struct SwitchStmt { std::shared_ptr ident; std::vector cases; }; // TODO: int i = 0 (var decl) struct ForStmt { std::shared_ptr init; std::shared_ptr condition; std::shared_ptr action; Body body; }; struct WhileStmt { Expr condition; Body body; }; struct AssignStmt { Expr lexpr, rexpr; }; struct ReturnStmt { Expr expr; }; struct Stmt { StmtType type; IfStmt _if; SwitchStmt _switch; ForStmt _for; WhileStmt _while; AssignStmt _assign; ReturnStmt _return; Expr _expr; };