//
// opcode.h
// Bytecode opcodes
// F.J. Alberti
//

#ifndef _OPCODE_H_
#define _OPCODE_H_

#include "base.h"


// Basic
const byte kNop         = 0x00;
const byte kDrop        = 0x01;
const byte kDup         = 0x02;
const byte kPushnil     = 0x03;
const byte kGoto        = 0x04;
const byte kIftrue      = 0x05; // reserved for future use
const byte kIffalse     = 0x06;
const byte kExeccall    = 0x07; // to be deprecated
const byte kCall        = 0x08;
const byte kTailcall    = 0x09;
const byte kCallnative  = 0x0a; // reserved for future use
const byte kReturn      = 0x0b;
const byte kNewfun      = 0x0c;
const byte kPushstr     = 0x0d;

// Operand stack access
const byte kGetlocal    = 0x0e;
const byte kGetlocal0   = 0x0f;
const byte kGetlocal1   = 0x10; // kGetlocal0+1;
const byte kGetlocal2   = 0x11; // kGetlocal0+2;
const byte kGetlocal3   = 0x12; // kGetlocal0+3;
const byte kGetlocal4   = 0x13; // kGetlocal0+4;
const byte kGetlocal5   = 0x14; // kGetlocal0+5;
const byte kGetlocal6   = 0x15; // kGetlocal0+6;
const byte kGetlocal7   = 0x16; // kGetlocal0+7;
const byte kSetlocal    = 0x17;
const byte kSetlocal0   = 0x18;
const byte kSetlocal1   = 0x19; // kSetlocal0+1;
const byte kSetlocal2   = 0x1a; // kSetlocal0+2;
const byte kSetlocal3   = 0x1b; // kSetlocal0+3;
const byte kSetlocal4   = 0x1c; // kSetlocal0+4;
const byte kSetlocal5   = 0x1d; // kSetlocal0+5;
const byte kSetlocal6   = 0x1e; // kSetlocal0+6;
const byte kSetlocal7   = 0x1f; // kSetlocal0+7;

// Package variable access
const byte kGetglobal   = 0x20;
const byte kGetglobal0  = 0x21;
const byte kGetglobal1  = 0x22; // kGetglobal0+1;
const byte kGetglobal2  = 0x23; // kGetglobal0+2;
const byte kGetglobal3  = 0x24; // kGetglobal0+3;
const byte kGetglobal4  = 0x25; // kGetglobal0+4;
const byte kGetglobal5  = 0x26; // kGetglobal0+5;
const byte kGetglobal6  = 0x27; // kGetglobal0+6;
const byte kGetglobal7  = 0x28; // kGetglobal0+7;
const byte kSetglobal   = 0x29;
const byte kSetglobal0  = 0x2a;
const byte kSetglobal1  = 0x2b; // kSetglobal0+1;
const byte kSetglobal2  = 0x2c; // kSetglobal0+2;
const byte kSetglobal3  = 0x2d; // kSetglobal0+3;
const byte kSetglobal4  = 0x2e; // kSetglobal0+4;
const byte kSetglobal5  = 0x2f; // kSetglobal0+5;
const byte kSetglobal6  = 0x30; // kSetglobal0+6;
const byte kSetglobal7  = 0x31; // kSetglobal0+7;

// Array creation and access
const byte kNewarray    = 0x32;
const byte kArraysize   = 0x33;
const byte kArrayget    = 0x34;
const byte kArrayset    = 0x35;
const byte kArraycheck  = 0x36;

// Tuple creation and access
const byte kNewtuple    = 0x37;
const byte kNewtuple1   = 0x38;
const byte kNewtuple2   = 0x39; // kNewTuple1+1
const byte kGetfield    = 0x3a;
const byte kGetfield0   = 0x3b;
const byte kGetfield1   = 0x3c; // kGetfield0+1;
const byte kGetfield2   = 0x3d; // kGetfield0+2;
const byte kGetfield3   = 0x3e; // kGetfield0+3;
const byte kGetfield4   = 0x3f; // kGetfield0+4;
const byte kGetfield5   = 0x40; // kGetfield0+5;
const byte kGetfield6   = 0x41; // kGetfield0+6;
const byte kGetfield7   = 0x42; // kGetfield0+7;
const byte kSetfield    = 0x43;
const byte kSetfield0   = 0x44;
const byte kSetfield1   = 0x45; // kSetfield0+1;
const byte kSetfield2   = 0x46; // kSetfield0+2;
const byte kSetfield3   = 0x47; // kSetfield0+3;
const byte kSetfield4   = 0x48; // kSetfield0+4;
const byte kSetfield5   = 0x49; // kSetfield0+5;
const byte kSetfield6   = 0x4a; // kSetfield0+6;
const byte kSetfield7   = 0x4b; // kSetfield0+7;

// Integer
const byte kPushint     = 0x4c;
const byte kPushint0    = 0x4d;
const byte kPushint1    = 0x4e; // kPushint0+1
const byte kPushint2    = 0x4f; // kPushint0+2
const byte kPushbyte    = 0x50;
const byte kIntadd      = 0x51;
const byte kIntadd1     = 0x52; // reserved for future use
const byte kIntsub      = 0x53;
const byte kIntsub1     = 0x54; // reserved for future use
const byte kIntmul      = 0x55;
const byte kIntdiv      = 0x56;
const byte kIntmod      = 0x57;
const byte kIntneg      = 0x58;
const byte kIntand      = 0x59;
const byte kIntor       = 0x5a;
const byte kIntxor      = 0x5b;
const byte kIntnot      = 0x5c;
const byte kIntshl      = 0x5d;
const byte kIntshr      = 0x5e;
const byte kInteq       = 0x5f;
const byte kIntne       = 0x60;
const byte kIntlt       = 0x61;
const byte kIntgt       = 0x62;
const byte kIntle       = 0x63;
const byte kIntge       = 0x64;
const byte kBooland     = 0x65;
const byte kBoolor      = 0x66;
const byte kBoolnot     = 0x67;

// Floating point
const byte kPushfloat   = 0x68;
const byte kPushfloat0  = 0x69;
const byte kPushfloat1  = 0x6a; // kPushfloat0+1
const byte kInt2float   = 0x6b;
const byte kFloat2int   = 0x6c;
const byte kFloatadd    = 0x6d;
const byte kFloatsub    = 0x6e;
const byte kFloatmul    = 0x6f;
const byte kFloatdiv    = 0x70;
const byte kFloatneg    = 0x71;
const byte kFloateq     = 0x72;
const byte kFloatne     = 0x73;
const byte kFloatlt     = 0x74;
const byte kFloatgt     = 0x75;
const byte kFloatle     = 0x76;
const byte kFloatge     = 0x77;

// Communication
const byte kNewcomm     = 0x78;
const byte kNewcommvar  = 0x79;

// Debugging
const byte kBreak       = 0x7a;
const byte kAssert      = 0x7b;
const byte kAddloc      = 0x7c; // to be deprecated
const byte kRemloc      = 0x7d; // to be deprecated
const byte kDebug       = 0x7e; // to be deprecated

const uint kMaxOpcode   = 0x7e; // kDebug


#endif // opcode.h