131 lines
2.6 KiB
C++
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);
|
|
} |