forked from solstice/solstice
163 lines
4.8 KiB
C++
163 lines
4.8 KiB
C++
|
|
#include <groundvm.h>
|
||
|
|
#include <vector>
|
||
|
|
#include <string>
|
||
|
|
#include <fstream>
|
||
|
|
#include <iostream>
|
||
|
|
#include <sstream>
|
||
|
|
#include <optional>
|
||
|
|
|
||
|
|
namespace HighGround {
|
||
|
|
|
||
|
|
namespace Parser {
|
||
|
|
|
||
|
|
enum class HGNodeType {
|
||
|
|
Add, Subtract, Equal, Set, While, If, None, Root, CodeBlock
|
||
|
|
};
|
||
|
|
|
||
|
|
class HGNode;
|
||
|
|
|
||
|
|
class HGNode {
|
||
|
|
HGNodeType nodeType = HGNodeType::None;
|
||
|
|
std::vector<HGNode> children;
|
||
|
|
public:
|
||
|
|
HGNode(HGNodeType nodeType) : nodeType(nodeType) {}
|
||
|
|
HGNode() = default;
|
||
|
|
void addNode(HGNode in) {
|
||
|
|
children.push_back(in);
|
||
|
|
}
|
||
|
|
std::vector<GroundInstruction> generateCode() {
|
||
|
|
std::vector<GroundInstruction> code;
|
||
|
|
return code;
|
||
|
|
}
|
||
|
|
};
|
||
|
|
|
||
|
|
} // namespace Parser
|
||
|
|
|
||
|
|
class Lexer {
|
||
|
|
std::string input;
|
||
|
|
size_t size;
|
||
|
|
size_t current;
|
||
|
|
|
||
|
|
std::optional<char> peek(int ahead = 1) {
|
||
|
|
if (current + ahead < size) {
|
||
|
|
return input[current + ahead];
|
||
|
|
} else {
|
||
|
|
return {};
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
std::optional<char> consume() {
|
||
|
|
if (current < size) {
|
||
|
|
return input[current++];
|
||
|
|
} else {
|
||
|
|
return {};
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
public:
|
||
|
|
Lexer(std::string in) : input(in), size(in.size()) {};
|
||
|
|
std::vector<std::string> lex() {
|
||
|
|
current = 0;
|
||
|
|
std::vector<std::string> tokens;
|
||
|
|
std::string buf;
|
||
|
|
while (auto copt = consume()) {
|
||
|
|
char c = copt.value();
|
||
|
|
switch (c) {
|
||
|
|
// tokens which are not followed by anything
|
||
|
|
case '(':
|
||
|
|
case ')':
|
||
|
|
case '{':
|
||
|
|
case '}':
|
||
|
|
{
|
||
|
|
if (!buf.empty()) {
|
||
|
|
tokens.push_back(buf);
|
||
|
|
buf.clear();
|
||
|
|
}
|
||
|
|
tokens.push_back(std::string(1, c));
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
// tokens which may be followed by either themselves
|
||
|
|
// or an equals sign
|
||
|
|
case '+':
|
||
|
|
case '-':
|
||
|
|
{
|
||
|
|
std::string newToken(1, c);
|
||
|
|
auto tokenopt = peek();
|
||
|
|
if (tokenopt) {
|
||
|
|
char token = tokenopt.value();
|
||
|
|
if (token == c || token == '=') {
|
||
|
|
newToken += token;
|
||
|
|
consume();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (!buf.empty()) {
|
||
|
|
tokens.push_back(buf);
|
||
|
|
buf.clear();
|
||
|
|
}
|
||
|
|
tokens.push_back(newToken);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
// tokens which may be followed by an equals sign
|
||
|
|
case '*':
|
||
|
|
case '/':
|
||
|
|
case '=':
|
||
|
|
{
|
||
|
|
std::string newToken(1, c);
|
||
|
|
auto tokenopt = peek();
|
||
|
|
if (tokenopt) {
|
||
|
|
char token = tokenopt.value();
|
||
|
|
if (token == '=') {
|
||
|
|
newToken += token;
|
||
|
|
consume();
|
||
|
|
}
|
||
|
|
}
|
||
|
|
if (!buf.empty()) {
|
||
|
|
tokens.push_back(buf);
|
||
|
|
buf.clear();
|
||
|
|
}
|
||
|
|
tokens.push_back(newToken);
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
// tokens which do not need to be included
|
||
|
|
case ' ':
|
||
|
|
case '\n':
|
||
|
|
{
|
||
|
|
if (!buf.empty()) {
|
||
|
|
tokens.push_back(buf);
|
||
|
|
buf.clear();
|
||
|
|
}
|
||
|
|
break;
|
||
|
|
}
|
||
|
|
default:
|
||
|
|
{
|
||
|
|
buf += c;
|
||
|
|
}
|
||
|
|
}
|
||
|
|
}
|
||
|
|
|
||
|
|
if (!buf.empty()) {
|
||
|
|
tokens.push_back(buf);
|
||
|
|
}
|
||
|
|
return tokens;
|
||
|
|
}
|
||
|
|
|
||
|
|
};
|
||
|
|
|
||
|
|
|
||
|
|
} // namespace HighGround
|
||
|
|
|
||
|
|
|
||
|
|
int main(int argc, char** argv) {
|
||
|
|
if (argc < 2) {
|
||
|
|
std::cout << "Usage: " << argv[0] << " (file)\n";
|
||
|
|
exit(1);
|
||
|
|
}
|
||
|
|
std::ifstream file(argv[1]);
|
||
|
|
std::ostringstream ss;
|
||
|
|
ss << file.rdbuf();
|
||
|
|
auto lexed = HighGround::Lexer(ss.str()).lex();
|
||
|
|
for (const std::string& str : lexed) {
|
||
|
|
std::cout << str << "\n";
|
||
|
|
}
|
||
|
|
}
|