78ef07cf0f
* Initial parser rewrite effort Lexer and Token cleanup, Parser started over * Greatly improved parser syntax * Reimplemented using declarations and variable placement parsing * Added back unions and structs * Added enums as well as mathematical expressions (+, -, *, /, <<, >>, &, |, ^) * Code style improvement * Implemented arrays and fixed memory issues * Fixed more memory issues in parser, reimplemented validator, evaluator and patterns * Fixed builtin types, arrays and reimplemented strings * Improved error messages * Made character a distinct type, used for chars and strings * Implemented padding, fixed arrays * Added bitfields * Added rvalue parsing, no evaluating yet * Added .idea folder to gitignore * Fixed build on MacOS * Added custom implementation of integral concept if not available * Rebased onto master * Fixed array variable decl crash * Added rvalues and dot syntax * Lower case all pattern language error messages * Fixed typo in variable name * Fixed bug where preprocessor would not ignore commented out directives * Reimplemented pointers * Fixed rebase issues
210 lines
8.0 KiB
C++
210 lines
8.0 KiB
C++
#pragma once
|
|
|
|
#include <hex.hpp>
|
|
|
|
#include "helpers/utils.hpp"
|
|
|
|
#include <string>
|
|
#include <variant>
|
|
|
|
namespace hex::lang {
|
|
|
|
class Token {
|
|
public:
|
|
enum class Type : u64 {
|
|
Keyword,
|
|
ValueType,
|
|
Operator,
|
|
Integer,
|
|
Identifier,
|
|
Separator
|
|
};
|
|
|
|
enum class Keyword {
|
|
Struct,
|
|
Union,
|
|
Using,
|
|
Enum,
|
|
Bitfield,
|
|
LittleEndian,
|
|
BigEndian,
|
|
};
|
|
|
|
enum class Operator {
|
|
AtDeclaration,
|
|
Assignment,
|
|
Inherit,
|
|
Plus,
|
|
Minus,
|
|
Star,
|
|
Slash,
|
|
ShiftLeft,
|
|
ShiftRight,
|
|
BitOr,
|
|
BitAnd,
|
|
BitXor
|
|
};
|
|
|
|
enum class ValueType {
|
|
Unsigned8Bit = 0x10,
|
|
Signed8Bit = 0x11,
|
|
Unsigned16Bit = 0x20,
|
|
Signed16Bit = 0x21,
|
|
Unsigned32Bit = 0x40,
|
|
Signed32Bit = 0x41,
|
|
Unsigned64Bit = 0x80,
|
|
Signed64Bit = 0x81,
|
|
Unsigned128Bit = 0x100,
|
|
Signed128Bit = 0x101,
|
|
Character = 0x13,
|
|
Float = 0x42,
|
|
Double = 0x82,
|
|
CustomType = 0x00,
|
|
Padding = 0x1F,
|
|
|
|
Unsigned = 0xFF00,
|
|
Signed = 0xFF01,
|
|
FloatingPoint = 0xFF02,
|
|
Integer = 0xFF03,
|
|
Any = 0xFFFF
|
|
};
|
|
|
|
enum class Separator {
|
|
RoundBracketOpen,
|
|
RoundBracketClose,
|
|
CurlyBracketOpen,
|
|
CurlyBracketClose,
|
|
SquareBracketOpen,
|
|
SquareBracketClose,
|
|
Comma,
|
|
Dot,
|
|
EndOfExpression,
|
|
EndOfProgram
|
|
};
|
|
|
|
using ValueTypes = std::variant<Keyword, std::string, Operator, s128, ValueType, Separator>;
|
|
|
|
Token(Type type, auto value, u32 lineNumber) : type(type), value(value), lineNumber(lineNumber) {
|
|
|
|
}
|
|
|
|
[[nodiscard]] constexpr static inline bool isUnsigned(const ValueType type) {
|
|
return (static_cast<u32>(type) & 0x0F) == 0x00;
|
|
}
|
|
|
|
[[nodiscard]] constexpr static inline bool isSigned(const ValueType type) {
|
|
return (static_cast<u32>(type) & 0x0F) == 0x01;
|
|
}
|
|
|
|
[[nodiscard]] constexpr static inline bool isFloatingPoint(const ValueType type) {
|
|
return (static_cast<u32>(type) & 0x0F) == 0x02;
|
|
}
|
|
|
|
[[nodiscard]] constexpr static inline u32 getTypeSize(const ValueType type) {
|
|
return static_cast<u32>(type) >> 4;
|
|
}
|
|
|
|
[[nodiscard]] constexpr static auto getTypeName(const lang::Token::ValueType type) {
|
|
switch (type) {
|
|
case ValueType::Signed8Bit: return "s8";
|
|
case ValueType::Signed16Bit: return "s16";
|
|
case ValueType::Signed32Bit: return "s32";
|
|
case ValueType::Signed64Bit: return "s64";
|
|
case ValueType::Signed128Bit: return "s128";
|
|
case ValueType::Unsigned8Bit: return "u8";
|
|
case ValueType::Unsigned16Bit: return "u16";
|
|
case ValueType::Unsigned32Bit: return "u32";
|
|
case ValueType::Unsigned64Bit: return "u64";
|
|
case ValueType::Unsigned128Bit: return "u128";
|
|
case ValueType::Float: return "float";
|
|
case ValueType::Double: return "double";
|
|
case ValueType::Character: return "char";
|
|
default: return "< ??? >";
|
|
}
|
|
}
|
|
|
|
bool operator==(const ValueTypes &other) const {
|
|
if (this->type == Type::Integer || this->type == Type::Identifier)
|
|
return true;
|
|
else if (this->type == Type::ValueType) {
|
|
auto otherValueType = std::get_if<ValueType>(&other);
|
|
auto valueType = std::get_if<ValueType>(&this->value);
|
|
|
|
if (otherValueType == nullptr) return false;
|
|
if (valueType == nullptr) return false;
|
|
|
|
if (*otherValueType == *valueType)
|
|
return true;
|
|
else if (*otherValueType == ValueType::Any)
|
|
return *valueType != ValueType::CustomType && *valueType != ValueType::Padding;
|
|
else if (*otherValueType == ValueType::Unsigned)
|
|
return isUnsigned(*valueType);
|
|
else if (*otherValueType == ValueType::Signed)
|
|
return isSigned(*valueType);
|
|
else if (*otherValueType == ValueType::FloatingPoint)
|
|
return isFloatingPoint(*valueType);
|
|
else if (*otherValueType == ValueType::Integer)
|
|
return isUnsigned(*valueType) || isSigned(*valueType);
|
|
}
|
|
else
|
|
return other == this->value;
|
|
|
|
return false;
|
|
}
|
|
|
|
bool operator!=(const ValueTypes &other) const {
|
|
return !operator==(other);
|
|
}
|
|
|
|
Type type;
|
|
ValueTypes value;
|
|
u32 lineNumber;
|
|
|
|
};
|
|
|
|
}
|
|
|
|
#define COMPONENT(type, value) hex::lang::Token::Type::type, hex::lang::Token::type::value
|
|
|
|
#define KEYWORD_STRUCT COMPONENT(Keyword, Struct)
|
|
#define KEYWORD_UNION COMPONENT(Keyword, Union)
|
|
#define KEYWORD_USING COMPONENT(Keyword, Using)
|
|
#define KEYWORD_ENUM COMPONENT(Keyword, Enum)
|
|
#define KEYWORD_BITFIELD COMPONENT(Keyword, Bitfield)
|
|
#define KEYWORD_LE COMPONENT(Keyword, LittleEndian)
|
|
#define KEYWORD_BE COMPONENT(Keyword, BigEndian)
|
|
|
|
#define INTEGER hex::lang::Token::Type::Integer, 0xFFFF'FFFF'FFFF'FFFF
|
|
#define IDENTIFIER hex::lang::Token::Type::Identifier, ""
|
|
|
|
#define OPERATOR_AT COMPONENT(Operator, AtDeclaration)
|
|
#define OPERATOR_ASSIGNMENT COMPONENT(Operator, Assignment)
|
|
#define OPERATOR_INHERIT COMPONENT(Operator, Inherit)
|
|
#define OPERATOR_PLUS COMPONENT(Operator, Plus)
|
|
#define OPERATOR_MINUS COMPONENT(Operator, Minus)
|
|
#define OPERATOR_STAR COMPONENT(Operator, Star)
|
|
#define OPERATOR_SLASH COMPONENT(Operator, Slash)
|
|
#define OPERATOR_SHIFTLEFT COMPONENT(Operator, ShiftLeft)
|
|
#define OPERATOR_SHIFTRIGHT COMPONENT(Operator, ShiftRight)
|
|
#define OPERATOR_BITOR COMPONENT(Operator, BitOr)
|
|
#define OPERATOR_BITAND COMPONENT(Operator, BitAnd)
|
|
#define OPERATOR_BITXOR COMPONENT(Operator, BitXor)
|
|
|
|
#define VALUETYPE_CUSTOMTYPE COMPONENT(ValueType, CustomType)
|
|
#define VALUETYPE_PADDING COMPONENT(ValueType, Padding)
|
|
#define VALUETYPE_UNSIGNED COMPONENT(ValueType, Unsigned)
|
|
#define VALUETYPE_SIGNED COMPONENT(ValueType, Signed)
|
|
#define VALUETYPE_FLOATINGPOINT COMPONENT(ValueType, FloatingPoint)
|
|
#define VALUETYPE_INTEGER COMPONENT(ValueType, Integer)
|
|
#define VALUETYPE_ANY COMPONENT(ValueType, Any)
|
|
|
|
#define SEPARATOR_ROUNDBRACKETOPEN COMPONENT(Separator, RoundBracketOpen)
|
|
#define SEPARATOR_ROUNDBRACKETCLOSE COMPONENT(Separator, RoundBracketClose)
|
|
#define SEPARATOR_CURLYBRACKETOPEN COMPONENT(Separator, CurlyBracketOpen)
|
|
#define SEPARATOR_CURLYBRACKETCLOSE COMPONENT(Separator, CurlyBracketClose)
|
|
#define SEPARATOR_SQUAREBRACKETOPEN COMPONENT(Separator, SquareBracketOpen)
|
|
#define SEPARATOR_SQUAREBRACKETCLOSE COMPONENT(Separator, SquareBracketClose)
|
|
#define SEPARATOR_COMMA COMPONENT(Separator, Comma)
|
|
#define SEPARATOR_DOT COMPONENT(Separator, Dot)
|
|
#define SEPARATOR_ENDOFEXPRESSION COMPONENT(Separator, EndOfExpression)
|
|
#define SEPARATOR_ENDOFPROGRAM COMPONENT(Separator, EndOfProgram) |