Initial commit

This commit is contained in:
2025-12-13 18:07:26 +11:00
commit f1b156ce4d
3 changed files with 164 additions and 0 deletions

162
src/main.cpp Normal file
View File

@@ -0,0 +1,162 @@
#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";
}
}