c-repl/src/include/types.hpp

236 lines
5.4 KiB
C++

#ifndef TYPES_H
#define TYPES_H
#include <variant>
#include <string>
#include <unordered_map>
#include <list>
#include <vector>
#include <stdexcept>
#include <tuple>
#include <functional>
using namespace std;
/**
* Types definition
*/
struct Type;
enum class TypeType {
Int, Double, Void, Function
};
using ArgDefinition = tuple<Type, string>;
using FunctionPrototype = vector<ArgDefinition>;
using TypeData = variant<monostate, FunctionPrototype>;
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<monostate, int, double, string, Type>;
struct CodePosition {
int line;
int column;
};
struct Token {
TokenType type;
TokenData data { };
CodePosition pos;
};
using StackTraceEntry = tuple<string, CodePosition>;
using StackTrace = vector<StackTraceEntry>;
/** 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<InnerNode, Token>;
/**
* Noeud interne
*/
struct InnerNode {
NodeType type;
vector<Node> children;
CodePosition pos;
};
// A Leaf is always corresponding to a Token
/**
* Node: AST
* tokens: tokens pas encore parsés
*/
struct ParseReturn {
Node node;
vector<Token> tokens;
};
/**
* Interpreter
*/
struct MemoryVar;
using Closure = unordered_map<string, reference_wrapper<MemoryVar>>;
using UserFunction = tuple<Node, Closure>;
enum class InternalCall {
ClearMemory, DumpMemory, DumpHistory
};
using Function = variant<UserFunction, InternalCall>;
using EvalResult = variant<monostate, int, double, Function>;
enum class ScopeType { Block, Function, For };
struct MemoryVar {
EvalResult value;
Type type;
bool initialized;
string identifier;
};
struct Scope {
unordered_map<string, MemoryVar> vars;
int depth;
ScopeType type;
MemoryVar* fn;
CodePosition entry_pos;
};
#endif