Implements namespace statement.
This commit is contained in:
parent
2fb1b68ead
commit
43f080cc48
|
@ -3,7 +3,7 @@
|
|||
|
||||
#include <string_view>
|
||||
#include "../../Diagnostics/Diagnostics.hpp"
|
||||
#include "../../Utils/MemoryAllocator.hpp"
|
||||
#include "../../Utils/MemoryPool.hpp"
|
||||
#include "LexToken.hpp"
|
||||
|
||||
namespace MalachScript::Parser {
|
||||
|
@ -22,7 +22,7 @@ namespace MalachScript::Parser {
|
|||
size_t _scriptLength;
|
||||
Diagnostics::Diagnostics* _diagnostics;
|
||||
|
||||
Utils::MemoryAllocator<2048, 1024> _allocator;
|
||||
Utils::MemoryPool<2048, 1024> _allocator;
|
||||
|
||||
inline char8_t Consume() {
|
||||
if (++_position >= _scriptLength) {
|
||||
|
|
|
@ -14,7 +14,9 @@
|
|||
}
|
||||
|
||||
namespace MalachScript::Parser {
|
||||
ParsedScriptStatement* Parser::Parse() {
|
||||
const ParsedScriptStatement* Parser::Parse() { return ParseScript(); }
|
||||
|
||||
const ParsedScriptStatement* Parser::ParseScript() {
|
||||
std::vector<const ParsedStatement*> statements;
|
||||
statements.reserve(32);
|
||||
size_t current = 0;
|
||||
|
@ -26,7 +28,10 @@ namespace MalachScript::Parser {
|
|||
break;
|
||||
}
|
||||
const ParsedStatement* statement;
|
||||
if (ParseClass(statement)) {
|
||||
auto result = ParseClass(statement) || ParseNamespace(statement);
|
||||
if (!result) {
|
||||
// TODO: Log error
|
||||
continue;
|
||||
}
|
||||
statements.push_back(statement);
|
||||
current++;
|
||||
|
@ -123,16 +128,28 @@ namespace MalachScript::Parser {
|
|||
|
||||
PROGRESS_TOKEN(_currentToken);
|
||||
Identifier defineTo;
|
||||
if (!ParseIdentifier(defineTo, _currentToken, encounteredErrors)) {
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, _currentToken->GetSpan());
|
||||
}
|
||||
ParseIdentifier(defineTo, _currentToken, encounteredErrors);
|
||||
PROGRESS_TOKEN(_currentToken);
|
||||
EXPECT_TOKEN(_currentToken, SemicolonSymbol);
|
||||
PROGRESS_TOKEN(_currentToken);
|
||||
if (_currentToken->GetKind() != LexTokenKind::SemicolonSymbol) {
|
||||
LogError(Diagnostics::DiagnosticType::UnexpectedToken, _currentToken->GetSpan());
|
||||
}
|
||||
out = new ParsedTypeDefStatement(TextSpan(start, _currentToken->GetSpan().GetEnd()), defineTo, defineFrom);
|
||||
return true;
|
||||
}
|
||||
bool Parser::ParseNamespace(const ParsedStatement*& out) {
|
||||
if (_currentToken->GetKind() != LexTokenKind::NamespaceKeyword) {
|
||||
return false;
|
||||
}
|
||||
auto start = _currentToken->GetSpan().GetStart();
|
||||
PROGRESS_TOKEN(_currentToken);
|
||||
Identifier identifier;
|
||||
bool encounteredErrors = false;
|
||||
ParseIdentifier(identifier, _currentToken, encounteredErrors);
|
||||
auto script = ParseScript();
|
||||
auto end = _currentToken->GetSpan().GetEnd();
|
||||
PROGRESS_TOKEN(_currentToken);
|
||||
out = new ParsedNamespaceStatement(TextSpan(start, end), identifier, script);
|
||||
return true;
|
||||
}
|
||||
bool Parser::ParseVirtProp([[maybe_unused]] const ParsedStatement*& out) { return false; }
|
||||
bool Parser::ParseFunc([[maybe_unused]] const ParsedStatement*& out) { return false; }
|
||||
bool Parser::ParseVar([[maybe_unused]] const ParsedStatement*& out) { return false; }
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace MalachScript::Parser {
|
|||
public:
|
||||
Parser(std::u8string_view scriptName, const LexToken* firstToken, Diagnostics::Diagnostics* diagnostics)
|
||||
: _scriptName(scriptName), _diagnostics(diagnostics), _currentToken(firstToken) {}
|
||||
ParsedScriptStatement* Parse();
|
||||
const ParsedScriptStatement* Parse();
|
||||
|
||||
private:
|
||||
std::u8string_view _scriptName;
|
||||
|
@ -20,8 +20,10 @@ namespace MalachScript::Parser {
|
|||
_diagnostics->LogError(type, _scriptName, span);
|
||||
}
|
||||
|
||||
const ParsedScriptStatement* ParseScript();
|
||||
bool ParseClass(const ParsedStatement*& out);
|
||||
bool ParseTypeDef(const ParsedStatement*& out);
|
||||
bool ParseNamespace(const ParsedStatement*& out);
|
||||
bool ParseVirtProp(const ParsedStatement*& out);
|
||||
bool ParseFunc(const ParsedStatement*& out);
|
||||
bool ParseVar(const ParsedStatement*& out);
|
||||
|
|
|
@ -59,8 +59,21 @@ namespace MalachScript::Parser {
|
|||
ParsedTypeDefStatement(TextSpan span, const Identifier& defineFrom, const Identifier& defineTo)
|
||||
: ParsedStatementImpl<ParsedStatementKind::TypeDef>(span), _defineFrom(defineFrom), _defineTo(defineTo) {}
|
||||
|
||||
inline const Identifier& GetDefineFrom() const noexcept { return _defineFrom; }
|
||||
inline const Identifier& GetDefineTo() const noexcept { return _defineTo; }
|
||||
[[nodiscard]] inline const Identifier& GetDefineFrom() const noexcept { return _defineFrom; }
|
||||
[[nodiscard]] inline const Identifier& GetDefineTo() const noexcept { return _defineTo; }
|
||||
};
|
||||
|
||||
class ParsedNamespaceStatement : public ParsedStatementImpl<ParsedStatementKind::Namespace> {
|
||||
Identifier _identifier;
|
||||
const ParsedScriptStatement* _parsedScript;
|
||||
|
||||
public:
|
||||
ParsedNamespaceStatement(TextSpan span, const Identifier& identifier, const ParsedScriptStatement* script)
|
||||
: ParsedStatementImpl<ParsedStatementKind::Namespace>(span), _identifier(identifier),
|
||||
_parsedScript(script) {}
|
||||
|
||||
[[nodiscard]] inline const Identifier& GetIdentifier() const noexcept { return _identifier; }
|
||||
[[nodiscard]] inline const ParsedScriptStatement* GetScript() const noexcept { return _parsedScript; }
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -6,7 +6,8 @@ namespace MalachScript::Parser {
|
|||
Unknown,
|
||||
Script,
|
||||
Class,
|
||||
TypeDef
|
||||
TypeDef,
|
||||
Namespace
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#ifndef MALACHSCRIPT_MEMORYALLOCATOR_HPP
|
||||
#define MALACHSCRIPT_MEMORYALLOCATOR_HPP
|
||||
#ifndef MALACHSCRIPT_MEMORYPOOL_HPP
|
||||
#define MALACHSCRIPT_MEMORYPOOL_HPP
|
||||
|
||||
#include <cstddef>
|
||||
#include <cstdint>
|
||||
|
@ -7,13 +7,9 @@
|
|||
|
||||
namespace MalachScript::Utils {
|
||||
template <size_t initialSize, size_t steps>
|
||||
class MemoryAllocator {
|
||||
size_t _offset;
|
||||
size_t _capacity;
|
||||
uint8_t* _memory = nullptr;
|
||||
|
||||
class MemoryPool {
|
||||
public:
|
||||
MemoryAllocator() : _offset(0), _capacity(initialSize) {
|
||||
MemoryPool() : _offset(0), _capacity(initialSize) {
|
||||
auto *ptr = malloc(_capacity);
|
||||
if (ptr == nullptr) {
|
||||
throw std::logic_error("Out of memory.");
|
||||
|
@ -21,12 +17,25 @@ namespace MalachScript::Utils {
|
|||
_memory = static_cast<uint8_t*>(ptr);
|
||||
}
|
||||
|
||||
~MemoryAllocator(){
|
||||
~MemoryPool(){
|
||||
free(_memory);
|
||||
}
|
||||
|
||||
template <class T, class... parameters> T* Create(parameters... args){
|
||||
if (_offset + sizeof(T) >= _capacity) {
|
||||
IncreaseStep();
|
||||
}
|
||||
auto* element = new (_memory + _offset) T(args...);
|
||||
_offset += sizeof(T);
|
||||
return element;
|
||||
}
|
||||
|
||||
private:
|
||||
size_t _offset;
|
||||
size_t _capacity;
|
||||
uint8_t* _memory = nullptr;
|
||||
|
||||
void IncreaseStep(){
|
||||
_capacity += steps;
|
||||
auto newPtr = realloc(_memory, _capacity);
|
||||
if (newPtr == nullptr) {
|
||||
|
@ -34,12 +43,7 @@ namespace MalachScript::Utils {
|
|||
}
|
||||
_memory = static_cast<uint8_t*>(newPtr);
|
||||
}
|
||||
uint8_t* ptr = _memory + _offset;
|
||||
T* element = new (ptr) T(args...);
|
||||
_offset += sizeof(T);
|
||||
return element;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
#endif // MALACHSCRIPT_MEMORYALLOCATOR_HPP
|
||||
#endif // MALACHSCRIPT_MEMORYPOOL_HPP
|
Loading…
Reference in New Issue