ton-assembly
Version:
TON assembler and disassembler
219 lines • 6.57 kB
JavaScript
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.processStack = exports.parseStack = exports.parse = void 0;
const $ = __importStar(require("./grammar.gen.pegjs"));
const parse = (log) => {
const lines = log.split("\n");
const vmLines = lines.map(line => parseLine(line.trim()));
return vmLines.map(it => processVmLine(it));
};
exports.parse = parse;
const parseLine = (line) => {
try {
return $.parse(line, { startRule: "vmLine" });
}
catch {
return {
$: "VmUnknown",
text: line,
};
}
};
const processVmLine = (line) => {
switch (line.$) {
case "VmLoc":
return {
$: "VmLoc",
hash: line.hash.trim(),
offset: parseNumber(line.offset),
};
case "VmStack": {
const stack = (0, exports.parseStack)(line.stack);
if (!stack) {
throw new Error(`Cannot parse stack: ${line.stack}`);
}
return {
$: "VmStack",
stack: (0, exports.processStack)(stack),
};
}
case "VmExecute":
return {
$: "VmExecute",
instr: line.instr.trim(),
};
case "VmLimitChanged":
return {
$: "VmLimitChanged",
limit: parseNumber(line.limit),
};
case "VmGasRemaining":
return {
$: "VmGasRemaining",
gas: parseNumber(line.gas),
};
case "VmException":
return {
$: "VmException",
errno: parseNumber(line.errno),
message: line.message.trim(),
};
case "VmExceptionHandler":
return {
$: "VmExceptionHandler",
errno: parseNumber(line.errno),
};
case "VmFinalC5":
return {
$: "VmFinalC5",
hex: line.value.value.trim(),
};
case "VmUnknown":
return {
$: "VmUnknown",
text: line.text.trim(),
};
default:
return {
$: "VmUnknown",
text: "",
};
}
};
const parseStack = (line) => {
const res = tryParseStack(line);
if (res)
return res;
const res2 = tryParseStack(line + "]");
if (res2)
return res2;
const res3 = tryParseStack(line + "} ]");
if (res3)
return res3;
// try to recover many missing `]`
for (let i = 0; i < 100; i++) {
const resN = tryParseStack(line + "} ]" + "]".repeat(i));
if (resN) {
return resN;
}
}
return undefined;
};
exports.parseStack = parseStack;
const tryParseStack = (line) => {
try {
return $.parse(line, { startRule: "VmParsedStack" });
}
catch {
return undefined;
}
};
const processStack = (stack) => {
return stack.values.map(it => processStackElement(it));
};
exports.processStack = processStack;
const parseNumber = (it) => {
const val = Number.parseInt(it.value);
if (it.op === "-") {
return -val;
}
return val;
};
const parseBigNum = (it) => {
const val = BigInt(it.value);
if (it.op === "-") {
return -val;
}
return val;
};
const processStackElement = (it) => {
switch (it.value.$) {
case "Null":
return { $: "Null" };
case "NaN":
return { $: "NaN" };
case "Integer":
return { $: "Integer", value: parseBigNum(it.value.value) };
case "Tuple":
case "TupleParen":
return {
$: "Tuple",
elements: it.value.elements.map(it => processStackElement(it)),
};
case "Cell":
return {
$: "Cell",
boc: it.value.value,
};
case "Continuation":
return {
$: "Continuation",
name: it.value.value,
};
case "Builder":
return {
$: "Builder",
hex: it.value.value,
};
case "CellSlice":
if (it.value.body.$ === "CellSliceBody") {
return {
$: "Slice",
hex: it.value.body.value,
startBit: parseNumber(it.value.body.bits.start),
endBit: parseNumber(it.value.body.bits.end),
startRef: parseNumber(it.value.body.refs.start),
endRef: parseNumber(it.value.body.refs.end),
};
}
return {
$: "Slice",
hex: it.value.body.value,
startBit: 0,
endBit: 0,
startRef: 0,
endRef: 0,
};
case "Unknown":
return {
$: "Unknown",
value: "",
};
default:
return { $: "Unknown", value: "" };
}
};
//# sourceMappingURL=parse.js.map