#ifndef TYPES_H #define TYPES_H #include #include #include #include #include #include #include #include using namespace std; /** * Types definition */ struct Type; enum class TypeType { Int, Double, Void, Function }; using ArgDefinition = tuple; using FunctionPrototype = vector; using TypeData = variant; struct Type { TypeType type; TypeData data { }; }; /** * Tokens definition */ enum class TokenType { Identifier, Litteral, Plus, Minus, DoublePlus, DoubleMinus, DoubleEqual, Land, Lor, Lt, Gt, Leq, Geq, NotEqual, Not, Star, Slash, Percent, Equal, Semicolon, LParenthese, RParenthese, LCurlyBracket, RCurlyBracket, If, Else, While, For, Break, Continue, Return, Comma }; using TokenData = variant; struct CodePosition { int line; int column; }; struct Token { TokenType type; TokenData data { }; CodePosition pos; }; using StackTraceEntry = tuple; using StackTrace = vector; /** Grammar: Prog -> Instruction Prog | Instruction Instruction -> Statement | ExprStatement; | Expr; | ; Statement -> | { Prog } | If (Expr) Instruction | If (Expr) Instruction Else Instruction | While (Expr) Instruction | For (Expr | ExprStatement; Expr; Expr) Instruction | Continue ; | Break ; | Return ; | Return Expr ; | Type ParIdentifier ( Args ) ; | Type ParIdentifier ( Args ) { Prog } ExprStatement -> | Type ParIdentifier = Expr // AssignedDeclaration | Type ParIdentifier // Declaration Args -> Type ParIdentifier, Args | Type ParIdentifier | void Expr -> Comp, Expr | Comp Comp -> | Sum | Sum == Comp | Sum != Comp | Sum < Comp | Sum > Comp | Sum <= Comp | Sum >= Comp | Sum && Comp | Sum || Comp Sum -> | Term | Term + Sum | Term - Sum Term -> | Unary | Unary * Term | Unary / Term | Unary % Term Unary -> | Val | - Unary | + Unary | ! Unary Val -> | Litteral | ++ParIdentifier | --ParIdentifier | ParIdentifier = Expr // Assignment | ParIdentifier++ | ParIdentifier-- | ParIdentifier // This makes the grammar ambiguous but simpler to parse | (Expr) | ParIdentifier ( Expr ) // FunctionCall ParIdentifier -> | Identifier | (ParIdentifier) */ /** * Type de Noeuds */ enum class NodeType { /* On ne créé pas de nouveau noeud -> ; Prog */ Prog, // -> Instruction Prog Epsilon, // -> ; AssignedDeclaration, // -> Type Identifier = Expr Declaration, // -> Type Identifier Plus, // -> Term + Sum Minus, // -> Term - Sum Mult, // -> Unary * Term Div, // -> Unary / Term Mod, // -> Unary % Term UnaryMinus, // -> - Unary UnaryPlus, // -> + Unary Neg, // -> ! Unary Assignment, // -> Identifier = Expr LIncr, // -> ++ParIdentifier RIncr, // -> ParIdentifier++ LDecr, // -> --ParIdentifier RDecr, // -> ParIdentifier-- If, // -> If (Expr) Instruction IfElse, // -> If (Expr) Instruction Else Instruction For, // -> For (Expr) Instruction While, // -> While (Expr/ ExprStatement; Expr; Expr) Instruction Bloc, // -> { Prog } Lt, // -> Sum < Comp Gt, // -> Sum > Comp Leq, // -> Sum <= Comp Geq, // -> Sum >= Comp Eq, // -> Sum == Comp Neq, // -> Sum != Comp Land, // -> Sum && Comp Lor, // -> Sum || Comp Comma, // -> Comp, Expr FunctionPrototype, // -> Type ParIdentifier ( Args ) ; FunctionDeclaration, // -> Type ParIdentifier ( Args ) { Prog } FunctionCall, // -> ParIdentifier ( Expr ) FunctionArgs, // -> Type ParIdentifier, Args | Type ParIdentifier | void FunctionArgsValues, // as Expr, but returns a vector of comp instead of a tree Return, // -> Return ; | Return Expr ; }; /** * InnerNode: noeud interne * Token: feuille */ struct InnerNode; using Node = variant; /** * Noeud interne */ struct InnerNode { NodeType type; vector children; CodePosition pos; }; // A Leaf is always corresponding to a Token /** * Node: AST * tokens: tokens pas encore parsés */ struct ParseReturn { Node node; vector tokens; }; /** * Interpreter */ struct MemoryVar; using Closure = unordered_map>; using UserFunction = tuple; enum class InternalCall { ClearMemory, DumpMemory, DumpHistory }; using Function = variant; using EvalResult = variant; enum class ScopeType { Block, Function, For }; struct MemoryVar { EvalResult value; Type type; bool initialized; string identifier; }; struct Scope { unordered_map vars; int depth; ScopeType type; MemoryVar* fn; CodePosition entry_pos; }; #endif