type
  Tvalue = Cardinal;
  Tid = Cardinal;
  TFunc0 = function: Tvalue;
  TFunc1 = function(argc: integer; argv: Pointer; This: Tvalue): Tvalue; cdecl;
  TAttr0 = function(This: Tvalue): Tvalue; cdecl;
  TAttr1 = function(This, v: Tvalue): Tvalue; cdecl;
  TGetValFunc = function(data: Tvalue): Tvalue; cdecl;
  TRetIntFunc = function: Integer;
  PInteger = ^Integer;
  Pvalue = ^Tvalue;
  Pid = ^Tid;
  TGetStrProc = procedure(S: string);
  TRetStrFunc = function: string;
  TRetChrFunc = function: Char;
  TAllocFunc = function(var AControl; owner: Tvalue): Tvalue;
  Tvalue_array = array of Tvalue;

  rb_atomic_t = Longint;

  POpenFile = ^TOpenFile;
  TOpenFile = record
    f, f2: Pointer;
    mode, pid, lineno: Integer;
    path: PChar;
    finalize: procedure; cdecl;
  end;
  
  PREPatternBuffer = ^TREPatternBuffer;
  TREPatternBuffer = record
  end;
  
  PRERegisters = ^TRERegisters;
  TRERegisters = record
    allocated: Integer;
    num_regs: Integer;
    beg_index: PInteger;
    end_index: PInteger;
  end;
  
  PRBasic = ^TRBasic;
  TRBasic = record
    flags: Longword;
    klass: Tvalue;
  end;
  
  TRObject = record
    basic: TRBasic;
    iv_tbl: PSTTable;
  end;
  
  TRClass = record
    basic: TRBasic;
    iv_tbl, m_tbl: PSTTable;
    super: Tvalue;
  end;
  
  TRFloat = record
    basic: TRBasic;
    value: Double;
  end;
  
  PRString = ^TRString;
  TRString = record
    basic: TRBasic;
    len: Longint;
    ptr: PChar;
    orig: Tvalue;
  end;
  
  PRArray = ^TRArray;
  TRArray = record
    basic: TRBasic;
    len, capa: Longint;
    ptr: Pvalue;
  end;
  
  TRRegexp = record
    basic: TRBasic;
    ptr: PREPatternBuffer;
    len: Longint;
    str: PChar;
  end;
  
  PRMatch = ^TRMatch;
  TRMatch = record
    basic: TRBasic;
    str: Tvalue;
    regs: PRERegisters;
  end;
  
  PRHash = ^TRHash;
  TRHash = record
    basic: TRBasic;
    tbl: PSTTable;
    iter_lev: Integer;
    ifnone: Tvalue;
  end;
  
  PRFile = ^TRFile;
  TRFile = record
    basic: TRBasic;
    fptr: POpenFile;
  end;
  
  PRData = ^TRData;
  TRData = record
    basic: TRBasic;
    dmark, dfree: procedure;
    data: Pointer;
  end;
  
  TRStruct = record
    basic: TRBasic;
    len: Longint;
    ptr: Pvalue;
  end;
  
  TRBignum = record
    basic: TRBasic;
    sign: Char;
    len: Longint;
    digits: Pointer;
  end;
  
  Ptrace_var = ^Ttrace_var;
  Ttrace_var = record
    removed: Integer;
    func: Pointer;
    data: Tvalue;
    next: Ptrace_var;
  end;
  
  Pglobal_variable = ^Tglobal_variable;
  Tglobal_variable = record
    counter: Integer;
    data: Pointer;
    getter: Pvalue;
    setter: Pointer;
    marker: Pointer;
    block_trace: Integer;
    trace: Ptrace_var;
  end;
  
  Pglobal_entry = ^Tglobal_entry;
  Tglobal_entry = record
    variable: Pglobal_variable; // var is reserved
    id: Tid;
  end;
  
  PRNode = ^TRNode;
  TRNode = record
    flags: Longword;
    nd_file: PChar;
    u1: record
      case Integer of
        0: (node: PRNode);
        1: (id: Tid);
        2: (value: Tvalue);
        3: (cfunc: Pointer);
        4: (tbl: Pid);
    end;
    u2: record
      case Integer of
        0: (node: PRNode);
        1: (id: Tid);
        2: (argc: Longint);
        3: (value: Tvalue);
    end;
    u3: record
      case Integer of
        0: (node: PRNode);
        1: (id: Tid);
        2: (state: Longint);
        3: (entry: Pglobal_entry);
        4: (cnt: Longint);
        5: (value: Tvalue);
    end;
  end;
 
  PRFRAME = ^TRFRAME;
{$IFDEF RUBY19}
  TRFRAME = record
    self: Tvalue;
    argc: Integer;
    callee: Tid;         //++
    this_func: Tid;      //++
    this_class: Tvalue;  //++
    prev, tmp: PRFRAME;
    node: PRNode;
    block: BLOCK;        //++????
    flags: Integer;
    uniq: Integer;
  end;
{$ELSE}
{$IFDEF RUBY185}
  TRFRAME = record
    self: Tvalue;
    argc: Integer;
    last_func: Tid;      //--
    orig_func: Tid;      //--
    last_class: Tvalue;  //--
    prev, tmp: PRFRAME;
    node: PRNode;
    iter: Integer;       //--
    flags: Integer;
    uniq: Integer;
  end;
{$ELSE}
{$IFDEF RUBY18}
  TRFRAME = record
    self: Tvalue;
    argc: Integer;       //--
    argv: Pvalue;
    last_func: Tid;
    orig_func: Tid;      //++
    last_class: Tvalue;  //++
    prev, tmp: PRFRAME;
    node: PRNode;        //++
    iter: Integer;
    flags: Integer;
    uniq: Integer;       //++
  end;
{$ELSE}  // RUBY16
  TRFRAME = record
    self: Tvalue;
    argc: Integer;
    argv: Pvalue;
    last_func: Tid;
    cbase: Tvalue;      //--
    prev, tmp: PRFRAME;
    filename: PChar;    //--
    line: Integer;      //--
    iter: Integer;
    flags: Integer;
  end;
{$ENDIF}
{$ENDIF}
{$ENDIF}

  PRSCOPE = ^TRSCOPE;
  TRSCOPE = record
    super: TRBasic;
    local_tbl: Pid;
    local_vars: Pvalue;
    flags: Integer;
  end;

  PRVarmap = ^TRVarmap;
  TRVarmap = record
    super: TRBasic;
    id: Tid;
    val: Tvalue;
    next: PRVarmap;
  end;

