OMGPL/include/syntax_tree.hpp

233 lines
7 KiB
C++
Raw Normal View History

2021-12-09 16:33:51 +00:00
#pragma once
#include <variant>
#include <limits>
#include <vector>
#include <memory>
#include "lexer.hpp"
struct Node;
struct Variable;
struct VariableInStack;
struct Expression;
2021-12-27 13:53:28 +00:00
void SetPrintStringStream();
std::stringstream& GetPrintStringStream();
2021-12-09 16:33:51 +00:00
struct Node {
Node* parent = nullptr;
Node* next = nullptr;
Node* previous = nullptr;
void Insert(Node*);
void InsertBefore(Node*);
virtual void Run(std::vector<std::shared_ptr<VariableInStack>>& stack) = 0;
2021-12-27 12:50:56 +00:00
2021-12-09 16:33:51 +00:00
virtual ~Node() {}
};
enum class Operation {
None,
Plus,
Minus,
Star,
Slash,
Equal,
ExclamationMark,
PlusEqual,
MinusEqual,
StarEqual,
SlashEqual,
EqualEqual,
ExclamationMarkEqual,
PlusPlus,
MinusMinus,
LAngle,
RAngle,
LAngleEqual,
RAngleEqual,
Value
};
enum class PriorityType {
L, R
};
struct TypeVariable {
enum ID {
none = 0, type_int = 1, type_string = 2
};
TypeVariable() {}
2021-12-27 12:50:56 +00:00
2021-12-09 16:33:51 +00:00
TypeVariable(ID id) : id(id) {}
2021-12-27 12:50:56 +00:00
2021-12-09 16:33:51 +00:00
ID id = ID::none;
size_t size;
};
struct DeallocateStack : public Node {
DeallocateStack(size_t count) : count(count) {}
2021-12-27 12:50:56 +00:00
void Run(std::vector<std::shared_ptr<VariableInStack>>& stack) override;
2021-12-09 16:33:51 +00:00
size_t count;
};
struct HiddenDeallocateStack : public Node {
HiddenDeallocateStack(size_t count) : count(count) {}
2021-12-27 12:50:56 +00:00
void Run(std::vector<std::shared_ptr<VariableInStack>>& stack) override;
2021-12-09 16:33:51 +00:00
size_t count;
};
struct VariableInStack {
VariableInStack(TypeVariable type_variable) : type_variable(type_variable) {}
2021-12-27 12:50:56 +00:00
void CallOperator(std::shared_ptr<VariableInStack>& another, std::shared_ptr<VariableInStack>& result, Operation op);
void Clear();
void Allocate();
2021-12-09 16:33:51 +00:00
TypeVariable type_variable;
void* memory = nullptr;
2021-12-27 12:50:56 +00:00
private:
void CallEqualOperator(const std::shared_ptr<VariableInStack>& another,
std::shared_ptr<VariableInStack>& result,
const Operation& op);
void CallComparisonOperator(const std::shared_ptr<VariableInStack>& another,
std::shared_ptr<VariableInStack>& result,
const Operation& op) const;
void CallArithmeticOperator(const std::shared_ptr<VariableInStack>& another,
std::shared_ptr<VariableInStack>& result,
const Operation& op) const;
void CallEqualOperatorInt(const std::shared_ptr<VariableInStack>& another,
const std::shared_ptr<VariableInStack>& result,
const Operation& op) const;
void CallEqualOperatorString(const std::shared_ptr<VariableInStack>& another,
const std::shared_ptr<VariableInStack>& result,
const Operation& op) const;
2021-12-09 16:33:51 +00:00
};
struct Variable : public Node {
Variable(std::string type, std::string name) : type(std::move(type)), name(std::move(name)) {}
2021-12-27 12:50:56 +00:00
2021-12-09 16:33:51 +00:00
void Run(std::vector<std::shared_ptr<VariableInStack>>& stack) override;
std::string type;
std::string name;
Expression* default_value = nullptr;
// TYPE
// STORAGE
};
struct Container : public Node {
void AddChildren(Node*);
2021-12-27 12:50:56 +00:00
void Run(std::vector<std::shared_ptr<VariableInStack>>& stack) override;
2021-12-09 16:33:51 +00:00
Node* children_begin = nullptr;
Node* children_end = nullptr;
};
struct CodeBlock : public Container {};
struct CreateVariables : Node {
CreateVariables(size_t count) : count(count) {}
2021-12-27 12:50:56 +00:00
2021-12-09 16:33:51 +00:00
void Run(std::vector<std::shared_ptr<VariableInStack>>& stack) override {}
2021-12-27 12:50:56 +00:00
2021-12-09 16:33:51 +00:00
size_t count;
};
struct CallFunction : public Node {
CallFunction(std::string name_function) : name_function(std::move(name_function)) {}
2021-12-27 12:50:56 +00:00
2021-12-09 16:33:51 +00:00
void Run(std::vector<std::shared_ptr<VariableInStack>>& stack) override;
std::string name_function;
std::vector<Expression*> parameters;
};
using stack_pointer = size_t;
struct Expression : public Node {
using Types = std::variant<std::string, Expression*, stack_pointer>;
2021-12-27 12:50:56 +00:00
2021-12-09 16:33:51 +00:00
Expression() {}
2021-12-27 12:50:56 +00:00
Expression(Types type1, Types type2, Operation op);
void AddStackPointer(stack_pointer d);
void Run(std::vector<std::shared_ptr<VariableInStack>>& stack) override;
2021-12-09 16:33:51 +00:00
static size_t GetPriority(Operation);
static PriorityType GetPriorityType(Operation);
static Operation Convert(Lexer::LexerToken::Type);
Types type1, type2;
Operation op = Operation::None;
stack_pointer position_result = 0;
size_t count;
};
2021-12-27 12:50:56 +00:00
struct BlockFor : public Node {
void Run(std::vector<std::shared_ptr<VariableInStack>>& stack) override;
2021-12-09 16:33:51 +00:00
Variable* var = nullptr;
Expression* check = nullptr;
Expression* tick = nullptr;
CodeBlock* code = nullptr;
};
2021-12-27 12:50:56 +00:00
struct BlockIf : public Node {
void Run(std::vector<std::shared_ptr<VariableInStack>>& stack) override;
2021-12-09 16:33:51 +00:00
Expression* check = nullptr;
CodeBlock* code = nullptr;
};
2021-12-27 12:50:56 +00:00
struct BlockWhile : public Node {
void Run(std::vector<std::shared_ptr<VariableInStack>>& stack) override;
2021-12-09 16:33:51 +00:00
Expression* check = nullptr;
CodeBlock* code = nullptr;
};
class SyntaxTree {
public:
SyntaxTree() {}
2021-12-27 12:50:56 +00:00
2021-12-09 16:33:51 +00:00
void PushLexerTokenList(const LexerTokenList&);
void Compile();
void Run();
private:
bool IsTypeName(Node*, const std::string&);
bool IsVariableName(Node*, const std::string&);
bool IsFunctionName(Node*, const std::string&);
CodeBlock* ParseCurlyBrackets(Container*, const LexerTokenList&, LexerTokenList::const_iterator&);
void PushCurlyBrackets(Container*, const LexerTokenList&, LexerTokenList::const_iterator&);
void PushRoundBrackets(Container*, const LexerTokenList&, LexerTokenList::const_iterator&);
void PushFunction(Container*, const LexerTokenList&, LexerTokenList::const_iterator&);
void PushLine(Container*, const LexerTokenList&, LexerTokenList::const_iterator&);
Variable* ParseNewVariable(const LexerTokenList&, LexerTokenList::const_iterator&);
void PushNewVariable(Container*, const LexerTokenList&, LexerTokenList::const_iterator&);
void PushExpression(Container*, const LexerTokenList&, LexerTokenList::const_iterator&);
void PushParametersFunction(CallFunction*, const LexerTokenList&, LexerTokenList::const_iterator&);
void PushCallFunction(Container*, const LexerTokenList&, LexerTokenList::const_iterator&);
2021-12-27 12:50:56 +00:00
void PushBlockFor(Container* container, const LexerTokenList& list, LexerTokenList::const_iterator& it);
void PushSignatureBlockFor(BlockFor* node_for, const LexerTokenList& list, LexerTokenList::const_iterator& it);
void PushBlockIf(Container* container, const LexerTokenList& list, LexerTokenList::const_iterator& it);
void PushSignatureBlockIf(BlockIf* node_if, const LexerTokenList& list, LexerTokenList::const_iterator& it);
void PushBlockWhile(Container* container, const LexerTokenList& list, LexerTokenList::const_iterator& it);
void PushSignatureBlockWhile(BlockWhile* node_if, const LexerTokenList& list, LexerTokenList::const_iterator& it);
2021-12-09 16:33:51 +00:00
Expression* ParseExpression(LexerTokenList::const_iterator, LexerTokenList::const_iterator);
Expression* ParseExpression(const LexerTokenList&, LexerTokenList::const_iterator&);
void PushDeallocateStack(Node*, size_t);
stack_pointer GetCountStackOffsetForVariable(Node* node, std::string name);
void LinkVariables(Node*);
void LinkVariablesInExpression(Expression*, Node*);
CodeBlock* tree_ = nullptr;
};