Skip to content

Instantly share code, notes, and snippets.

@commander-trashdin
Created October 31, 2019 22:38
Show Gist options
  • Save commander-trashdin/5eedbe0dcd8d73be64a1dbef413a62db to your computer and use it in GitHub Desktop.
Save commander-trashdin/5eedbe0dcd8d73be64a1dbef413a62db to your computer and use it in GitHub Desktop.
scheme_parser
#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