MalachScript/src/Parser/Parser.hpp

198 lines
12 KiB
C++

#ifndef MALACHSCRIPT_PARSER_HPP
#define MALACHSCRIPT_PARSER_HPP
#include <functional>
#include "../CoreData/Operators.hpp"
#include "../Diagnostics/Logger.hpp"
#include "../Utils/ScopedPtr.hpp"
#include "Lexer/LexToken.hpp"
#include "Statements/ParsedStatement.hpp"
namespace MalachScript::Parser {
class Parser {
public:
static const ParsedScriptStatement* Parse(const LexToken* firstToken, Diagnostics::Logger* diagnostics);
private:
using log_func = const std::function<void(Diagnostics::DiagnosticLevel level, Diagnostics::DiagnosticType,
const ScriptTextSpan&, const std::vector<std::string>&)>;
/////////////////////////////////////////////////////////////////////////////////////////
// Underlying functions are laid out in the order they are defined in the grammar.ebnf //
/////////////////////////////////////////////////////////////////////////////////////////
static inline bool ParseIdentifier(Identifier& out, const LexToken* token) {
if (token->GetKind() != LexTokenKind::Identifier) {
return false;
}
out = reinterpret_cast<const IdentifierToken*>(token)->GetValue();
return true;
}
static inline bool ParseAssignOp(AssignmentOperator& op, const LexToken*& token) {
switch (token->GetKind()) {
case LexTokenKind::EqualsSymbol: op = AssignmentOperator::Assignment; return true;
case LexTokenKind::PlusEqualsSymbol: op = AssignmentOperator::AdditionAssignment; return true;
case LexTokenKind::MinusEqualsSymbol: op = AssignmentOperator::SubtractionAssignment; return true;
case LexTokenKind::StarEqualsSymbol: op = AssignmentOperator::MultiplicationAssignment; return true;
case LexTokenKind::SlashEqualsSymbol: op = AssignmentOperator::DivisionAssignment; return true;
case LexTokenKind::VerticalLineEqualsSymbol: op = AssignmentOperator::BitwiseOrAssignment; return true;
case LexTokenKind::AmpersandEqualsSymbol: op = AssignmentOperator::BitwiseAndAssignment; return true;
case LexTokenKind::CaretEqualsSymbol: op = AssignmentOperator::BitwiseXorAssignment; return true;
case LexTokenKind::PercentEqualsSymbol: op = AssignmentOperator::ModuloAssignment; return true;
case LexTokenKind::StarStarEqualsSymbol: op = AssignmentOperator::ExponentiationAssignment; return true;
case LexTokenKind::LessThanLessThanEqualsSymbol:
op = AssignmentOperator::BitwiseLeftShiftAssignment;
return true;
case LexTokenKind::GreaterThanGreaterThanEqualsSymbol:
op = AssignmentOperator::BitwiseRightShiftAssignment;
return true;
case LexTokenKind::GreaterThanGreaterThanGreaterThanEqualsSymbol:
op = AssignmentOperator::ArithmeticRightShiftAssignment;
return true;
default: return false;
}
}
static inline bool ParseLogicOp(LogicOperator& op, const LexToken*& token) {
switch (token->GetKind()) {
case LexTokenKind::AmpersandAmpersandSymbol:
case LexTokenKind::AndKeyword: op = LogicOperator::LogicalAnd; return true;
case LexTokenKind::VerticalLineVerticalLineSymbol:
case LexTokenKind::OrKeyword: op = LogicOperator::LogicalOr; return true;
case LexTokenKind::CaretCaretSymbol:
case LexTokenKind::XorKeyword: op = LogicOperator::LogicalXor; return true;
default: return false;
}
}
static inline bool ParseCompOp(ComparisonOperator& op, const LexToken*& token) {
switch (token->GetKind()) {
case LexTokenKind::EqualsEqualsSymbol: op = ComparisonOperator::Equality; return true;
case LexTokenKind::ExclamationMarkEqualsSymbol: op = ComparisonOperator::Inequality; return true;
case LexTokenKind::LessThanSymbol: op = ComparisonOperator::LessThan; return true;
case LexTokenKind::LessThanEqualsSymbol: op = ComparisonOperator::LessThanEquals; return true;
case LexTokenKind::GreaterThanSymbol: op = ComparisonOperator::GreaterThan; return true;
case LexTokenKind::GreaterThanEqualsSymbol: op = ComparisonOperator::GreaterThanEquals; return true;
case LexTokenKind::IsKeyword: op = ComparisonOperator::Identity; return true;
case LexTokenKind::ExclamationMarkIsSymbol: op = ComparisonOperator::InverseIdentity; return true;
default: return false;
}
}
static inline bool ParseMathOp(MathOperator& op, const LexToken*& token) {
switch (token->GetKind()) {
case LexTokenKind::PlusSymbol: op = MathOperator::Addition; return true;
case LexTokenKind::MinusSymbol: op = MathOperator::Subtraction; return true;
case LexTokenKind::StarSymbol: op = MathOperator::Multiplication; return true;
case LexTokenKind::SlashSymbol: op = MathOperator::Division; return true;
case LexTokenKind::PercentSymbol: op = MathOperator::Modulo; return true;
case LexTokenKind::StarStarSymbol: op = MathOperator::Exponentiation; return true;
default: return false;
}
}
static inline bool ParseBitOp(BitOperator& op, const LexToken*& token) {
switch (token->GetKind()) {
case LexTokenKind::AmpersandSymbol: op = BitOperator::BitwiseAnd; return true;
case LexTokenKind::VerticalLineSymbol: op = BitOperator::BitwiseOr; return true;
case LexTokenKind::CaretSymbol: op = BitOperator::BitwiseXor; return true;
case LexTokenKind::LessThanLessThanSymbol: op = BitOperator::BitwiseLeftShift; return true;
case LexTokenKind::GreaterThanGreaterThanSymbol: op = BitOperator::BitwiseRightShift; return true;
case LexTokenKind::GreaterThanGreaterThanGreaterThanSymbol:
op = BitOperator::ArithmeticRightShift;
return true;
default: return false;
}
}
static bool ParsePrimType(Identifier& out, const LexToken*& currentToken, const log_func&);
static bool ParseDataType(Identifier& out, const LexToken*& currentToken, const log_func&);
static bool ParseScope(std::vector<Identifier>& out, const LexToken*& currentToken, const log_func&);
static bool ParseType(ScopedPtr<const ParsedTypeStatement>& out, const LexToken*& currentToken,
const log_func&);
static bool ParseAssign(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken, const log_func&);
// InitList
inline static bool ParsePreOp(PreOperator& op, const LexToken*& token, const log_func&) {
switch (token->GetKind()) {
case LexTokenKind::MinusSymbol: op = PreOperator::Negation; return true;
case LexTokenKind::PlusSymbol: op = PreOperator::Identity; return true;
case LexTokenKind::ExclamationMarkSymbol: op = PreOperator::Inversion; return true;
case LexTokenKind::PlusPlusSymbol: op = PreOperator::Increment; return true;
case LexTokenKind::MinusMinusSymbol: op = PreOperator::Decrement; return true;
case LexTokenKind::TildeSymbol: op = PreOperator::BitwiseComplement; return true;
case LexTokenKind::AtSymbol: op = PreOperator::Handle; return true;
default: return false;
}
}
// ArgList
// FuncCall
// ConstructCall
static bool ParseVarAccess(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken,
const log_func&);
// Cast
static bool ParseLiteral(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken, const log_func&);
static bool ParseTypeMod(TypeMod& typeMod, const LexToken*& currentToken, const log_func&);
// Lambda
static bool ParseExprValue(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken,
const log_func&);
// ExprPostOp
static bool ParseExprTerm(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken,
const log_func&);
static bool ParseExpr(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken, const log_func&);
static bool ParseTernary(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken, const log_func&);
static bool ParseReturn(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken, const log_func&);
static bool ParseExprStat(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken,
const log_func&);
static bool ParseContinue(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken,
const log_func&);
static bool ParseBreak(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken, const log_func&);
static bool ParseIfStatement(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken,
const log_func&);
static bool ParseForStatement(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken,
const log_func&);
static bool ParseWhileStatement(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken,
const log_func&);
static bool ParseDoWhileStatement(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken,
const log_func&);
static bool ParseTryStatement(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken,
const log_func&);
static bool ParseCaseStatement(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken,
const log_func&);
static bool ParseSwitchStatement(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken,
const log_func&);
static bool ParseStatement(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken,
const log_func&);
static bool ParseVar(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken, const log_func&);
static bool ParseStatBlock(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken,
const log_func&);
static bool ParseFuncAttr(FuncAttr& out, const LexToken*& currentToken, const log_func&);
static bool ParseParamList(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken,
const log_func&);
static bool ParseVirtProp(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken,
const log_func&);
static bool ParseFunc(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken, const log_func&);
static bool ParseFuncDef(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken, const log_func&);
static bool ParseClass(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken, const log_func&);
// Mixin
// Enum
// Import
static bool ParseTypeDef(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken, const log_func&);
// InterfaceMethod
// Interface
static bool ParseNamespace(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken,
const log_func&);
static bool ParseScript(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken, const log_func&);
};
}
#endif // MALACHSCRIPT_PARSER_HPP