-
-
Save commander-trashdin/5eedbe0dcd8d73be64a1dbef413a62db to your computer and use it in GitHub Desktop.
scheme_parser
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#include <memory> | |
#include </home/aun/SDA/shad-cpp0/scheme-tokenizer/tokenizer.h> | |
enum class Types { cellType, numberType, symbolType }; | |
class Object { | |
public: | |
virtual Types ID() = 0; | |
virtual ~Object() = default; | |
}; | |
class Cell : public Object { | |
public: | |
Cell() : head_(nullptr), tail_(nullptr) { | |
} | |
Cell(std::shared_ptr<Object> head, std::shared_ptr<Object> tail) : head_(head), tail_(tail) { | |
} | |
Types ID() { | |
return Types::cellType; | |
} | |
std::shared_ptr<Object>& GetFirst() { | |
return head_; | |
} | |
std::shared_ptr<Object>& GetSecond() { | |
return tail_; | |
} | |
private: | |
std::shared_ptr<Object> head_; | |
std::shared_ptr<Object> tail_; | |
}; | |
class Number : public Object { | |
public: | |
Number() : value_(0) { | |
} | |
explicit Number(int value) : value_(value) { | |
} | |
Types ID() { | |
return Types::numberType; | |
} | |
int GetValue() const { | |
return value_; | |
} | |
private: | |
int value_; | |
}; | |
class Symbol : public Object { | |
public: | |
Symbol() : name_("") { | |
} | |
explicit Symbol(std::string name) : name_(name) { | |
} | |
Types ID() { | |
return Types::symbolType; | |
} | |
const std::string& GetName() const { | |
return name_; | |
} | |
private: | |
std::string name_; | |
}; | |
struct SyntaxError : public std::runtime_error { | |
explicit SyntaxError(const std::string& what) : std::runtime_error(what) { | |
} | |
}; | |
bool IsNumber(const std::shared_ptr<Object>& obj) { | |
return Types::numberType == obj.get()->ID(); | |
} | |
std::shared_ptr<Number> AsNumber(const std::shared_ptr<Object>& obj) { | |
return std::dynamic_pointer_cast<Number>(obj); | |
} | |
bool IsCell(const std::shared_ptr<Object>& obj) { | |
return Types::cellType == obj->ID(); | |
} | |
std::shared_ptr<Cell> AsCell(const std::shared_ptr<Object>& obj) { | |
return std::dynamic_pointer_cast<Cell>(obj); | |
} | |
bool IsSymbol(const std::shared_ptr<Object>& obj) { | |
return Types::symbolType == obj->ID(); | |
} | |
std::shared_ptr<Symbol> AsSymbol(const std::shared_ptr<Object>& obj) { | |
return std::dynamic_pointer_cast<Symbol>(obj); | |
} | |
std::shared_ptr<Object> ReadList(Tokenizer* tokenizer); | |
std::shared_ptr<Object> Read(Tokenizer* tokenizer) { | |
if (tokenizer->IsEnd()) { | |
return nullptr; | |
} | |
auto current_object = tokenizer->GetToken(); | |
if (std::holds_alternative<SymbolToken>(current_object)) { | |
tokenizer->Next(); | |
return std::make_shared<Symbol>(std::get<SymbolToken>(current_object).name); | |
} else if (std::holds_alternative<ConstantToken>(tokenizer->GetToken())) { | |
tokenizer->Next(); | |
return std::make_shared<Number>(std::get<ConstantToken>(current_object).value); | |
} else if (std::holds_alternative<BracketToken>(current_object) && | |
std::get<BracketToken>(current_object) == BracketToken::OPEN) { | |
tokenizer->Next(); | |
auto ls = ReadList(tokenizer); | |
tokenizer->Next(); | |
return ls; | |
} else if (std::holds_alternative<DotToken>(current_object)) { | |
} else if (std::holds_alternative<QuoteToken>(current_object)) { | |
} else { | |
} | |
} | |
std::shared_ptr<Object> ReadList(Tokenizer* tokenizer) { | |
std::shared_ptr<Object> head = nullptr; | |
std::shared_ptr<Cell> tail = nullptr; | |
while (!tokenizer->IsEnd()) { | |
auto current_token = tokenizer->GetToken(); | |
if (std::holds_alternative<BracketToken>(current_token) && | |
std::get<BracketToken>(current_token) == BracketToken::CLOSE) { | |
return head; | |
} | |
auto current_object = Read(tokenizer); | |
auto new_cell = std::make_shared<Cell>(Cell()); | |
new_cell->GetFirst() = current_object; | |
if (head == nullptr) { | |
head = new_cell; | |
tail = new_cell; | |
} else { | |
tail->GetSecond() = new_cell; | |
tail = new_cell; | |
} | |
tokenizer->Next(); | |
} | |
return head; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment