236 lines
5.4 KiB
C++
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 |