Rework text spans a bit to include script file, make binder log an error when two classes have a circular value reference.
continuous-integration/drone/push Build is failing
Details
continuous-integration/drone/push Build is failing
Details
This commit is contained in:
parent
8660933f27
commit
59af34fac9
|
@ -27,13 +27,13 @@ namespace MalachScriptRepl {
|
|||
auto logger = MalachScript::Diagnostics::Logger();
|
||||
auto lexer = MalachScript::Parser::Lexer("diag", script, &logger);
|
||||
const auto* firstToken = lexer.Lex();
|
||||
const auto* parsedResult = MalachScript::Parser::Parser::Parse(firstToken, "diag", &logger);
|
||||
const auto* parsedResult = MalachScript::Parser::Parser::Parse(firstToken, &logger);
|
||||
|
||||
auto* ns = new MalachScript::Binder::BoundNamespace();
|
||||
const MalachScript::Binder::Binder::log_func log =
|
||||
[&logger](MalachScript::Diagnostics::DiagnosticLevel level, MalachScript::Diagnostics::DiagnosticType type,
|
||||
const MalachScript::TextSpan& span,
|
||||
const std::vector<std::string>& formats) { logger.Log(level, type, "", span, formats); };
|
||||
const MalachScript::ScriptTextSpan& span,
|
||||
const std::vector<std::string>& formats) { logger.Log(level, type, span, formats); };
|
||||
MalachScript::Binder::Binder::Bind(ns, {parsedResult}, log);
|
||||
|
||||
const MalachScript::Diagnostics::Diagnostic* diag = nullptr;
|
||||
|
|
|
@ -66,7 +66,7 @@ namespace MalachScript::Binder {
|
|||
break;
|
||||
}
|
||||
|
||||
type = new BoundType(identifier, s->GetClassAttr());
|
||||
type = new BoundType(identifier, s->GetClassAttr(), s->GetSpan());
|
||||
if (activeType.has_value()) {
|
||||
activeType.value()->RegisterType(identifier, type.value());
|
||||
} else {
|
||||
|
@ -210,9 +210,39 @@ namespace MalachScript::Binder {
|
|||
}
|
||||
}
|
||||
|
||||
static void FinaliseType(BoundType* type, std::vector<const BoundType*>& stack, const Binder::log_func& log) {
|
||||
if (type->IsInitialised()) {
|
||||
return;
|
||||
}
|
||||
if (std::find(stack.begin(), stack.end(), type) != stack.end()) {
|
||||
log(Diagnostics::DiagnosticLevel::Error, Diagnostics::DiagnosticType::CircularTypeReference,
|
||||
type->GetSpan().value(),
|
||||
{stack[stack.size() - 1]->GetIdentifier().GetStdString(), type->GetIdentifier().GetStdString()});
|
||||
return;
|
||||
}
|
||||
|
||||
stack.push_back(type);
|
||||
size_t size = 0;
|
||||
for (auto& inherits : type->GetInherits()) {
|
||||
if (!inherits->IsInitialised()) {
|
||||
FinaliseType(const_cast<BoundType*>(inherits), stack, log);
|
||||
}
|
||||
size += inherits->GetSize();
|
||||
}
|
||||
for (auto& field : type->GetFieldsLookup()) {
|
||||
if (!field.second->GetType()->IsInitialised()) {
|
||||
FinaliseType(const_cast<BoundType*>(field.second->GetType()), stack, log);
|
||||
}
|
||||
size += field.second->GetType()->GetSize();
|
||||
}
|
||||
stack.pop_back();
|
||||
type->Finalise(size);
|
||||
}
|
||||
|
||||
static void FinaliseNamespace(BoundNamespace* ns, const Binder::log_func& log) {
|
||||
std::vector<const BoundType*> s = {};
|
||||
for (const auto& t : ns->GetTypes()) {
|
||||
t.second->Finalise();
|
||||
FinaliseType(t.second, s, log);
|
||||
}
|
||||
for (const auto& n : ns->GetNamespaces()) {
|
||||
FinaliseNamespace(n.second, log);
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace MalachScript::Binder {
|
|||
class Binder {
|
||||
public:
|
||||
using log_func = const std::function<void(Diagnostics::DiagnosticLevel level, Diagnostics::DiagnosticType,
|
||||
const TextSpan&, const std::vector<std::string>&)>;
|
||||
const ScriptTextSpan&, const std::vector<std::string>&)>;
|
||||
|
||||
static void Bind(BoundNamespace* ns,
|
||||
const std::vector<const MalachScript::Parser::ParsedStatement*>& statements,
|
||||
|
|
|
@ -1,34 +1,30 @@
|
|||
#ifndef MALACHSCRIPT_BOUNDTYPE_HPP
|
||||
#define MALACHSCRIPT_BOUNDTYPE_HPP
|
||||
|
||||
#include <functional>
|
||||
#include <unordered_map>
|
||||
#include <vector>
|
||||
#include "../CoreData/ClassAttr.hpp"
|
||||
#include "../CoreData/Identifier.hpp"
|
||||
#include "../Diagnostics/Logger.hpp"
|
||||
#include "BoundVariable.hpp"
|
||||
|
||||
namespace MalachScript::Binder {
|
||||
class BoundType {
|
||||
public:
|
||||
BoundType(Identifier identifier, ClassAttr classAttr) : _identifier(identifier), _classAttr(classAttr) {}
|
||||
BoundType(Identifier identifier, ClassAttr classAttr, size_t size)
|
||||
: _identifier(identifier), _classAttr(classAttr), _size(size), _inherits(0) {}
|
||||
using log_func = const std::function<void(Diagnostics::DiagnosticLevel level, Diagnostics::DiagnosticType,
|
||||
const ScriptTextSpan&, const std::vector<std::string>&)>;
|
||||
|
||||
inline void Finalise() noexcept {
|
||||
if (_initialised) {
|
||||
return;
|
||||
}
|
||||
BoundType(Identifier identifier, ClassAttr classAttr, std::optional<ScriptTextSpan> span)
|
||||
: _identifier(identifier), _classAttr(classAttr), _span(span) {}
|
||||
BoundType(Identifier identifier, ClassAttr classAttr, size_t size)
|
||||
: _initialised(true), _identifier(identifier), _classAttr(classAttr), _size(size), _inherits(0) {}
|
||||
|
||||
void Finalise(size_t size) noexcept {
|
||||
_initialised = true;
|
||||
for (auto& inherits : _inherits) {
|
||||
if (!inherits->IsInitialised()) {
|
||||
const_cast<BoundType*>(inherits)->Finalise();
|
||||
}
|
||||
_size += inherits->GetSize();
|
||||
}
|
||||
for (auto& field : _fields) {
|
||||
if (!field->GetType()->IsInitialised()) {
|
||||
const_cast<BoundType*>(field->GetType())->Finalise();
|
||||
}
|
||||
_size += field->GetType()->GetSize();
|
||||
}
|
||||
_size = size;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline const Identifier& GetIdentifier() const noexcept { return _identifier; }
|
||||
[[nodiscard]] inline size_t GetSize() const noexcept { return _size; }
|
||||
[[nodiscard]] inline bool IsInitialised() const noexcept { return _initialised; }
|
||||
|
@ -50,8 +46,9 @@ namespace MalachScript::Binder {
|
|||
[[nodiscard]] inline const std::unordered_map<Identifier, BoundVariable*>& GetFieldsLookup() const noexcept {
|
||||
return _fieldsLookup;
|
||||
}
|
||||
[[nodiscard]] inline const std::vector<const BoundType*>& GetInherits() const noexcept { return _inherits; }
|
||||
|
||||
inline std::optional<BoundType*> ResolveType(const Identifier& identifier) const noexcept {
|
||||
[[nodiscard]] inline std::optional<BoundType*> ResolveType(const Identifier& identifier) const noexcept {
|
||||
auto find = _types.find(identifier);
|
||||
if (find == _types.end()) {
|
||||
return {};
|
||||
|
@ -59,10 +56,14 @@ namespace MalachScript::Binder {
|
|||
return find->second;
|
||||
}
|
||||
|
||||
[[nodiscard]] inline const std::optional<ScriptTextSpan>& GetSpan() const noexcept { return _span; }
|
||||
|
||||
private:
|
||||
bool _initialised = false;
|
||||
Identifier _identifier;
|
||||
ClassAttr _classAttr;
|
||||
std::optional<ScriptTextSpan> _span;
|
||||
|
||||
size_t _size = 0;
|
||||
std::vector<const BoundType*> _inherits;
|
||||
std::vector<BoundVariable*> _fields;
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef MALACHSCRIPT_BOUNDVARIABLE_HPP
|
||||
#define MALACHSCRIPT_BOUNDVARIABLE_HPP
|
||||
|
||||
#include "../CoreData/AccessModifier.hpp"
|
||||
|
||||
namespace MalachScript::Binder {
|
||||
class BoundType;
|
||||
|
||||
|
|
|
@ -1,6 +1,8 @@
|
|||
#ifndef MALACHSCRIPT_CLASSATTR_HPP
|
||||
#define MALACHSCRIPT_CLASSATTR_HPP
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
namespace MalachScript {
|
||||
enum class ClassAttr : uint8_t {
|
||||
None = 0,
|
||||
|
|
|
@ -11,6 +11,7 @@ namespace MalachScript::Diagnostics {
|
|||
|
||||
UnknownType,
|
||||
TypeAlreadyDefined,
|
||||
CircularTypeReference,
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -28,6 +28,9 @@ namespace MalachScript::Diagnostics {
|
|||
return util::Format("Unknown Type Encounted: '{0}'", diag->GetFormats());
|
||||
case DiagnosticType::TypeAlreadyDefined:
|
||||
return util::Format("Type already defined: '{0}'", diag->GetFormats());
|
||||
case DiagnosticType::CircularTypeReference:
|
||||
return util::Format("Type '{0}' can't hold a value type of type '{1}' due to a circular reference",
|
||||
diag->GetFormats());
|
||||
}
|
||||
return std::to_string((uint8_t)diag->GetType());
|
||||
}
|
||||
|
|
|
@ -9,25 +9,29 @@ namespace MalachScript::Diagnostics {
|
|||
std::vector<Diagnostic> _messages;
|
||||
|
||||
public:
|
||||
inline void Log(DiagnosticLevel level, DiagnosticType type, std::string_view scriptName, TextSpan span,
|
||||
inline void Log(DiagnosticLevel level, DiagnosticType type, const ScriptTextSpan& span,
|
||||
const std::vector<std::string>& formats = {}) {
|
||||
_messages.emplace_back(level, type, scriptName, span, formats);
|
||||
_messages.emplace_back(level, type, span.GetScriptName(), span.GetSpan(), formats);
|
||||
}
|
||||
inline void LogTrace(DiagnosticType type, std::string_view scriptName, TextSpan span) {
|
||||
Log(DiagnosticLevel::Trace, type, scriptName, span);
|
||||
}
|
||||
inline void LogInfo(DiagnosticType type, std::string_view scriptName, TextSpan span) {
|
||||
Log(DiagnosticLevel::Information, type, scriptName, span);
|
||||
}
|
||||
inline void LogWarning(DiagnosticType type, std::string_view scriptName, TextSpan span) {
|
||||
Log(DiagnosticLevel::Warning, type, scriptName, span);
|
||||
}
|
||||
inline void LogError(DiagnosticType type, std::string_view scriptName, TextSpan span,
|
||||
inline void LogTrace(DiagnosticType type, const ScriptTextSpan& span,
|
||||
const std::vector<std::string>& formats = {}) {
|
||||
Log(DiagnosticLevel::Error, type, scriptName, span, formats);
|
||||
Log(DiagnosticLevel::Trace, type, span, formats);
|
||||
}
|
||||
inline void LogCritical(DiagnosticType type, std::string_view scriptName, TextSpan span) {
|
||||
Log(DiagnosticLevel::Critical, type, scriptName, span);
|
||||
inline void LogInfo(DiagnosticType type, const ScriptTextSpan& span,
|
||||
const std::vector<std::string>& formats = {}) {
|
||||
Log(DiagnosticLevel::Information, type, span, formats);
|
||||
}
|
||||
inline void LogWarning(DiagnosticType type, const ScriptTextSpan& span,
|
||||
const std::vector<std::string>& formats = {}) {
|
||||
Log(DiagnosticLevel::Warning, type, span, formats);
|
||||
}
|
||||
inline void LogError(DiagnosticType type, const ScriptTextSpan& span,
|
||||
const std::vector<std::string>& formats = {}) {
|
||||
Log(DiagnosticLevel::Error, type, span, formats);
|
||||
}
|
||||
inline void LogCritical(DiagnosticType type, const ScriptTextSpan& span,
|
||||
const std::vector<std::string>& formats = {}) {
|
||||
Log(DiagnosticLevel::Critical, type, span, formats);
|
||||
}
|
||||
|
||||
[[nodiscard]] const std::vector<Diagnostic>& GetMessages() const noexcept { return _messages; }
|
||||
|
|
|
@ -11,14 +11,14 @@
|
|||
namespace MalachScript::Parser {
|
||||
class LexToken {
|
||||
std::unique_ptr<const LexToken> _next;
|
||||
TextSpan _span;
|
||||
ScriptTextSpan _span;
|
||||
|
||||
public:
|
||||
inline LexToken(const TextSpan& span) : _span(span) {}
|
||||
inline LexToken(const ScriptTextSpan& span) : _span(span) {}
|
||||
virtual ~LexToken() = default;
|
||||
[[nodiscard]] virtual LexTokenKind GetKind() const noexcept = 0;
|
||||
[[nodiscard]] inline const std::unique_ptr<const LexToken>& GetNext() const noexcept { return _next; }
|
||||
[[nodiscard]] inline const TextSpan& GetSpan() const noexcept { return _span; }
|
||||
[[nodiscard]] inline const ScriptTextSpan& GetSpan() const noexcept { return _span; }
|
||||
[[nodiscard]] virtual std::string ToString() const noexcept { return LexTokenKindHelper::ToString(GetKind()); }
|
||||
|
||||
inline void SetNext(LexToken* token) { _next = std::unique_ptr<const LexToken>(token); }
|
||||
|
@ -26,7 +26,7 @@ namespace MalachScript::Parser {
|
|||
|
||||
template <LexTokenKind kind> class LexTokenImpl : public LexToken {
|
||||
public:
|
||||
inline LexTokenImpl(const TextSpan& span) : LexToken(span){};
|
||||
inline LexTokenImpl(const ScriptTextSpan& span) : LexToken(span){};
|
||||
[[nodiscard]] inline LexTokenKind GetKind() const noexcept final { return kind; }
|
||||
};
|
||||
|
||||
|
@ -34,7 +34,7 @@ namespace MalachScript::Parser {
|
|||
ParseInt _value;
|
||||
|
||||
public:
|
||||
IntegerLiteral(const TextSpan& span, ParseInt value)
|
||||
IntegerLiteral(const ScriptTextSpan& span, ParseInt value)
|
||||
: LexTokenImpl<LexTokenKind::IntegerLiteral>(span), _value(value) {}
|
||||
[[nodiscard]] inline ParseInt GetValue() const noexcept { return _value; }
|
||||
|
||||
|
@ -49,7 +49,7 @@ namespace MalachScript::Parser {
|
|||
ParseFloat _value;
|
||||
|
||||
public:
|
||||
FloatLiteral(const TextSpan& span, ParseFloat value)
|
||||
FloatLiteral(const ScriptTextSpan& span, ParseFloat value)
|
||||
: LexTokenImpl<LexTokenKind::FloatLiteral>(span), _value(value) {}
|
||||
[[nodiscard]] inline long double GetValue() const noexcept { return _value; }
|
||||
|
||||
|
@ -64,7 +64,7 @@ namespace MalachScript::Parser {
|
|||
ParseString _value;
|
||||
|
||||
public:
|
||||
StringLiteral(const TextSpan& span, ParseString value)
|
||||
StringLiteral(const ScriptTextSpan& span, ParseString value)
|
||||
: LexTokenImpl<LexTokenKind::StringLiteral>(span), _value(std::move(value)) {}
|
||||
[[nodiscard]] inline const ParseString& GetValue() const noexcept { return _value; }
|
||||
|
||||
|
@ -81,7 +81,7 @@ namespace MalachScript::Parser {
|
|||
Identifier _value;
|
||||
|
||||
public:
|
||||
IdentifierToken(const TextSpan& span, Identifier value)
|
||||
IdentifierToken(const ScriptTextSpan& span, Identifier value)
|
||||
: LexTokenImpl<LexTokenKind::Identifier>(span), _value(value) {}
|
||||
[[nodiscard]] inline const Identifier& GetValue() const noexcept { return _value; }
|
||||
|
||||
|
|
|
@ -25,7 +25,8 @@ namespace MalachScript::Parser {
|
|||
auto start = _position;
|
||||
auto c = Consume();
|
||||
switch (c) {
|
||||
case '\0': return Create<LexTokenImpl<LexTokenKind::EndOfFile>>(TextSpan(start + 1, start + 2));
|
||||
case '\0':
|
||||
return Create<LexTokenImpl<LexTokenKind::EndOfFile>>(ScriptTextSpan(start + 1, start + 2, _scriptName));
|
||||
case '*': {
|
||||
auto n = Peek();
|
||||
if (n == '*') {
|
||||
|
@ -34,71 +35,81 @@ namespace MalachScript::Parser {
|
|||
if (n == '=') {
|
||||
Progress();
|
||||
// **=
|
||||
return Create<LexTokenImpl<LexTokenKind::StarStarEqualsSymbol>>(TextSpan(start, start + 3));
|
||||
return Create<LexTokenImpl<LexTokenKind::StarStarEqualsSymbol>>(
|
||||
ScriptTextSpan(start, start + 3, _scriptName));
|
||||
}
|
||||
// **
|
||||
return Create<LexTokenImpl<LexTokenKind::StarStarSymbol>>(TextSpan(start, start + 2));
|
||||
return Create<LexTokenImpl<LexTokenKind::StarStarSymbol>>(
|
||||
ScriptTextSpan(start, start + 2, _scriptName));
|
||||
}
|
||||
if (n == '=') {
|
||||
Progress();
|
||||
// *=
|
||||
return Create<LexTokenImpl<LexTokenKind::StarEqualsSymbol>>(TextSpan(start, start + 2));
|
||||
return Create<LexTokenImpl<LexTokenKind::StarEqualsSymbol>>(
|
||||
ScriptTextSpan(start, start + 2, _scriptName));
|
||||
}
|
||||
// *
|
||||
return Create<LexTokenImpl<LexTokenKind::StarSymbol>>(TextSpan(start, start + 1));
|
||||
return Create<LexTokenImpl<LexTokenKind::StarSymbol>>(ScriptTextSpan(start, start + 1, _scriptName));
|
||||
}
|
||||
case '/':
|
||||
if (Peek() == '=') {
|
||||
Progress();
|
||||
// /=
|
||||
return Create<LexTokenImpl<LexTokenKind::SlashEqualsSymbol>>(TextSpan(start, start + 2));
|
||||
return Create<LexTokenImpl<LexTokenKind::SlashEqualsSymbol>>(
|
||||
ScriptTextSpan(start, start + 2, _scriptName));
|
||||
}
|
||||
// /
|
||||
return Create<LexTokenImpl<LexTokenKind::SlashSymbol>>(TextSpan(start, start + 1));
|
||||
return Create<LexTokenImpl<LexTokenKind::SlashSymbol>>(ScriptTextSpan(start, start + 1, _scriptName));
|
||||
case '%':
|
||||
if (Peek() == '=') {
|
||||
Progress();
|
||||
// %=
|
||||
return Create<LexTokenImpl<LexTokenKind::PercentEqualsSymbol>>(TextSpan(start, start + 2));
|
||||
return Create<LexTokenImpl<LexTokenKind::PercentEqualsSymbol>>(
|
||||
ScriptTextSpan(start, start + 2, _scriptName));
|
||||
}
|
||||
// %
|
||||
return Create<LexTokenImpl<LexTokenKind::PercentSymbol>>(TextSpan(start, start + 1));
|
||||
return Create<LexTokenImpl<LexTokenKind::PercentSymbol>>(ScriptTextSpan(start, start + 1, _scriptName));
|
||||
case '+': {
|
||||
auto n = Peek();
|
||||
if (n == '=') {
|
||||
Progress();
|
||||
// +=
|
||||
return Create<LexTokenImpl<LexTokenKind::PlusEqualsSymbol>>(TextSpan(start, start + 2));
|
||||
return Create<LexTokenImpl<LexTokenKind::PlusEqualsSymbol>>(
|
||||
ScriptTextSpan(start, start + 2, _scriptName));
|
||||
}
|
||||
if (n == '+') {
|
||||
Progress();
|
||||
// ++
|
||||
return Create<LexTokenImpl<LexTokenKind::PlusPlusSymbol>>(TextSpan(start, start + 2));
|
||||
return Create<LexTokenImpl<LexTokenKind::PlusPlusSymbol>>(
|
||||
ScriptTextSpan(start, start + 2, _scriptName));
|
||||
}
|
||||
// +
|
||||
return Create<LexTokenImpl<LexTokenKind::PlusSymbol>>(TextSpan(start, start + 1));
|
||||
return Create<LexTokenImpl<LexTokenKind::PlusSymbol>>(ScriptTextSpan(start, start + 1, _scriptName));
|
||||
}
|
||||
case '-': {
|
||||
auto n = Peek();
|
||||
if (n == '=') {
|
||||
Progress();
|
||||
// -=
|
||||
return Create<LexTokenImpl<LexTokenKind::MinusEqualsSymbol>>(TextSpan(start, start + 2));
|
||||
return Create<LexTokenImpl<LexTokenKind::MinusEqualsSymbol>>(
|
||||
ScriptTextSpan(start, start + 2, _scriptName));
|
||||
}
|
||||
if (n == '-') {
|
||||
Progress();
|
||||
// --
|
||||
return Create<LexTokenImpl<LexTokenKind::MinusMinusSymbol>>(TextSpan(start, start + 2));
|
||||
return Create<LexTokenImpl<LexTokenKind::MinusMinusSymbol>>(
|
||||
ScriptTextSpan(start, start + 2, _scriptName));
|
||||
}
|
||||
// -
|
||||
return Create<LexTokenImpl<LexTokenKind::MinusSymbol>>(TextSpan(start, start + 1));
|
||||
return Create<LexTokenImpl<LexTokenKind::MinusSymbol>>(ScriptTextSpan(start, start + 1, _scriptName));
|
||||
}
|
||||
case '<': {
|
||||
auto n = Peek();
|
||||
if (n == '=') {
|
||||
Progress();
|
||||
// <=
|
||||
return Create<LexTokenImpl<LexTokenKind::LessThanEqualsSymbol>>(TextSpan(start, start + 2));
|
||||
return Create<LexTokenImpl<LexTokenKind::LessThanEqualsSymbol>>(
|
||||
ScriptTextSpan(start, start + 2, _scriptName));
|
||||
}
|
||||
if (n == '<') {
|
||||
Progress();
|
||||
|
@ -106,20 +117,23 @@ namespace MalachScript::Parser {
|
|||
Progress();
|
||||
// <<=
|
||||
return Create<LexTokenImpl<LexTokenKind::LessThanLessThanEqualsSymbol>>(
|
||||
TextSpan(start, start + 3));
|
||||
ScriptTextSpan(start, start + 3, _scriptName));
|
||||
}
|
||||
// <<
|
||||
return Create<LexTokenImpl<LexTokenKind::LessThanLessThanSymbol>>(TextSpan(start, start + 2));
|
||||
return Create<LexTokenImpl<LexTokenKind::LessThanLessThanSymbol>>(
|
||||
ScriptTextSpan(start, start + 2, _scriptName));
|
||||
}
|
||||
// <
|
||||
return Create<LexTokenImpl<LexTokenKind::LessThanSymbol>>(TextSpan(start, start + 1));
|
||||
return Create<LexTokenImpl<LexTokenKind::LessThanSymbol>>(
|
||||
ScriptTextSpan(start, start + 1, _scriptName));
|
||||
}
|
||||
case '>': {
|
||||
auto n = Peek();
|
||||
if (n == '=') {
|
||||
Progress();
|
||||
// >=
|
||||
return Create<LexTokenImpl<LexTokenKind::GreaterThanEqualsSymbol>>(TextSpan(start, start + 2));
|
||||
return Create<LexTokenImpl<LexTokenKind::GreaterThanEqualsSymbol>>(
|
||||
ScriptTextSpan(start, start + 2, _scriptName));
|
||||
}
|
||||
if (n == '>') {
|
||||
Progress();
|
||||
|
@ -128,7 +142,7 @@ namespace MalachScript::Parser {
|
|||
Progress();
|
||||
// >>=
|
||||
return Create<LexTokenImpl<LexTokenKind::GreaterThanGreaterThanEqualsSymbol>>(
|
||||
TextSpan(start, start + 3));
|
||||
ScriptTextSpan(start, start + 3, _scriptName));
|
||||
}
|
||||
if (n == '>') {
|
||||
Progress();
|
||||
|
@ -136,125 +150,159 @@ namespace MalachScript::Parser {
|
|||
Progress();
|
||||
// >>>=
|
||||
return Create<LexTokenImpl<LexTokenKind::GreaterThanGreaterThanGreaterThanEqualsSymbol>>(
|
||||
TextSpan(start, start + 4));
|
||||
ScriptTextSpan(start, start + 4, _scriptName));
|
||||
}
|
||||
// >>>
|
||||
return Create<LexTokenImpl<LexTokenKind::GreaterThanGreaterThanGreaterThanSymbol>>(
|
||||
TextSpan(start, start + 3));
|
||||
ScriptTextSpan(start, start + 3, _scriptName));
|
||||
}
|
||||
// >>
|
||||
return Create<LexTokenImpl<LexTokenKind::GreaterThanGreaterThanSymbol>>(TextSpan(start, start + 2));
|
||||
return Create<LexTokenImpl<LexTokenKind::GreaterThanGreaterThanSymbol>>(
|
||||
ScriptTextSpan(start, start + 2, _scriptName));
|
||||
}
|
||||
// >
|
||||
return Create<LexTokenImpl<LexTokenKind::GreaterThanSymbol>>(TextSpan(start, start + 1));
|
||||
return Create<LexTokenImpl<LexTokenKind::GreaterThanSymbol>>(
|
||||
ScriptTextSpan(start, start + 1, _scriptName));
|
||||
}
|
||||
case '(': return Create<LexTokenImpl<LexTokenKind::OpenParenthesisSymbol>>(TextSpan(start, start + 1));
|
||||
case ')': return Create<LexTokenImpl<LexTokenKind::CloseParenthesisSymbol>>(TextSpan(start, start + 1));
|
||||
case '(':
|
||||
return Create<LexTokenImpl<LexTokenKind::OpenParenthesisSymbol>>(
|
||||
ScriptTextSpan(start, start + 1, _scriptName));
|
||||
case ')':
|
||||
return Create<LexTokenImpl<LexTokenKind::CloseParenthesisSymbol>>(
|
||||
ScriptTextSpan(start, start + 1, _scriptName));
|
||||
case '=': {
|
||||
if (Peek() == '=') {
|
||||
Progress();
|
||||
// ==
|
||||
return Create<LexTokenImpl<LexTokenKind::EqualsEqualsSymbol>>(TextSpan(start, start + 2));
|
||||
return Create<LexTokenImpl<LexTokenKind::EqualsEqualsSymbol>>(
|
||||
ScriptTextSpan(start, start + 2, _scriptName));
|
||||
}
|
||||
// =
|
||||
return Create<LexTokenImpl<LexTokenKind::EqualsSymbol>>(TextSpan(start, start + 1));
|
||||
return Create<LexTokenImpl<LexTokenKind::EqualsSymbol>>(ScriptTextSpan(start, start + 1, _scriptName));
|
||||
}
|
||||
case '!': {
|
||||
auto n = Peek();
|
||||
if (n == '=') {
|
||||
Progress();
|
||||
// !=
|
||||
return Create<LexTokenImpl<LexTokenKind::ExclamationMarkEqualsSymbol>>(TextSpan(start, start + 2));
|
||||
return Create<LexTokenImpl<LexTokenKind::ExclamationMarkEqualsSymbol>>(
|
||||
ScriptTextSpan(start, start + 2, _scriptName));
|
||||
}
|
||||
if (n == 'i' && Peek(2) == 's') {
|
||||
Progress(2);
|
||||
// !is
|
||||
return Create<LexTokenImpl<LexTokenKind::ExclamationMarkIsSymbol>>(TextSpan(start, start + 3));
|
||||
return Create<LexTokenImpl<LexTokenKind::ExclamationMarkIsSymbol>>(
|
||||
ScriptTextSpan(start, start + 3, _scriptName));
|
||||
}
|
||||
// !
|
||||
return Create<LexTokenImpl<LexTokenKind::ExclamationMarkSymbol>>(TextSpan(start, start + 1));
|
||||
return Create<LexTokenImpl<LexTokenKind::ExclamationMarkSymbol>>(
|
||||
ScriptTextSpan(start, start + 1, _scriptName));
|
||||
}
|
||||
case '?': return Create<LexTokenImpl<LexTokenKind::QuestionMarkSymbol>>(TextSpan(start, start + 1));
|
||||
case '?':
|
||||
return Create<LexTokenImpl<LexTokenKind::QuestionMarkSymbol>>(
|
||||
ScriptTextSpan(start, start + 1, _scriptName));
|
||||
case ':': {
|
||||
if (Peek() == ':') {
|
||||
Progress();
|
||||
// ::
|
||||
return Create<LexTokenImpl<LexTokenKind::ColonColonSymbol>>(TextSpan(start, start + 2));
|
||||
return Create<LexTokenImpl<LexTokenKind::ColonColonSymbol>>(
|
||||
ScriptTextSpan(start, start + 2, _scriptName));
|
||||
}
|
||||
// :
|
||||
return Create<LexTokenImpl<LexTokenKind::ColonSymbol>>(TextSpan(start, start + 1));
|
||||
return Create<LexTokenImpl<LexTokenKind::ColonSymbol>>(ScriptTextSpan(start, start + 1, _scriptName));
|
||||
}
|
||||
case '&': {
|
||||
auto n = Peek();
|
||||
if (n == '=') {
|
||||
Progress();
|
||||
// &=
|
||||
return Create<LexTokenImpl<LexTokenKind::AmpersandEqualsSymbol>>(TextSpan(start, start + 2));
|
||||
return Create<LexTokenImpl<LexTokenKind::AmpersandEqualsSymbol>>(
|
||||
ScriptTextSpan(start, start + 2, _scriptName));
|
||||
}
|
||||
if (n == '&') {
|
||||
Progress();
|
||||
// &&
|
||||
return Create<LexTokenImpl<LexTokenKind::AmpersandAmpersandSymbol>>(TextSpan(start, start + 2));
|
||||
return Create<LexTokenImpl<LexTokenKind::AmpersandAmpersandSymbol>>(
|
||||
ScriptTextSpan(start, start + 2, _scriptName));
|
||||
}
|
||||
// &
|
||||
return Create<LexTokenImpl<LexTokenKind::AmpersandSymbol>>(TextSpan(start, start + 1));
|
||||
return Create<LexTokenImpl<LexTokenKind::AmpersandSymbol>>(
|
||||
ScriptTextSpan(start, start + 1, _scriptName));
|
||||
}
|
||||
case ',': return Create<LexTokenImpl<LexTokenKind::CommaSymbol>>(TextSpan(start, start + 1));
|
||||
case '{': return Create<LexTokenImpl<LexTokenKind::OpenCurlyParenthesisSymbol>>(TextSpan(start, start + 1));
|
||||
case ',':
|
||||
return Create<LexTokenImpl<LexTokenKind::CommaSymbol>>(ScriptTextSpan(start, start + 1, _scriptName));
|
||||
case '{':
|
||||
return Create<LexTokenImpl<LexTokenKind::OpenCurlyParenthesisSymbol>>(
|
||||
ScriptTextSpan(start, start + 1, _scriptName));
|
||||
case '}':
|
||||
return Create<LexTokenImpl<LexTokenKind::CloseCurlyParenthesisSymbol>>(TextSpan(start, start + 1));
|
||||
case ';': return Create<LexTokenImpl<LexTokenKind::SemicolonSymbol>>(TextSpan(start, start + 1));
|
||||
return Create<LexTokenImpl<LexTokenKind::CloseCurlyParenthesisSymbol>>(
|
||||
ScriptTextSpan(start, start + 1, _scriptName));
|
||||
case ';':
|
||||
return Create<LexTokenImpl<LexTokenKind::SemicolonSymbol>>(
|
||||
ScriptTextSpan(start, start + 1, _scriptName));
|
||||
case '|': {
|
||||
auto n = Peek();
|
||||
if (n == '=') {
|
||||
Progress();
|
||||
// |=
|
||||
return Create<LexTokenImpl<LexTokenKind::VerticalLineEqualsSymbol>>(TextSpan(start, start + 2));
|
||||
return Create<LexTokenImpl<LexTokenKind::VerticalLineEqualsSymbol>>(
|
||||
ScriptTextSpan(start, start + 2, _scriptName));
|
||||
}
|
||||
if (n == '|') {
|
||||
Progress();
|
||||
// ||
|
||||
return Create<LexTokenImpl<LexTokenKind::VerticalLineVerticalLineSymbol>>(
|
||||
TextSpan(start, start + 2));
|
||||
ScriptTextSpan(start, start + 2, _scriptName));
|
||||
}
|
||||
// |
|
||||
return Create<LexTokenImpl<LexTokenKind::VerticalLineSymbol>>(TextSpan(start, start + 1));
|
||||
return Create<LexTokenImpl<LexTokenKind::VerticalLineSymbol>>(
|
||||
ScriptTextSpan(start, start + 1, _scriptName));
|
||||
}
|
||||
case '^': {
|
||||
auto n = Peek();
|
||||
if (n == '=') {
|
||||
Progress();
|
||||
// ^=
|
||||
return Create<LexTokenImpl<LexTokenKind::CaretEqualsSymbol>>(TextSpan(start, start + 2));
|
||||
return Create<LexTokenImpl<LexTokenKind::CaretEqualsSymbol>>(
|
||||
ScriptTextSpan(start, start + 2, _scriptName));
|
||||
}
|
||||
if (n == '^') {
|
||||
Progress();
|
||||
// ^^
|
||||
return Create<LexTokenImpl<LexTokenKind::CaretCaretSymbol>>(TextSpan(start, start + 2));
|
||||
return Create<LexTokenImpl<LexTokenKind::CaretCaretSymbol>>(
|
||||
ScriptTextSpan(start, start + 2, _scriptName));
|
||||
}
|
||||
// ^
|
||||
return Create<LexTokenImpl<LexTokenKind::CaretSymbol>>(TextSpan(start, start + 1));
|
||||
return Create<LexTokenImpl<LexTokenKind::CaretSymbol>>(ScriptTextSpan(start, start + 1, _scriptName));
|
||||
}
|
||||
case '~': return Create<LexTokenImpl<LexTokenKind::TildeSymbol>>(TextSpan(start, start + 1));
|
||||
case '.': return Create<LexTokenImpl<LexTokenKind::DotSymbol>>(TextSpan(start, start + 1));
|
||||
case '[': return Create<LexTokenImpl<LexTokenKind::OpenBlockParenthesisSymbol>>(TextSpan(start, start + 1));
|
||||
case '~':
|
||||
return Create<LexTokenImpl<LexTokenKind::TildeSymbol>>(ScriptTextSpan(start, start + 1, _scriptName));
|
||||
case '.':
|
||||
return Create<LexTokenImpl<LexTokenKind::DotSymbol>>(ScriptTextSpan(start, start + 1, _scriptName));
|
||||
case '[':
|
||||
return Create<LexTokenImpl<LexTokenKind::OpenBlockParenthesisSymbol>>(
|
||||
ScriptTextSpan(start, start + 1, _scriptName));
|
||||
case ']':
|
||||
return Create<LexTokenImpl<LexTokenKind::CloseBlockParenthesisSymbol>>(TextSpan(start, start + 1));
|
||||
case '@': return Create<LexTokenImpl<LexTokenKind::AtSymbol>>(TextSpan(start, start + 1));
|
||||
return Create<LexTokenImpl<LexTokenKind::CloseBlockParenthesisSymbol>>(
|
||||
ScriptTextSpan(start, start + 1, _scriptName));
|
||||
case '@':
|
||||
return Create<LexTokenImpl<LexTokenKind::AtSymbol>>(ScriptTextSpan(start, start + 1, _scriptName));
|
||||
|
||||
case ' ':
|
||||
case '\r':
|
||||
case '\n':
|
||||
case '\t': return Create<LexTokenImpl<LexTokenKind::Whitespace>>(TextSpan(start, start + 1));
|
||||
case '\t':
|
||||
return Create<LexTokenImpl<LexTokenKind::Whitespace>>(ScriptTextSpan(start, start + 1, _scriptName));
|
||||
// Byte order mark
|
||||
case '\xEF': {
|
||||
if (Peek() == '\xBB' && Peek(2) == '\xBF') {
|
||||
Progress(2);
|
||||
return Create<LexTokenImpl<LexTokenKind::Whitespace>>(TextSpan(start, start + 3));
|
||||
return Create<LexTokenImpl<LexTokenKind::Whitespace>>(
|
||||
ScriptTextSpan(start, start + 3, _scriptName));
|
||||
}
|
||||
LogError(Diagnostics::DiagnosticType::UnknownCharacter, TextSpan(start, start + 1),
|
||||
LogError(Diagnostics::DiagnosticType::UnknownCharacter, ScriptTextSpan(start, start + 1, _scriptName),
|
||||
{std::string(1, c)});
|
||||
return Create<LexTokenImpl<LexTokenKind::Unknown>>(TextSpan(start, start + 1));
|
||||
return Create<LexTokenImpl<LexTokenKind::Unknown>>(ScriptTextSpan(start, start + 1, _scriptName));
|
||||
}
|
||||
case '0':
|
||||
case '1':
|
||||
|
@ -277,9 +325,9 @@ namespace MalachScript::Parser {
|
|||
default:
|
||||
if (IsAlphaNumericalOrUnderscore(c))
|
||||
return LexKeywordOrIdentifier();
|
||||
LogError(Diagnostics::DiagnosticType::UnknownCharacter, TextSpan(start, start + 1),
|
||||
LogError(Diagnostics::DiagnosticType::UnknownCharacter, ScriptTextSpan(start, start + 1, _scriptName),
|
||||
{std::string(1, (char)c)});
|
||||
return Create<LexTokenImpl<LexTokenKind::Unknown>>(TextSpan(start, start + 1));
|
||||
return Create<LexTokenImpl<LexTokenKind::Unknown>>(ScriptTextSpan(start, start + 1, _scriptName));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -311,7 +359,7 @@ namespace MalachScript::Parser {
|
|||
Progress();
|
||||
numericalSystem = 2;
|
||||
break;
|
||||
default: return Create<IntegerLiteral>(TextSpan(_position - 1, _position), 0);
|
||||
default: return Create<IntegerLiteral>(ScriptTextSpan(_position - 1, _position, _scriptName), 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -390,9 +438,9 @@ namespace MalachScript::Parser {
|
|||
if (isExponent) {
|
||||
val *= pow(10, exponentValue);
|
||||
}
|
||||
return Create<FloatLiteral>(TextSpan(start, _position), val);
|
||||
return Create<FloatLiteral>(ScriptTextSpan(start, _position, _scriptName), val);
|
||||
}
|
||||
return Create<IntegerLiteral>(TextSpan(start, _position), value);
|
||||
return Create<IntegerLiteral>(ScriptTextSpan(start, _position, _scriptName), value);
|
||||
}
|
||||
|
||||
IntegerLiteral* Lexer::LexHexadecimal() {
|
||||
|
@ -407,7 +455,7 @@ namespace MalachScript::Parser {
|
|||
value <<= 4;
|
||||
value += v;
|
||||
}
|
||||
return Create<IntegerLiteral>(TextSpan(start - 1, _position), value);
|
||||
return Create<IntegerLiteral>(ScriptTextSpan(start - 1, _position, _scriptName), value);
|
||||
}
|
||||
IntegerLiteral* Lexer::LexOctal() {
|
||||
auto start = _position;
|
||||
|
@ -421,7 +469,7 @@ namespace MalachScript::Parser {
|
|||
value <<= 3;
|
||||
value += v;
|
||||
}
|
||||
return Create<IntegerLiteral>(TextSpan(start - 1, _position), value);
|
||||
return Create<IntegerLiteral>(ScriptTextSpan(start - 1, _position, _scriptName), value);
|
||||
}
|
||||
IntegerLiteral* Lexer::LexBinary() {
|
||||
auto start = _position;
|
||||
|
@ -435,7 +483,7 @@ namespace MalachScript::Parser {
|
|||
value <<= 1;
|
||||
value += v;
|
||||
}
|
||||
return Create<IntegerLiteral>(TextSpan(start - 1, _position), value);
|
||||
return Create<IntegerLiteral>(ScriptTextSpan(start - 1, _position, _scriptName), value);
|
||||
}
|
||||
StringLiteral* Lexer::LexString(char opening, bool heredoc) {
|
||||
auto openingPos = _position;
|
||||
|
@ -455,13 +503,13 @@ namespace MalachScript::Parser {
|
|||
break;
|
||||
}
|
||||
if (current == '\0') {
|
||||
LogError(Diagnostics::DiagnosticType::ExpectedEndOfString, TextSpan(start, start + offset),
|
||||
{"EndOfFile"});
|
||||
LogError(Diagnostics::DiagnosticType::ExpectedEndOfString,
|
||||
ScriptTextSpan(start, start + offset, _scriptName), {"EndOfFile"});
|
||||
break;
|
||||
}
|
||||
if (!heredoc && (current == '\n' || current == '\r')) {
|
||||
LogError(Diagnostics::DiagnosticType::ExpectedEndOfString, TextSpan(start, start + offset),
|
||||
{"Newline"});
|
||||
LogError(Diagnostics::DiagnosticType::ExpectedEndOfString,
|
||||
ScriptTextSpan(start, start + offset, _scriptName), {"Newline"});
|
||||
break;
|
||||
}
|
||||
offset++;
|
||||
|
@ -470,7 +518,7 @@ namespace MalachScript::Parser {
|
|||
if (heredoc) {
|
||||
Progress(2);
|
||||
}
|
||||
return Create<StringLiteral>(TextSpan(openingPos, openingPos + _position),
|
||||
return Create<StringLiteral>(ScriptTextSpan(openingPos, openingPos + _position, _scriptName),
|
||||
ParseString(_script.substr(start, offset)));
|
||||
}
|
||||
|
||||
|
@ -485,135 +533,151 @@ namespace MalachScript::Parser {
|
|||
auto hash = Identifier::Hash(str);
|
||||
switch (hash) {
|
||||
case Identifier::Hash("and"):
|
||||
return Create<LexTokenImpl<LexTokenKind::AndKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::AndKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("abstract"):
|
||||
return Create<LexTokenImpl<LexTokenKind::AbstractKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::AbstractKeyword>>(
|
||||
ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("auto"):
|
||||
return Create<LexTokenImpl<LexTokenKind::AutoKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::AutoKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("bool"):
|
||||
return Create<LexTokenImpl<LexTokenKind::BoolKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::BoolKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("break"):
|
||||
return Create<LexTokenImpl<LexTokenKind::BreakKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::BreakKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("case"):
|
||||
return Create<LexTokenImpl<LexTokenKind::CaseKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::CaseKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("cast"):
|
||||
return Create<LexTokenImpl<LexTokenKind::CastKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::CastKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("catch"):
|
||||
return Create<LexTokenImpl<LexTokenKind::CatchKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::CatchKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("class"):
|
||||
return Create<LexTokenImpl<LexTokenKind::ClassKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::ClassKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("const"):
|
||||
return Create<LexTokenImpl<LexTokenKind::ConstKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::ConstKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("continue"):
|
||||
return Create<LexTokenImpl<LexTokenKind::ContinueKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::ContinueKeyword>>(
|
||||
ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("default"):
|
||||
return Create<LexTokenImpl<LexTokenKind::DefaultKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::DefaultKeyword>>(
|
||||
ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("do"):
|
||||
return Create<LexTokenImpl<LexTokenKind::DoKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::DoKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("double"):
|
||||
return Create<LexTokenImpl<LexTokenKind::DoubleKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::DoubleKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("else"):
|
||||
return Create<LexTokenImpl<LexTokenKind::ElseKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::ElseKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("enum"):
|
||||
return Create<LexTokenImpl<LexTokenKind::EnumKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::EnumKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("explicit"):
|
||||
return Create<LexTokenImpl<LexTokenKind::ExplicitKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::ExplicitKeyword>>(
|
||||
ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("external"):
|
||||
return Create<LexTokenImpl<LexTokenKind::ExternalKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::ExternalKeyword>>(
|
||||
ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("false"):
|
||||
return Create<LexTokenImpl<LexTokenKind::FalseKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::FalseKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("final"):
|
||||
return Create<LexTokenImpl<LexTokenKind::FinalKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::FinalKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("float"):
|
||||
return Create<LexTokenImpl<LexTokenKind::FloatKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::FloatKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("for"):
|
||||
return Create<LexTokenImpl<LexTokenKind::ForKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::ForKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("from"):
|
||||
return Create<LexTokenImpl<LexTokenKind::FromKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::FromKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("funcdef"):
|
||||
return Create<LexTokenImpl<LexTokenKind::FuncdefKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::FuncdefKeyword>>(
|
||||
ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("function"):
|
||||
return Create<LexTokenImpl<LexTokenKind::FunctionKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::FunctionKeyword>>(
|
||||
ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("get"):
|
||||
return Create<LexTokenImpl<LexTokenKind::GetKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::GetKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("if"):
|
||||
return Create<LexTokenImpl<LexTokenKind::IfKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::IfKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("import"):
|
||||
return Create<LexTokenImpl<LexTokenKind::ImportKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::ImportKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("in"):
|
||||
return Create<LexTokenImpl<LexTokenKind::InKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::InKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("inout"):
|
||||
return Create<LexTokenImpl<LexTokenKind::InoutKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::InoutKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("int"):
|
||||
return Create<LexTokenImpl<LexTokenKind::IntKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::IntKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("interface"):
|
||||
return Create<LexTokenImpl<LexTokenKind::InterfaceKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::InterfaceKeyword>>(
|
||||
ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("int8"):
|
||||
return Create<LexTokenImpl<LexTokenKind::Int8Keyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::Int8Keyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("int16"):
|
||||
return Create<LexTokenImpl<LexTokenKind::Int16Keyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::Int16Keyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("int32"):
|
||||
return Create<LexTokenImpl<LexTokenKind::Int32Keyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::Int32Keyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("int64"):
|
||||
return Create<LexTokenImpl<LexTokenKind::Int64Keyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::Int64Keyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("is"):
|
||||
return Create<LexTokenImpl<LexTokenKind::IsKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::IsKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("mixin"):
|
||||
return Create<LexTokenImpl<LexTokenKind::MixinKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::MixinKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("namespace"):
|
||||
return Create<LexTokenImpl<LexTokenKind::NamespaceKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::NamespaceKeyword>>(
|
||||
ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("not"):
|
||||
return Create<LexTokenImpl<LexTokenKind::NotKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::NotKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("null"):
|
||||
return Create<LexTokenImpl<LexTokenKind::NullKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::NullKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("or"):
|
||||
return Create<LexTokenImpl<LexTokenKind::OrKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::OrKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("out"):
|
||||
return Create<LexTokenImpl<LexTokenKind::OutKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::OutKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("override"):
|
||||
return Create<LexTokenImpl<LexTokenKind::OverrideKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::OverrideKeyword>>(
|
||||
ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("private"):
|
||||
return Create<LexTokenImpl<LexTokenKind::PrivateKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::PrivateKeyword>>(
|
||||
ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("property"):
|
||||
return Create<LexTokenImpl<LexTokenKind::PropertyKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::PropertyKeyword>>(
|
||||
ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("protected"):
|
||||
return Create<LexTokenImpl<LexTokenKind::ProtectedKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::ProtectedKeyword>>(
|
||||
ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("return"):
|
||||
return Create<LexTokenImpl<LexTokenKind::ReturnKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::ReturnKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("set"):
|
||||
return Create<LexTokenImpl<LexTokenKind::SetKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::SetKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("shared"):
|
||||
return Create<LexTokenImpl<LexTokenKind::SharedKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::SharedKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("super"):
|
||||
return Create<LexTokenImpl<LexTokenKind::SuperKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::SuperKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("switch"):
|
||||
return Create<LexTokenImpl<LexTokenKind::SwitchKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::SwitchKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("this"):
|
||||
return Create<LexTokenImpl<LexTokenKind::ThisKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::ThisKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("true"):
|
||||
return Create<LexTokenImpl<LexTokenKind::TrueKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::TrueKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("try"):
|
||||
return Create<LexTokenImpl<LexTokenKind::TryKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::TryKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("typedef"):
|
||||
return Create<LexTokenImpl<LexTokenKind::TypedefKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::TypedefKeyword>>(
|
||||
ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("uint"):
|
||||
return Create<LexTokenImpl<LexTokenKind::UintKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::UintKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("uint8"):
|
||||
return Create<LexTokenImpl<LexTokenKind::Uint8Keyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::Uint8Keyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("uint16"):
|
||||
return Create<LexTokenImpl<LexTokenKind::Uint16Keyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::Uint16Keyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("uint32"):
|
||||
return Create<LexTokenImpl<LexTokenKind::Uint32Keyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::Uint32Keyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("uint64"):
|
||||
return Create<LexTokenImpl<LexTokenKind::Uint64Keyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::Uint64Keyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("void"):
|
||||
return Create<LexTokenImpl<LexTokenKind::VoidKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::VoidKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("while"):
|
||||
return Create<LexTokenImpl<LexTokenKind::WhileKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::WhileKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
case Identifier::Hash("xor"):
|
||||
return Create<LexTokenImpl<LexTokenKind::XorKeyword>>(TextSpan(start, _position));
|
||||
return Create<LexTokenImpl<LexTokenKind::XorKeyword>>(ScriptTextSpan(start, _position, _scriptName));
|
||||
|
||||
default: return Create<IdentifierToken>(TextSpan(start, _position), Identifier(str.data(), offset, hash));
|
||||
default:
|
||||
return Create<IdentifierToken>(ScriptTextSpan(start, _position, _scriptName),
|
||||
Identifier(str.data(), offset, hash));
|
||||
}
|
||||
}
|
||||
bool Lexer::IsAlphaNumericalOrUnderscore(char c) {
|
||||
|
|
|
@ -57,8 +57,9 @@ namespace MalachScript::Parser {
|
|||
return _allocator.Create<T>(args...);
|
||||
}
|
||||
|
||||
inline void LogError(Diagnostics::DiagnosticType type, TextSpan span, const std::vector<std::string>& formats) {
|
||||
_diagnostics->LogError(type, _scriptName, span, formats);
|
||||
inline void LogError(Diagnostics::DiagnosticType type, const ScriptTextSpan& span,
|
||||
const std::vector<std::string>& formats) {
|
||||
_diagnostics->LogError(type, span, formats);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
|
|
@ -38,11 +38,10 @@
|
|||
namespace MalachScript::Parser {
|
||||
using namespace Diagnostics;
|
||||
|
||||
const ParsedScriptStatement* Parser::Parse(const LexToken* firstToken, std::string_view scriptName,
|
||||
Logger* diagnostics) {
|
||||
const log_func& log = [diagnostics, scriptName](DiagnosticLevel level, DiagnosticType type,
|
||||
const TextSpan& span, const std::vector<std::string>& formats) {
|
||||
diagnostics->Log(level, type, scriptName, span, formats);
|
||||
const ParsedScriptStatement* Parser::Parse(const LexToken* firstToken, Logger* diagnostics) {
|
||||
const log_func& log = [diagnostics](DiagnosticLevel level, DiagnosticType type, const ScriptTextSpan& span,
|
||||
const std::vector<std::string>& formats) {
|
||||
diagnostics->Log(level, type, span, formats);
|
||||
};
|
||||
|
||||
ScopedPtr<const ParsedStatement> s = nullptr;
|
||||
|
@ -89,7 +88,7 @@ namespace MalachScript::Parser {
|
|||
if (currentAmount > 0) {
|
||||
end = statements.back()->GetSpan().GetEnd();
|
||||
}
|
||||
out = new ParsedScriptStatement(TextSpan(0, end), statements);
|
||||
out = new ParsedScriptStatement(ScriptTextSpan(0, end, currentToken->GetSpan().GetScriptName()), statements);
|
||||
currentToken = current;
|
||||
return true;
|
||||
}
|
||||
|
@ -172,8 +171,9 @@ namespace MalachScript::Parser {
|
|||
logUnexpectedTokenWithAnyOf(current, LexTokenKind::SemicolonSymbol, LexTokenKind::ColonSymbol,
|
||||
LexTokenKind::OpenCurlyParenthesisSymbol);
|
||||
}
|
||||
out = new ParsedClassStatement(TextSpan(start, current->GetSpan().GetEnd()), classAttr, identifier, inherits,
|
||||
body);
|
||||
out = new ParsedClassStatement(
|
||||
ScriptTextSpan(start, current->GetSpan().GetEnd(), current->GetSpan().GetScriptName()), classAttr,
|
||||
identifier, inherits, body);
|
||||
currentToken = current;
|
||||
return true;
|
||||
}
|
||||
|
@ -197,7 +197,9 @@ namespace MalachScript::Parser {
|
|||
}
|
||||
PROGRESS_TOKEN(current);
|
||||
EXPECT_TOKEN(current, SemicolonSymbol);
|
||||
out = new ParsedTypeDefStatement(TextSpan(start, current->GetSpan().GetEnd()), defineFrom, defineTo);
|
||||
out = new ParsedTypeDefStatement(
|
||||
ScriptTextSpan(start, current->GetSpan().GetEnd(), current->GetSpan().GetScriptName()), defineFrom,
|
||||
defineTo);
|
||||
return true;
|
||||
}
|
||||
bool Parser::ParseNamespace(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken,
|
||||
|
@ -221,7 +223,7 @@ namespace MalachScript::Parser {
|
|||
}
|
||||
auto end = current->GetSpan().GetEnd();
|
||||
EXPECT_TOKEN(current, CloseCurlyParenthesisSymbol);
|
||||
out = new ParsedNamespaceStatement(TextSpan(start, end), identifier,
|
||||
out = new ParsedNamespaceStatement(ScriptTextSpan(start, end, current->GetSpan().GetScriptName()), identifier,
|
||||
(const ParsedScriptStatement*)script.TakeOwnership());
|
||||
currentToken = current;
|
||||
return true;
|
||||
|
@ -289,9 +291,10 @@ namespace MalachScript::Parser {
|
|||
} else {
|
||||
PROGRESS_TOKEN(current);
|
||||
}
|
||||
out = new ParsedFuncStatement(TextSpan(start, current->GetSpan().GetEnd()), isShared, isExternal,
|
||||
accessModifier, typeStatement.TakeOwnership(), returnsReference, identifier,
|
||||
paramList.TakeOwnership(), isConst, funcAttr, statblock.TakeOwnership());
|
||||
out = new ParsedFuncStatement(
|
||||
ScriptTextSpan(start, current->GetSpan().GetEnd(), current->GetSpan().GetScriptName()), isShared,
|
||||
isExternal, accessModifier, typeStatement.TakeOwnership(), returnsReference, identifier,
|
||||
paramList.TakeOwnership(), isConst, funcAttr, statblock.TakeOwnership());
|
||||
currentToken = current;
|
||||
return true;
|
||||
}
|
||||
|
@ -331,7 +334,8 @@ namespace MalachScript::Parser {
|
|||
}
|
||||
auto end = current->GetSpan().GetEnd();
|
||||
currentToken = current;
|
||||
out = new ParsedTypeStatement(TextSpan(start, end), isConst, isArray, isHandle, scopedIdentifier);
|
||||
out = new ParsedTypeStatement(ScriptTextSpan(start, end, current->GetSpan().GetScriptName()), isConst, isArray,
|
||||
isHandle, scopedIdentifier);
|
||||
return true;
|
||||
}
|
||||
bool Parser::ParseScope(std::vector<Identifier>& scope, const LexToken*& currentToken, const log_func& log) {
|
||||
|
@ -413,11 +417,15 @@ namespace MalachScript::Parser {
|
|||
if (currentToken->GetKind() == LexTokenKind::VoidKeyword) {
|
||||
PROGRESS_TOKEN(currentToken);
|
||||
EXPECT_TOKEN(currentToken, CloseParenthesisSymbol);
|
||||
out = new ParsedParamListStatement(TextSpan(start, currentToken->GetSpan().GetEnd()), parameters);
|
||||
out = new ParsedParamListStatement(
|
||||
ScriptTextSpan(start, currentToken->GetSpan().GetEnd(), currentToken->GetSpan().GetScriptName()),
|
||||
parameters);
|
||||
return true;
|
||||
}
|
||||
if (currentToken->GetKind() == LexTokenKind::CloseParenthesisSymbol) {
|
||||
out = new ParsedParamListStatement(TextSpan(start, currentToken->GetSpan().GetEnd()), parameters);
|
||||
out = new ParsedParamListStatement(
|
||||
ScriptTextSpan(start, currentToken->GetSpan().GetEnd(), currentToken->GetSpan().GetScriptName()),
|
||||
parameters);
|
||||
PROGRESS_TOKEN(currentToken);
|
||||
return true;
|
||||
}
|
||||
|
@ -448,7 +456,9 @@ namespace MalachScript::Parser {
|
|||
PROGRESS_TOKEN(currentToken);
|
||||
}
|
||||
EXPECT_TOKEN(currentToken, CloseParenthesisSymbol);
|
||||
out = new ParsedParamListStatement(TextSpan(start, currentToken->GetSpan().GetEnd()), parameters);
|
||||
out = new ParsedParamListStatement(
|
||||
ScriptTextSpan(start, currentToken->GetSpan().GetEnd(), currentToken->GetSpan().GetScriptName()),
|
||||
parameters);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -471,7 +481,7 @@ namespace MalachScript::Parser {
|
|||
}
|
||||
}
|
||||
|
||||
bool Parser::ParseVirtProp([[maybe_unused]] ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken,
|
||||
bool Parser::ParseVirtProp(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken,
|
||||
const log_func& log) {
|
||||
const auto* current = currentToken;
|
||||
AccessModifier access = AccessModifier::Public;
|
||||
|
@ -526,7 +536,9 @@ namespace MalachScript::Parser {
|
|||
}
|
||||
|
||||
if (hasGet) {
|
||||
logError(DiagnosticType::DoubleProperty, TextSpan(start, current->GetSpan().GetEnd()), {});
|
||||
logError(DiagnosticType::DoubleProperty,
|
||||
ScriptTextSpan(start, current->GetSpan().GetEnd(), current->GetSpan().GetScriptName()),
|
||||
{});
|
||||
}
|
||||
hasGet = true;
|
||||
} else if (current->GetKind() == LexTokenKind::SetKeyword) {
|
||||
|
@ -545,7 +557,9 @@ namespace MalachScript::Parser {
|
|||
}
|
||||
|
||||
if (hasSet) {
|
||||
logError(DiagnosticType::DoubleProperty, TextSpan(start, current->GetSpan().GetEnd()), {});
|
||||
logError(DiagnosticType::DoubleProperty,
|
||||
ScriptTextSpan(start, current->GetSpan().GetEnd(), current->GetSpan().GetScriptName()),
|
||||
{});
|
||||
}
|
||||
hasSet = true;
|
||||
} else {
|
||||
|
@ -558,10 +572,11 @@ namespace MalachScript::Parser {
|
|||
PROGRESS_TOKEN(current);
|
||||
}
|
||||
|
||||
out = new ParsedVirtPropStatement(TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()),
|
||||
access, typeStatement.TakeOwnership(), ref, identifier, hasGet, getConst,
|
||||
getAttr, getStatement.TakeOwnership(), hasSet, setConst, setAttr,
|
||||
setStatement.TakeOwnership());
|
||||
out = new ParsedVirtPropStatement(
|
||||
ScriptTextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd(),
|
||||
current->GetSpan().GetScriptName()),
|
||||
access, typeStatement.TakeOwnership(), ref, identifier, hasGet, getConst, getAttr,
|
||||
getStatement.TakeOwnership(), hasSet, setConst, setAttr, setStatement.TakeOwnership());
|
||||
currentToken = current;
|
||||
return true;
|
||||
}
|
||||
|
@ -590,7 +605,8 @@ namespace MalachScript::Parser {
|
|||
logUnexpectedTokenWithoutExpected(current);
|
||||
}
|
||||
}
|
||||
out = new ParsedIfStatement(TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()),
|
||||
out = new ParsedIfStatement(ScriptTextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd(),
|
||||
current->GetSpan().GetScriptName()),
|
||||
condition.TakeOwnership(), body.TakeOwnership(), elseStatement.TakeOwnership());
|
||||
currentToken = current;
|
||||
return true;
|
||||
|
@ -637,8 +653,9 @@ namespace MalachScript::Parser {
|
|||
// TODO: Default values
|
||||
// TODO: Creating multiple vars in a single line (int a, b, c)
|
||||
EXPECT_TOKEN(current, SemicolonSymbol);
|
||||
out = new ParsedVarStatement(TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()), access,
|
||||
typeStatement.TakeOwnership(), identifier);
|
||||
out = new ParsedVarStatement(ScriptTextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd(),
|
||||
current->GetSpan().GetScriptName()),
|
||||
access, typeStatement.TakeOwnership(), identifier);
|
||||
currentToken = current;
|
||||
return true;
|
||||
}
|
||||
|
@ -668,8 +685,10 @@ namespace MalachScript::Parser {
|
|||
logUnexpectedToken(CloseCurlyParenthesisSymbol, current);
|
||||
}
|
||||
|
||||
out = new ParsedStatBlockStatement(TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()),
|
||||
statements);
|
||||
out =
|
||||
new ParsedStatBlockStatement(ScriptTextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd(),
|
||||
current->GetSpan().GetScriptName()),
|
||||
statements);
|
||||
currentToken = current;
|
||||
return true;
|
||||
}
|
||||
|
@ -740,9 +759,10 @@ namespace MalachScript::Parser {
|
|||
currentToken = current;
|
||||
return true;
|
||||
}
|
||||
out = new ParsedBinaryStatement<AssignmentOperator>(
|
||||
TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()), leftHand.TakeOwnership(), op,
|
||||
rightHand.TakeOwnership());
|
||||
out = new ParsedBinaryStatement<AssignmentOperator>(ScriptTextSpan(currentToken->GetSpan().GetStart(),
|
||||
current->GetSpan().GetEnd(),
|
||||
current->GetSpan().GetScriptName()),
|
||||
leftHand.TakeOwnership(), op, rightHand.TakeOwnership());
|
||||
currentToken = current;
|
||||
return true;
|
||||
}
|
||||
|
@ -764,8 +784,9 @@ namespace MalachScript::Parser {
|
|||
currentToken = current; \
|
||||
return true; \
|
||||
} \
|
||||
out = new ParsedBinaryStatement < operator>(TextSpan(currentToken->GetSpan().GetStart(), \
|
||||
current->GetSpan().GetEnd()), \
|
||||
out = new ParsedBinaryStatement < operator>(ScriptTextSpan(currentToken->GetSpan().GetStart(), \
|
||||
current->GetSpan().GetEnd(), \
|
||||
current->GetSpan().GetScriptName()), \
|
||||
leftHand.TakeOwnership(), name, rightHand.TakeOwnership()); \
|
||||
currentToken = current; \
|
||||
return true; \
|
||||
|
@ -804,12 +825,16 @@ namespace MalachScript::Parser {
|
|||
|
||||
// TODO: remainder of
|
||||
if (current->GetKind() == LexTokenKind::PlusPlusSymbol) {
|
||||
operand = new ParsedIncrementStatement(TextSpan(operand->GetSpan().GetStart(), current->GetSpan().GetEnd()),
|
||||
operand.TakeOwnership());
|
||||
operand =
|
||||
new ParsedIncrementStatement(ScriptTextSpan(operand->GetSpan().GetStart(), current->GetSpan().GetEnd(),
|
||||
current->GetSpan().GetScriptName()),
|
||||
operand.TakeOwnership());
|
||||
PROGRESS_TOKEN(current);
|
||||
} else if (current->GetKind() == LexTokenKind::MinusMinusSymbol) {
|
||||
operand = new ParsedDecrementStatement(TextSpan(operand->GetSpan().GetStart(), current->GetSpan().GetEnd()),
|
||||
operand.TakeOwnership());
|
||||
operand =
|
||||
new ParsedDecrementStatement(ScriptTextSpan(operand->GetSpan().GetStart(), current->GetSpan().GetEnd(),
|
||||
current->GetSpan().GetScriptName()),
|
||||
operand.TakeOwnership());
|
||||
PROGRESS_TOKEN(current);
|
||||
}
|
||||
|
||||
|
@ -897,7 +922,9 @@ namespace MalachScript::Parser {
|
|||
ScopedPtr<const ParsedStatement> returnBody;
|
||||
ParseAssign(returnBody, currentToken, log);
|
||||
EXPECT_TOKEN(currentToken, SemicolonSymbol);
|
||||
out = new ParsedReturnStatement(TextSpan(start, currentToken->GetSpan().GetEnd()), returnBody.TakeOwnership());
|
||||
out = new ParsedReturnStatement(
|
||||
ScriptTextSpan(start, currentToken->GetSpan().GetEnd(), currentToken->GetSpan().GetScriptName()),
|
||||
returnBody.TakeOwnership());
|
||||
return true;
|
||||
}
|
||||
bool Parser::ParseExprStat(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken,
|
||||
|
@ -913,7 +940,9 @@ namespace MalachScript::Parser {
|
|||
std::vector<Identifier> scope;
|
||||
auto start = currentToken->GetSpan().GetStart();
|
||||
if (ParseScope(scope, currentToken, log)) {
|
||||
out = new ParsedVarAccessStatement(TextSpan(start, currentToken->GetSpan().GetEnd()), scope);
|
||||
out = new ParsedVarAccessStatement(
|
||||
ScriptTextSpan(start, currentToken->GetSpan().GetEnd(), currentToken->GetSpan().GetScriptName()),
|
||||
scope);
|
||||
return true;
|
||||
}
|
||||
Identifier identifier;
|
||||
|
@ -934,7 +963,8 @@ namespace MalachScript::Parser {
|
|||
auto start = currentToken->GetSpan().GetStart();
|
||||
PROGRESS_TOKEN(currentToken);
|
||||
EXPECT_TOKEN(currentToken, SemicolonSymbol);
|
||||
out = new ParsedContinueStatement(TextSpan(start, currentToken->GetSpan().GetEnd()));
|
||||
out = new ParsedContinueStatement(
|
||||
ScriptTextSpan(start, currentToken->GetSpan().GetEnd(), currentToken->GetSpan().GetScriptName()));
|
||||
return true;
|
||||
}
|
||||
bool Parser::ParseBreak(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken,
|
||||
|
@ -945,7 +975,8 @@ namespace MalachScript::Parser {
|
|||
auto start = currentToken->GetSpan().GetStart();
|
||||
PROGRESS_TOKEN(currentToken);
|
||||
EXPECT_TOKEN(currentToken, SemicolonSymbol);
|
||||
out = new ParsedBreakStatement(TextSpan(start, currentToken->GetSpan().GetEnd()));
|
||||
out = new ParsedBreakStatement(
|
||||
ScriptTextSpan(start, currentToken->GetSpan().GetEnd(), currentToken->GetSpan().GetScriptName()));
|
||||
return true;
|
||||
}
|
||||
bool Parser::ParseForStatement(ScopedPtr<const ParsedStatement>& out, const LexToken*& currentToken,
|
||||
|
@ -983,7 +1014,8 @@ namespace MalachScript::Parser {
|
|||
return false;
|
||||
}
|
||||
|
||||
out = new ParsedForStatement(TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()),
|
||||
out = new ParsedForStatement(ScriptTextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd(),
|
||||
current->GetSpan().GetScriptName()),
|
||||
init.TakeOwnership(), condition.TakeOwnership(), increment,
|
||||
statementBlock.TakeOwnership());
|
||||
currentToken = current;
|
||||
|
@ -1009,7 +1041,8 @@ namespace MalachScript::Parser {
|
|||
logUnexpectedTokenWithoutExpected(current);
|
||||
return false;
|
||||
}
|
||||
out = new ParsedWhileStatement(TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()),
|
||||
out = new ParsedWhileStatement(ScriptTextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd(),
|
||||
current->GetSpan().GetScriptName()),
|
||||
condition.TakeOwnership(), body.TakeOwnership());
|
||||
currentToken = current;
|
||||
return true;
|
||||
|
@ -1035,7 +1068,8 @@ namespace MalachScript::Parser {
|
|||
}
|
||||
EXPECT_TOKEN(current, CloseParenthesisSymbol);
|
||||
EXPECT_TOKEN(current, SemicolonSymbol);
|
||||
out = new ParsedDoWhileStatement(TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()),
|
||||
out = new ParsedDoWhileStatement(ScriptTextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd(),
|
||||
current->GetSpan().GetScriptName()),
|
||||
condition.TakeOwnership(), body.TakeOwnership());
|
||||
currentToken = current;
|
||||
return true;
|
||||
|
@ -1060,7 +1094,8 @@ namespace MalachScript::Parser {
|
|||
return false;
|
||||
}
|
||||
|
||||
out = new ParsedTryStatement(TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()),
|
||||
out = new ParsedTryStatement(ScriptTextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd(),
|
||||
current->GetSpan().GetScriptName()),
|
||||
tryStatement.TakeOwnership(), catchStatement.TakeOwnership());
|
||||
currentToken = current;
|
||||
return true;
|
||||
|
@ -1103,7 +1138,8 @@ namespace MalachScript::Parser {
|
|||
// Consume }
|
||||
PROGRESS_TOKEN(current);
|
||||
|
||||
out = new ParsedSwitchStatement(TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()),
|
||||
out = new ParsedSwitchStatement(ScriptTextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd(),
|
||||
current->GetSpan().GetScriptName()),
|
||||
expression.TakeOwnership(), caseStatements);
|
||||
currentToken = current;
|
||||
return true;
|
||||
|
@ -1146,7 +1182,8 @@ namespace MalachScript::Parser {
|
|||
}
|
||||
}
|
||||
|
||||
out = new ParsedCaseStatement(TextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd()),
|
||||
out = new ParsedCaseStatement(ScriptTextSpan(currentToken->GetSpan().GetStart(), current->GetSpan().GetEnd(),
|
||||
current->GetSpan().GetScriptName()),
|
||||
expression.TakeOwnership(), statements);
|
||||
currentToken = current;
|
||||
return true;
|
||||
|
|
|
@ -11,12 +11,11 @@
|
|||
namespace MalachScript::Parser {
|
||||
class Parser {
|
||||
public:
|
||||
static const ParsedScriptStatement* Parse(const LexToken* firstToken, std::string_view scriptName,
|
||||
Diagnostics::Logger* diagnostics);
|
||||
static const ParsedScriptStatement* Parse(const LexToken* firstToken, Diagnostics::Logger* diagnostics);
|
||||
|
||||
private:
|
||||
using log_func = const std::function<void(Diagnostics::DiagnosticLevel level, Diagnostics::DiagnosticType,
|
||||
const TextSpan&, const std::vector<std::string>&)>;
|
||||
const ScriptTextSpan&, const std::vector<std::string>&)>;
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Underlying functions are laid out in the order they are defined in the grammar.ebnf //
|
||||
|
|
|
@ -15,18 +15,18 @@
|
|||
#include "ParsedStatementKind.hpp"
|
||||
namespace MalachScript::Parser {
|
||||
class ParsedStatement {
|
||||
TextSpan _span;
|
||||
ScriptTextSpan _span;
|
||||
|
||||
public:
|
||||
ParsedStatement(TextSpan span) : _span(span) {}
|
||||
ParsedStatement(ScriptTextSpan span) : _span(span) {}
|
||||
virtual ~ParsedStatement() = default;
|
||||
[[nodiscard]] virtual ParsedStatementKind GetKind() const noexcept = 0;
|
||||
[[nodiscard]] inline const TextSpan& GetSpan() const noexcept { return _span; }
|
||||
[[nodiscard]] inline const ScriptTextSpan& GetSpan() const noexcept { return _span; }
|
||||
};
|
||||
|
||||
template <ParsedStatementKind kind> class ParsedStatementImpl : public ParsedStatement {
|
||||
public:
|
||||
ParsedStatementImpl(TextSpan span) : ParsedStatement(span) {}
|
||||
ParsedStatementImpl(ScriptTextSpan span) : ParsedStatement(span) {}
|
||||
[[nodiscard]] inline ParsedStatementKind GetKind() const noexcept final { return kind; }
|
||||
};
|
||||
|
||||
|
@ -34,7 +34,7 @@ namespace MalachScript::Parser {
|
|||
std::vector<std::unique_ptr<const ParsedStatement>> _statements;
|
||||
|
||||
public:
|
||||
ParsedScriptStatement(TextSpan span, const std::vector<const ParsedStatement*>& statements)
|
||||
ParsedScriptStatement(ScriptTextSpan span, const std::vector<const ParsedStatement*>& statements)
|
||||
: ParsedStatementImpl<ParsedStatementKind::Script>(span), _statements(statements.size()) {
|
||||
for (size_t i = 0; i < statements.size(); i++)
|
||||
_statements[i] = std::unique_ptr<const ParsedStatement>(statements[i]);
|
||||
|
@ -47,7 +47,7 @@ namespace MalachScript::Parser {
|
|||
|
||||
class ParsedClassStatement : public ParsedStatementImpl<ParsedStatementKind::Class> {
|
||||
public:
|
||||
ParsedClassStatement(TextSpan span, ClassAttr classAttr, Identifier identifier,
|
||||
ParsedClassStatement(ScriptTextSpan span, ClassAttr classAttr, Identifier identifier,
|
||||
const std::vector<Identifier>& inherits, const std::vector<const ParsedStatement*>& body)
|
||||
: ParsedStatementImpl<ParsedStatementKind::Class>(span), _classAttr(classAttr), _identifier(identifier),
|
||||
_inherits(inherits), _body(body.size()) {
|
||||
|
@ -75,7 +75,7 @@ namespace MalachScript::Parser {
|
|||
Identifier _defineTo;
|
||||
|
||||
public:
|
||||
ParsedTypeDefStatement(TextSpan span, const Identifier& defineFrom, const Identifier& defineTo)
|
||||
ParsedTypeDefStatement(ScriptTextSpan span, const Identifier& defineFrom, const Identifier& defineTo)
|
||||
: ParsedStatementImpl<ParsedStatementKind::TypeDef>(span), _defineFrom(defineFrom), _defineTo(defineTo) {}
|
||||
|
||||
[[nodiscard]] inline const Identifier& GetDefineFrom() const noexcept { return _defineFrom; }
|
||||
|
@ -87,7 +87,7 @@ namespace MalachScript::Parser {
|
|||
std::unique_ptr<const ParsedStatement> _parsedScript;
|
||||
|
||||
public:
|
||||
ParsedNamespaceStatement(TextSpan span, const Identifier& identifier, const ParsedScriptStatement* script)
|
||||
ParsedNamespaceStatement(ScriptTextSpan span, const Identifier& identifier, const ParsedScriptStatement* script)
|
||||
: ParsedStatementImpl<ParsedStatementKind::Namespace>(span), _identifier(identifier),
|
||||
_parsedScript(script) {}
|
||||
|
||||
|
@ -104,7 +104,7 @@ namespace MalachScript::Parser {
|
|||
ScopedIdentifier _scopedIdentifier;
|
||||
|
||||
public:
|
||||
ParsedTypeStatement(TextSpan span, bool isConst, bool isArray, bool isHandle,
|
||||
ParsedTypeStatement(ScriptTextSpan span, bool isConst, bool isArray, bool isHandle,
|
||||
const ScopedIdentifier& scopedIdentifier)
|
||||
: ParsedStatementImpl<ParsedStatementKind::Type>(span), _isConst(isConst), _isArray(isArray),
|
||||
_isHandle(isHandle), _scopedIdentifier(scopedIdentifier) {}
|
||||
|
@ -155,7 +155,7 @@ namespace MalachScript::Parser {
|
|||
std::vector<std::unique_ptr<const ParsedParameter>> _parameters;
|
||||
|
||||
public:
|
||||
ParsedParamListStatement(TextSpan span, const std::vector<const ParsedParameter*>& parameters)
|
||||
ParsedParamListStatement(ScriptTextSpan span, const std::vector<const ParsedParameter*>& parameters)
|
||||
: ParsedStatementImpl<ParsedStatementKind::ParamList>(span), _parameters(parameters.size()) {
|
||||
for (size_t i = 0; i < parameters.size(); i++) {
|
||||
_parameters[i] = std::unique_ptr<const ParsedParameter>(parameters[i]);
|
||||
|
@ -181,7 +181,7 @@ namespace MalachScript::Parser {
|
|||
std::unique_ptr<const ParsedStatement> _statBlock;
|
||||
|
||||
public:
|
||||
ParsedFuncStatement(const TextSpan& span, bool isShared, bool isExternal, AccessModifier access,
|
||||
ParsedFuncStatement(const ScriptTextSpan& span, bool isShared, bool isExternal, AccessModifier access,
|
||||
const ParsedStatement* type, bool returnsReference, const Identifier& identifier,
|
||||
const ParsedStatement* paramList, bool isConst, FuncAttr funcAttr,
|
||||
const ParsedStatement* statBlock)
|
||||
|
@ -209,7 +209,7 @@ namespace MalachScript::Parser {
|
|||
|
||||
class ParsedVirtPropStatement : public ParsedStatementImpl<ParsedStatementKind::VirtProp> {
|
||||
public:
|
||||
ParsedVirtPropStatement(const TextSpan& span, AccessModifier access, const ParsedStatement* returnType,
|
||||
ParsedVirtPropStatement(const ScriptTextSpan& span, AccessModifier access, const ParsedStatement* returnType,
|
||||
bool isReturnTypeRef, Identifier identifier, bool hasGet, bool getConst,
|
||||
FuncAttr getAttr, const ParsedStatement* getStatement, bool hasSet, bool setConst,
|
||||
FuncAttr setAttr, const ParsedStatement* setStatement)
|
||||
|
@ -257,7 +257,7 @@ namespace MalachScript::Parser {
|
|||
|
||||
class ParsedStatBlockStatement : public ParsedStatementImpl<ParsedStatementKind::StatBlock> {
|
||||
public:
|
||||
ParsedStatBlockStatement(const TextSpan& span, const std::vector<const ParsedStatement*>& statements)
|
||||
ParsedStatBlockStatement(const ScriptTextSpan& span, const std::vector<const ParsedStatement*>& statements)
|
||||
: ParsedStatementImpl(span), _statements(statements.size()) {
|
||||
for (size_t i = 0; i < statements.size(); i++) {
|
||||
_statements[i] = std::unique_ptr<const ParsedStatement>(statements[i]);
|
||||
|
@ -274,7 +274,7 @@ namespace MalachScript::Parser {
|
|||
|
||||
class ParsedVarStatement : public ParsedStatementImpl<ParsedStatementKind::Var> {
|
||||
public:
|
||||
ParsedVarStatement(const TextSpan& span, AccessModifier access, const ParsedTypeStatement* typeStatement,
|
||||
ParsedVarStatement(const ScriptTextSpan& span, AccessModifier access, const ParsedTypeStatement* typeStatement,
|
||||
Identifier identifier)
|
||||
: ParsedStatementImpl(span), _access(access), _typeStatement(typeStatement), _identifier(identifier) {}
|
||||
|
||||
|
@ -292,7 +292,7 @@ namespace MalachScript::Parser {
|
|||
|
||||
class ParsedIfStatement : public ParsedStatementImpl<ParsedStatementKind::If> {
|
||||
public:
|
||||
ParsedIfStatement(const TextSpan& span, const ParsedStatement* condition, const ParsedStatement* body,
|
||||
ParsedIfStatement(const ScriptTextSpan& span, const ParsedStatement* condition, const ParsedStatement* body,
|
||||
const ParsedStatement* elseStatement)
|
||||
: ParsedStatementImpl(span), _condition(condition), _body(body), _elseStatement(elseStatement) {}
|
||||
|
||||
|
@ -313,7 +313,7 @@ namespace MalachScript::Parser {
|
|||
template <class TOperator>
|
||||
class ParsedBinaryStatement : public ParsedStatementImpl<ParsedStatementKind::BinaryExpression> {
|
||||
public:
|
||||
ParsedBinaryStatement(const TextSpan& span, const ParsedStatement* leftHand, TOperator op,
|
||||
ParsedBinaryStatement(const ScriptTextSpan& span, const ParsedStatement* leftHand, TOperator op,
|
||||
const ParsedStatement* rightHand)
|
||||
: ParsedStatementImpl(span), _leftHand(leftHand), _operator(op), _rightHand(rightHand) {}
|
||||
|
||||
|
@ -327,12 +327,12 @@ namespace MalachScript::Parser {
|
|||
|
||||
class ParsedVoidStatement : public ParsedStatementImpl<ParsedStatementKind::Void> {
|
||||
public:
|
||||
ParsedVoidStatement(const TextSpan& span) : ParsedStatementImpl(span) {}
|
||||
ParsedVoidStatement(const ScriptTextSpan& span) : ParsedStatementImpl(span) {}
|
||||
};
|
||||
|
||||
template <class T> class ParsedLiteralStatement : public ParsedStatementImpl<ParsedStatementKind::Literal> {
|
||||
public:
|
||||
ParsedLiteralStatement(const TextSpan& span, T literalValue)
|
||||
ParsedLiteralStatement(const ScriptTextSpan& span, T literalValue)
|
||||
: ParsedStatementImpl(span), _literalValue(literalValue) {}
|
||||
|
||||
[[nodiscard]] inline const T& GetLiteralValue() const noexcept { return _literalValue; }
|
||||
|
@ -343,7 +343,7 @@ namespace MalachScript::Parser {
|
|||
|
||||
class ParsedReturnStatement : public ParsedStatementImpl<ParsedStatementKind::Return> {
|
||||
public:
|
||||
ParsedReturnStatement(const TextSpan& span, const ParsedStatement* statement)
|
||||
ParsedReturnStatement(const ScriptTextSpan& span, const ParsedStatement* statement)
|
||||
: ParsedStatementImpl(span), _statement(statement) {}
|
||||
|
||||
private:
|
||||
|
@ -352,7 +352,7 @@ namespace MalachScript::Parser {
|
|||
|
||||
class ParsedVarAccessStatement : public ParsedStatementImpl<ParsedStatementKind::VarAccess> {
|
||||
public:
|
||||
ParsedVarAccessStatement(const TextSpan& span, std::vector<Identifier> scope)
|
||||
ParsedVarAccessStatement(const ScriptTextSpan& span, std::vector<Identifier> scope)
|
||||
: ParsedStatementImpl(span), _scope(std::move(scope)) {}
|
||||
|
||||
private:
|
||||
|
@ -361,7 +361,7 @@ namespace MalachScript::Parser {
|
|||
|
||||
class ParsedIncrementStatement : public ParsedStatementImpl<ParsedStatementKind::Increment> {
|
||||
public:
|
||||
ParsedIncrementStatement(const TextSpan& span, const ParsedStatement* statement)
|
||||
ParsedIncrementStatement(const ScriptTextSpan& span, const ParsedStatement* statement)
|
||||
: ParsedStatementImpl(span), _statement(statement) {}
|
||||
|
||||
private:
|
||||
|
@ -370,7 +370,7 @@ namespace MalachScript::Parser {
|
|||
|
||||
class ParsedDecrementStatement : public ParsedStatementImpl<ParsedStatementKind::Decrement> {
|
||||
public:
|
||||
ParsedDecrementStatement(const TextSpan& span, const ParsedStatement* statement)
|
||||
ParsedDecrementStatement(const ScriptTextSpan& span, const ParsedStatement* statement)
|
||||
: ParsedStatementImpl(span), _statement(statement) {}
|
||||
|
||||
private:
|
||||
|
@ -379,17 +379,17 @@ namespace MalachScript::Parser {
|
|||
|
||||
class ParsedContinueStatement : public ParsedStatementImpl<ParsedStatementKind::Continue> {
|
||||
public:
|
||||
ParsedContinueStatement(const TextSpan& span) : ParsedStatementImpl(span) {}
|
||||
ParsedContinueStatement(const ScriptTextSpan& span) : ParsedStatementImpl(span) {}
|
||||
};
|
||||
|
||||
class ParsedBreakStatement : public ParsedStatementImpl<ParsedStatementKind::Break> {
|
||||
public:
|
||||
ParsedBreakStatement(const TextSpan& span) : ParsedStatementImpl(span) {}
|
||||
ParsedBreakStatement(const ScriptTextSpan& span) : ParsedStatementImpl(span) {}
|
||||
};
|
||||
|
||||
class ParsedForStatement : public ParsedStatementImpl<ParsedStatementKind::For> {
|
||||
public:
|
||||
ParsedForStatement(const TextSpan& span, const ParsedStatement* init, const ParsedStatement* condition,
|
||||
ParsedForStatement(const ScriptTextSpan& span, const ParsedStatement* init, const ParsedStatement* condition,
|
||||
std::vector<const ParsedStatement*> increment, const ParsedStatement* body)
|
||||
: ParsedStatementImpl(span), _init(init), _condition(condition), _increment(increment.size()), _body(body) {
|
||||
for (size_t i = 0; i < increment.size(); i++) {
|
||||
|
@ -413,7 +413,7 @@ namespace MalachScript::Parser {
|
|||
|
||||
class ParsedWhileStatement : public ParsedStatementImpl<ParsedStatementKind::While> {
|
||||
public:
|
||||
ParsedWhileStatement(const TextSpan& span, const ParsedStatement* condition, const ParsedStatement* body)
|
||||
ParsedWhileStatement(const ScriptTextSpan& span, const ParsedStatement* condition, const ParsedStatement* body)
|
||||
: ParsedStatementImpl(span), _condition(condition), _body(body) {}
|
||||
|
||||
private:
|
||||
|
@ -423,7 +423,8 @@ namespace MalachScript::Parser {
|
|||
|
||||
class ParsedDoWhileStatement : public ParsedStatementImpl<ParsedStatementKind::DoWhile> {
|
||||
public:
|
||||
ParsedDoWhileStatement(const TextSpan& span, const ParsedStatement* condition, const ParsedStatement* body)
|
||||
ParsedDoWhileStatement(const ScriptTextSpan& span, const ParsedStatement* condition,
|
||||
const ParsedStatement* body)
|
||||
: ParsedStatementImpl(span), _condition(condition), _body(body) {}
|
||||
|
||||
private:
|
||||
|
@ -433,7 +434,7 @@ namespace MalachScript::Parser {
|
|||
|
||||
class ParsedTryStatement : public ParsedStatementImpl<ParsedStatementKind::Try> {
|
||||
public:
|
||||
ParsedTryStatement(const TextSpan& span, const ParsedStatement* tryStatement,
|
||||
ParsedTryStatement(const ScriptTextSpan& span, const ParsedStatement* tryStatement,
|
||||
const ParsedStatement* catchStatement)
|
||||
: ParsedStatementImpl(span), _tryStatement(tryStatement), _catchStatement(catchStatement) {}
|
||||
|
||||
|
@ -444,7 +445,7 @@ namespace MalachScript::Parser {
|
|||
|
||||
class ParsedSwitchStatement : public ParsedStatementImpl<ParsedStatementKind::Switch> {
|
||||
public:
|
||||
ParsedSwitchStatement(const TextSpan& span, const ParsedStatement* expression,
|
||||
ParsedSwitchStatement(const ScriptTextSpan& span, const ParsedStatement* expression,
|
||||
const std::vector<const ParsedStatement*>& cases)
|
||||
: ParsedStatementImpl(span), _expression(expression), _cases(cases.size()) {
|
||||
for (size_t i = 0; i < cases.size(); i++) {
|
||||
|
@ -459,7 +460,7 @@ namespace MalachScript::Parser {
|
|||
|
||||
class ParsedCaseStatement : public ParsedStatementImpl<ParsedStatementKind::Case> {
|
||||
public:
|
||||
ParsedCaseStatement(const TextSpan& span, const ParsedStatement* expression,
|
||||
ParsedCaseStatement(const ScriptTextSpan& span, const ParsedStatement* expression,
|
||||
const std::vector<const ParsedStatement*>& statements)
|
||||
: ParsedStatementImpl(span), _expression(expression), _statements(statements.size()) {
|
||||
for (size_t i = 0; i < statements.size(); i++) {
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
#define MALACHSCRIPT_TEXTSPAN_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <string>
|
||||
|
||||
namespace MalachScript {
|
||||
class TextSpan {
|
||||
size_t _start;
|
||||
|
@ -14,6 +16,24 @@ namespace MalachScript {
|
|||
inline bool operator==(const TextSpan& rhs) const { return _start == rhs._start && _end == rhs._end; }
|
||||
inline bool operator!=(const TextSpan& rhs) const { return !(rhs == *this); }
|
||||
};
|
||||
|
||||
class ScriptTextSpan {
|
||||
TextSpan _span;
|
||||
const std::string_view& _scriptName;
|
||||
|
||||
public:
|
||||
inline ScriptTextSpan(size_t start, size_t end, const std::string_view& scriptName)
|
||||
: _span(start, end), _scriptName(scriptName) {}
|
||||
[[nodiscard]] inline TextSpan GetSpan() const noexcept { return _span; }
|
||||
[[nodiscard]] inline const std::string_view& GetScriptName() const noexcept { return _scriptName; }
|
||||
inline bool operator==(const ScriptTextSpan& rhs) const {
|
||||
return _span == rhs._span && _scriptName == rhs._scriptName;
|
||||
}
|
||||
inline bool operator!=(const ScriptTextSpan& rhs) const { return !(rhs == *this); }
|
||||
[[nodiscard]] inline size_t GetStart() const noexcept { return _span.GetStart(); }
|
||||
[[nodiscard]] inline size_t GetEnd() const noexcept { return _span.GetEnd(); }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // MALACHSCRIPT_TEXTSPAN_HPP
|
||||
|
|
Loading…
Reference in New Issue