torpedo_coder/ideas/bytecode.cpp
2025-01-28 02:56:39 +01:00

131 lines
2.6 KiB
C++

#include <string>
#include <map>
#include <stdio.h>
#include <cctype>
#include <vector>
#include <cstdint>
std::string code = "HULL 1 5 10\nPAR A 1 3 \r\nENGINE north\nMUL a A 2\nADD a a 1\nHW cannon A a\nCOMM write 1 5\n";
#define BYTEINFO(bytekind, command, bytecode, func, p1k, p2k, p3k) {command, bytecode},
static std::map<std::string, uint8_t> keywords = {
#include "opcode_list.h"
#include "enginecode_list.h"
#include "hardwarecode_list.h"
#include "commcode_list.h"
};
void write_file_bytes(const char* filename, std::vector<uint8_t>& bytes)
{
FILE * f = fopen(filename, "w");
fwrite(&bytes[0], 1, bytes.size(), f);
fclose(f);
}
bool add_if_number(std::vector<uint8_t> &result_code, const std::string &token)
{
unsigned int i = 0;
int num = 0;
int sign = 1;
if (token.length() > 4) return false;
if (token[0] == '-')
{
sign = -1;
++i;
}
else if (token[0] == '+')
{
++i;
}
if (i >= token.length()) return false;
while(i < token.length())
{
char c = token[i];
if (c >= '0' && c<='9')
{
num = num * 10 + c - '0';
}
else
{
return false;
}
++i;
}
if (num > 100) return false;
num = sign * num + 0x99; //0 -> 0x99, 1 -> 0x9A, 2 -> 0x9B, ... (variables -> [0..52])
result_code.push_back((uint8_t)num);
return true;
}
bool add_if_variable(std::vector<uint8_t> &result_code, const std::string &token)
{
if (token.length() != 1) return false;
uint8_t c = token[0];
if (c >= 'a' && c <= 'z')
{
result_code.push_back(c - 'a');
return true;
}
else if (c >= 'A' && c <= 'Z')
{
result_code.push_back(c - 'A' + 'z' - 'a' + 1);
return true;
}
return false;
}
bool add_if_keyword(std::vector<uint8_t> &result_code, const std::string &token)
{
auto token_it = keywords.find(token);
if (token_it == keywords.end())
{
return false;
}
result_code.push_back(token_it->second);
return true;
}
int main()
{
std::vector<uint8_t> result_code;
unsigned int start = 0;
int remaining = 0;
for (unsigned int i = 0; i<code.length(); ++i)
{
if (isspace(code[i]))
{
if (start < i)
{
remaining = (remaining + 3) % 4;
std::string token = code.substr(start, i - start);
printf("%s %d\n", token.c_str(), remaining);
if (!add_if_variable(result_code, token)
&& !add_if_number(result_code, token)
&& !add_if_keyword(result_code, token)
)
{
printf("Unknown token: %s\n", token.c_str());
result_code.push_back('?');
}
}
if (code[i] == '\n')
{
for (int j = 0; j< remaining; ++j)
{
printf("NULL\n");
result_code.push_back(0);
}
remaining = 0;
}
start = i + 1;
}
}
write_file_bytes("bytecode.sbc", result_code);
}