Files
MicroST-Compiler/STCompiler.Common/Bytecode.cs
2025-10-13 13:30:00 +02:00

76 lines
5.5 KiB
C#

namespace STCompiler.Common;
using System.Collections.Generic;
public static class Bytecode {
public const string Magic = "STBC";
public const ushort Version = 2;
public const ushort DefaultCycleTime = 100; // in milliseconds
public static class OpCodes {
public const byte NOP = 0x00;
public const byte PUSH_CONST = 0x01; // integer/long
public const byte PUSH_REAL_CONST = 0x02; // float/double
public const byte LOAD_VAR = 0x03;
public const byte STORE_VAR = 0x04;
// Signed integer arithmetic (SINT, INT, DINT, LINT)
public const byte ADD_SINT = 0x10; public const byte SUB_SINT = 0x11; public const byte MUL_SINT = 0x12; public const byte DIV_SINT = 0x13;
public const byte ADD_INT = 0x14; public const byte SUB_INT = 0x15; public const byte MUL_INT = 0x16; public const byte DIV_INT = 0x17;
public const byte ADD_DINT = 0x18; public const byte SUB_DINT = 0x19; public const byte MUL_DINT = 0x1A; public const byte DIV_DINT = 0x1B;
public const byte ADD_LINT = 0x1C; public const byte SUB_LINT = 0x1D; public const byte MUL_LINT = 0x1E; public const byte DIV_LINT = 0x1F;
// Unsigned integer arithmetic (USINT, UINT, UDINT, ULINT) - moved to avoid conflicts
public const byte ADD_USINT = 0x22; public const byte SUB_USINT = 0x23; public const byte MUL_USINT = 0x24; public const byte DIV_USINT = 0x25;
public const byte ADD_UINT = 0x26; public const byte SUB_UINT = 0x27; public const byte MUL_UINT = 0x28; public const byte DIV_UINT = 0x29;
public const byte ADD_UDINT = 0x2A; public const byte SUB_UDINT = 0x2B; public const byte MUL_UDINT = 0x2C; public const byte DIV_UDINT = 0x2D;
public const byte ADD_ULINT = 0x2E; public const byte SUB_ULINT = 0x2F; public const byte MUL_ULINT = 0x30; public const byte DIV_ULINT = 0x31;
// Floating point arithmetic
public const byte ADD_REAL = 0x40; public const byte SUB_REAL = 0x41; public const byte MUL_REAL = 0x42; public const byte DIV_REAL = 0x43;
public const byte ADD_LREAL = 0x44; public const byte SUB_LREAL = 0x45; public const byte MUL_LREAL = 0x46; public const byte DIV_LREAL = 0x47;
// Comparisons signed
public const byte LT_S = 0x50; public const byte GT_S = 0x51; public const byte LE_S = 0x52; public const byte GE_S = 0x53; public const byte EQ_S = 0x54; public const byte NEQ_S = 0x55;
// Comparisons unsigned
public const byte LT_U = 0x56; public const byte GT_U = 0x57; public const byte LE_U = 0x58; public const byte GE_U = 0x59; public const byte EQ_U = 0x5A; public const byte NEQ_U = 0x5B;
// Comparisons floating
public const byte LT_F = 0x5C; public const byte GT_F = 0x5D; public const byte LE_F = 0x5E; public const byte GE_F = 0x5F; public const byte EQ_F = 0x60; public const byte NEQ_F = 0x61;
// Control flow
public const byte JZ = 0x70;
public const byte JMP = 0x71;
// Array operations
public const byte ARRAY_BOUNDS_CHECK = 0xE0;
public const byte HALT = 0xF0;
}
static readonly Dictionary<byte, string> names = new() {
{ OpCodes.NOP, "NOP" },
{ OpCodes.PUSH_CONST, "PUSH_CONST" },
{ OpCodes.PUSH_REAL_CONST, "PUSH_REAL_CONST" },
{ OpCodes.LOAD_VAR, "LOAD_VAR" },
{ OpCodes.STORE_VAR, "STORE_VAR" },
{ OpCodes.ADD_SINT, "ADD_SINT" }, { OpCodes.SUB_SINT, "SUB_SINT" }, { OpCodes.MUL_SINT, "MUL_SINT" }, { OpCodes.DIV_SINT, "DIV_SINT" },
{ OpCodes.ADD_INT, "ADD_INT" }, { OpCodes.SUB_INT, "SUB_INT" }, { OpCodes.MUL_INT, "MUL_INT" }, { OpCodes.DIV_INT, "DIV_INT" },
{ OpCodes.ADD_DINT, "ADD_DINT" }, { OpCodes.SUB_DINT, "SUB_DINT" }, { OpCodes.MUL_DINT, "MUL_DINT" }, { OpCodes.DIV_DINT, "DIV_DINT" },
{ OpCodes.ADD_LINT, "ADD_LINT" }, { OpCodes.SUB_LINT, "SUB_LINT" }, { OpCodes.MUL_LINT, "MUL_LINT" }, { OpCodes.DIV_LINT, "DIV_LINT" },
{ OpCodes.ADD_USINT, "ADD_USINT" }, { OpCodes.SUB_USINT, "SUB_USINT" }, { OpCodes.MUL_USINT, "MUL_USINT" }, { OpCodes.DIV_USINT, "DIV_USINT" },
{ OpCodes.ADD_UINT, "ADD_UINT" }, { OpCodes.SUB_UINT, "SUB_UINT" }, { OpCodes.MUL_UINT, "MUL_UINT" }, { OpCodes.DIV_UINT, "DIV_UINT" },
{ OpCodes.ADD_UDINT, "ADD_UDINT" }, { OpCodes.SUB_UDINT, "SUB_UDINT" }, { OpCodes.MUL_UDINT, "MUL_UDINT" }, { OpCodes.DIV_UDINT, "DIV_UDINT" },
{ OpCodes.ADD_ULINT, "ADD_ULINT" }, { OpCodes.SUB_ULINT, "SUB_ULINT" }, { OpCodes.MUL_ULINT, "MUL_ULINT" }, { OpCodes.DIV_ULINT, "DIV_ULINT" },
{ OpCodes.ADD_REAL, "ADD_REAL" }, { OpCodes.SUB_REAL, "SUB_REAL" }, { OpCodes.MUL_REAL, "MUL_REAL" }, { OpCodes.DIV_REAL, "DIV_REAL" },
{ OpCodes.ADD_LREAL, "ADD_LREAL" }, { OpCodes.SUB_LREAL, "SUB_LREAL" }, { OpCodes.MUL_LREAL, "MUL_LREAL" }, { OpCodes.DIV_LREAL, "DIV_LREAL" },
{ OpCodes.LT_S, "LT_S" }, { OpCodes.GT_S, "GT_S" }, { OpCodes.LE_S, "LE_S" }, { OpCodes.GE_S, "GE_S" }, { OpCodes.EQ_S, "EQ_S" }, { OpCodes.NEQ_S, "NEQ_S" },
{ OpCodes.LT_U, "LT_U" }, { OpCodes.GT_U, "GT_U" }, { OpCodes.LE_U, "LE_U" }, { OpCodes.GE_U, "GE_U" }, { OpCodes.EQ_U, "EQ_U" }, { OpCodes.NEQ_U, "NEQ_U" },
{ OpCodes.LT_F, "LT_F" }, { OpCodes.GT_F, "GT_F" }, { OpCodes.LE_F, "LE_F" }, { OpCodes.GE_F, "GE_F" }, { OpCodes.EQ_F, "EQ_F" }, { OpCodes.NEQ_F, "NEQ_F" },
{ OpCodes.JZ, "JZ" }, { OpCodes.JMP, "JMP" },
{ OpCodes.ARRAY_BOUNDS_CHECK, "ARRAY_BOUNDS_CHECK" },
{ OpCodes.HALT, "HALT" }
};
public static string OpName(byte op) => names.TryGetValue(op, out var s) ? s : ($"0x{op:X2}");
}