include Decompiler hpp namespace MobileBasic using namespace std const

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
#include "Decompiler.hpp"
namespace MobileBasic {
using namespace std;
const string Decompiler::decompile(Basic &basic, bool append_nl) {
unsigned short line_num;
unsigned char line_length, token_id;
string source_out = "";
BinaryReader code;
code.setData(basic.code, basic.meta.code_size);
try {
while (!code.isEOF()) {
line_num = code.readShort();
line_length = code.readByte();
source_out.append(to_string(line_num)).append(1, ' ');
size_t line_length_start = code.getOffset();
for (unsigned char i = line_length_start; i < line_length_start + line_length - 3; ++i) {
token_id = code.readByte();
switch (token_id) {
case Basic::TOK_ASSIGN:
source_out.append(1, '=');
break;
case Basic::TOK_MAKEREF:
break;
case Basic::TOK_EOS:
if (append_nl)
source_out.append("\r\n");
break;
case Basic::TOK_VARIABLE:
{
unsigned char var_id = code.readByte();
if (var_id >= basic.vars.size())
DECOMP_ERROR("Unknown variable with id=%d", E_UNKNOWN_VARIABLE, var_id);
source_out.append(basic.vars[var_id].name);
}
break;
case Basic::TOK_DATA:
MB_CONST_STRING_DATA(code, false, "DATA ", source_out);
break;
case Basic::TOK_REM:
MB_CONST_STRING_DATA(code, false, "REM ", source_out);
break;
case Basic::TOK_STRING:
MB_CONST_STRING_DATA(code, true, NULL, source_out);
break;
case Basic::TOK_BYTE:
source_out.append(to_string(code.readSByte()));
break;
case Basic::TOK_UBYTE:
source_out.append(to_string(code.readByte()));
break;
case Basic::TOK_UWORD:
source_out.append(to_string(code.readUShort()));
break;
case Basic::TOK_FLOAT:
if (basic.meta.version == Basic::MAGIC_MB_0191) {
unsigned char var_id = code.readByte();
if (var_id >= basic.meta.float_num)
DECOMP_ERROR("Unknown float with id=%d", E_UNKNOWN_VARIABLE, var_id);
source_out.append(to_string(basic.floats[var_id]));
} else
source_out.append(to_string(unpack_float(code.readUInt())));
break;
case Basic::TOK_INTEGER:
source_out.append(to_string(code.readUInt()));
break;
default:
unsigned int attr = TKN_GET_ATTR(Basic::basic_tokens[token_id].attributes);
if ((attr & Basic::ATTR_PRINT_BEFORE_THIS))
source_out.append(1, ' ');
source_out.append(Basic::basic_tokens[token_id].name);
if ((attr & Basic::ATTR_PRINT_SPACE_AFTER_GEN))
source_out.append(1, ' ');
break;
}
if (token_id == Basic::TOK_EOS)
break;
}
}
} catch (BinaryReaderException &ex) {
DECOMP_ERROR("Parse error[%d]: %s", E_PARSE, ex.getCode(), ex.getMessage());
}
return source_out;
}
}; // MobileBasic