const
  RubyDLL =
{$IFDEF LINUX}
  'libruby.so'
{$ENDIF}
{$IFDEF MSWINDOWS}
  {$IFDEF RUBY19}
    'msvcrt-ruby19.dll'
  {$ELSE}
  {$IFDEF RUBY18}
    'msvcrt-ruby18.dll'
  {$ELSE}
    'mswin32-ruby16.dll'
  {$ENDIF}
  {$ENDIF}
{$ENDIF}
  ;

const
  Qfalse = 0;
  Qtrue = 2;
  Qnil = 4;
  Qundef = 6;

  T_NONE   = $00;

  T_NIL    = $01;
  T_OBJECT = $02;
  T_CLASS  = $03;
  T_ICLASS = $04;
  T_MODULE = $05;
  T_FLOAT  = $06;
  T_STRING = $07;
  T_REGEXP = $08;
  T_ARRAY  = $09;
  T_FIXNUM = $0a;
  T_HASH   = $0b;
  T_STRUCT = $0c;
  T_BIGNUM = $0d;
  T_FILE   = $0e;

{$IFDEF RUBY19}
  T_TRUE   = $10;
  T_FALSE  = $11;
  T_DATA   = $12;
  T_MATCH  = $13;
  T_SYMBOL = $14;

  T_UNDEF  = $1c;
  T_VARMAP = $1d;
  T_SCOPE  = $1e;
  T_NODE   = $1f;

  T_MASK   = $1f;
{$ELSE}
  T_TRUE   = $20;
  T_FALSE  = $21;
  T_DATA   = $22;
  T_MATCH  = $23;
  T_SYMBOL = $24;

  T_UNDEF  = $3c;
  T_VARMAP = $3d;
  T_SCOPE  = $3e;
  T_NODE   = $3f;

  T_MASK   = $3f;
{$ENDIF}

  FIXNUM_FLAG = $01;
  IMMEDIATE_MASK = $03;
  SYMBOL_FLAG = $0e;

  FRAME_ALLOCA = 0;
  FRAME_MALLOC = 1;

  SCOPE_ALLOCA = 0;
  SCOPE_MALLOC = 1;
  SCOPE_NOSTACK = 2;
  SCOPE_DONT_RECYCLE = 4;

var
//  ruby_frame: PRFRAME;
//  ruby_scope: PRSCOPE;
  ruby_in_eval: Integer;
  ruby_class: Tvalue;
  ruby_dyna_vars: PRVarmap;

