(**************************************************************************

     $RCSfile: Rexx.mod $
  Description: Interface to ARexx

   Created by: fjc (Frank Copeland)
    $Revision: 3.2 $
      $Author: fjc $
        $Date: 1994/08/08 01:10:12 $

  Includes Release 40.15

  (C) Copyright 1987,1988,1989,1990 William S. Hawes
  (C) Copyright 1990-1993 Commodore-Amiga, Inc.
      All Rights Reserved

  Oberon-A interface Copyright © 1994, Frank Copeland.
  This file is part of the Oberon-A Interface.
  See Oberon-A.doc for conditions of use and distribution.

***************************************************************************)

MODULE Rexx;

(*
** $C- CaseChk       $I- IndexChk  $L+ LongAdr   $N- NilChk
** $P- PortableCode  $R- RangeChk  $S- StackChk  $T- TypeChk
** $V- OvflChk       $Z- ZeroVars
*)

IMPORT E := Exec, D := Dos, SYS := SYSTEM;


(*
**      $VER: storage.h 1.4 (8.11.91)
**
**      Header file to define ARexx data structures.
*)


(* The NexxStr structure is used to maintain the internal strings in REXX.
 * It includes the buffer area for the string and associated attributes.
 * This is actually a variable-length structure; it is allocated for a
 * specific length string, and the length is never modified thereafter
 * (since it's used for recycling).
 *)

TYPE

  NexxStrPtr * = CPOINTER TO NexxStr;
  NexxStr * = RECORD
    ivalue * : LONGINT;                (* integer value                 *)
    length * : E.UWORD;                (* length in bytes (excl null)   *)
    flags *  : E.BSET;                 (* attribute flags               *)
    hash *   : E.UBYTE;                (* hash code                     *)
    buff *   : ARRAY 8 OF CHAR;        (* buffer area for strings       *)
  END; (* NexxStr *)                   (* size: 16 bytes (minimum)      *)

CONST

  nxAddLen * = 9;                     (* offset plus null byte *)

(* String attribute flag bit definitions                                *)
  nsKeep     * = 0;                 (* permanent string?             *)
  nsString   * = 1;                 (* string form valid?            *)
  nsNotNum   * = 2;                 (* non-numeric?                  *)
  nsNumber   * = 3;                 (* a valid number?               *)
  nsBinary   * = 4;                 (* integer value saved?          *)
  nsFloat    * = 5;                 (* floating point format?        *)
  nsExt      * = 6;                 (* an external string?           *)
  nsSource   * = 7;                 (* part of the program source?   *)

(* Combinations of flags                                                *)
  nsIntNum   * = { nsNumber, nsBinary, nsString };
  nsDpNum    * = { nsNumber, nsFloat };
  nsAlpha    * = { nsNotNum, nsString };
  nsOwned    * = { nsSource, nsExt, nsKeep };
  nsKeepStr  * = { nsString, nsSource, nsNotNum };
  nsKeepNum  * = { nsString, nsSource, nsNumber, nsBinary };

(* The RexxArg structure is identical to the NexxStr structure, but
 * is allocated from system memory rather than from internal storage.
 * This structure is used for passing arguments to external programs.
 * It is usually passed as an "argstring", a pointer to the string buffer.
 *)

TYPE

  RexxArgPtr * = CPOINTER TO RexxArg;
  RexxArg * = RECORD
    size *   : LONGINT;                (* total allocated length        *)
    length * : E.UWORD;                (* length of string              *)
    flags *  : E.BSET;                 (* attribute flags               *)
    hash *   : E.UBYTE;                (* hash code                     *)
    buff *   : ARRAY 8 OF CHAR;        (* buffer area                   *)
  END; (* RexxArg *)                   (* size: 16 bytes (minimum)      *)

(* The RexxMsg structure is used for all communications with REXX
 * programs.  It is an EXEC message with a parameter block appended.
 *)

TYPE

  RexxMsgPtr * = CPOINTER TO RexxMsg;
  RexxMsg * = RECORD (E.Message)        (* EXEC message structure        *)
    taskBlock - : E.APTR;               (* global structure (private)    *)
    libBase -   : E.LibraryPtr;         (* library base (private)        *)
    action *    : LONGINT;              (* command (action) code         *)
    result1 *   : E.APTR;               (* primary result (return code)  *)
    result2 *   : E.APTR;               (* secondary result              *)
    args *      : ARRAY 16 OF E.STRPTR; (* argument block (ARG0-ARG15)   *)
    passPort *  : E.MsgPortPtr;         (* forwarding port               *)
    commAddr *  : E.STRPTR;             (* host address (port name)      *)
    fileExt *   : E.STRPTR;             (* file extension                *)
    stdin *     : D.FileHandlePtr;      (* input stream (filehandle)     *)
    stdout *    : D.FileHandlePtr;      (* output stream (filehandle)    *)
    avail *     : LONGINT;              (* future expansion              *)
  END; (* RexxMsg *)                   (* size: 128 bytes               *)

CONST

  maxRMArg  * = 15;                   (* maximum arguments             *)

(* Command (action) codes for message packets                           *)
  comm    * = 01000000H;           (* a command-level invocation    *)
  func    * = 02000000H;           (* a function call               *)
  close   * = 03000000H;           (* close the REXX server *)
  query   * = 04000000H;           (* query for information *)
  addFH   * = 07000000H;           (* add a function host           *)
  addLib  * = 08000000H;           (* add a function library        *)
  remLib  * = 09000000H;           (* remove a function library     *)
  addCon  * = 0A000000H;           (* add/update a ClipList string  *)
  remCon  * = 0B000000H;           (* remove a ClipList string      *)
  tcOpn   * = 0C000000H;           (* open the trace console        *)
  tcCls   * = 0D000000H;           (* close the trace console       *)

(* Command modifier flag bits                                           *)
  noIO    * = 00010000H;        (* suppress I/O inheritance?     *)
  result  * = 00020000H;        (* result string expected?       *)
  string  * = 00040000H;        (* program is a "string file"?   *)
  token   * = 00080000H;        (* tokenize the command line?    *)
  nonRet  * = 00100000H;        (* a "no-return" message?        *)

  rxCodeMask   * = 0FF000000H;
  rxArgMask    * = 0000000FH;

(* The RexxRsrc structure is used to manage global resources.  Each node
 * has a name string created as a RexxArg structure, and the total size
 * of the node is saved in the "rrSize" field.  The REXX systems library
 * provides functions to allocate and release resource nodes.  If special
 * deletion operations are required, an offset and base can be provided in
 * "rrFunc" and "rrBase", respectively.  This "autodelete" function will
 * be called with the base in register A6 and the node in A0.
 *)

TYPE

  RexxRsrcPtr * = CPOINTER TO RexxRsrc;
  RexxRsrc * = RECORD (E.Node)
    func * : INTEGER;                 (* "auto-delete" offset          *)
    base * : E.APTR;                  (* "auto-delete" base            *)
    size * : LONGINT;                 (* total size of node            *)
    arg1 * : E.APTR;                  (* available ...         *)
    arg2 * : E.APTR;                  (* available ...         *)
  END; (* RexxRsrc *)                 (* size: 32 bytes                *)

CONST

(* Resource node types                                                  *)
  rrtAny      * = 0;                 (* any node type ...             *)
  rrtLib      * = 1;                 (* a function library            *)
  rrtPort     * = 2;                 (* a public port         *)
  rrtFile     * = 3;                 (* a file IoBuff         *)
  rrtHost     * = 4;                 (* a function host               *)
  rrtClip     * = 5;                 (* a Clip List node              *)

(* The RexxTask structure holds the fields used by REXX to communicate with
 * external processes, including the client task.  It includes the global
 * data structure (and the base environment).  The structure is passed to
 * the newly-created task in its "wake-up" message.
 *)

CONST

  globalSz  * = 200;                  (* total size of GlobalData      *)

TYPE

  RexxTaskPtr * = CPOINTER TO RexxTask;
  RexxTask * = RECORD
    global *   : ARRAY globalSz OF SHORTINT;   (* global data structure *)
    msgPort *  : E.MsgPort;            (* global message port           *)
    flags *    : E.BSET;               (* task flag bits                *)
    sigBit *   : SHORTINT;             (* signal bit                    *)

    clientID * : E.APTR;               (* the client's task ID          *)
    msgPkt *   : E.APTR;               (* the packet being processed    *)
    taskID *   : E.APTR;               (* our task ID                   *)
    rexxPort * : E.APTR;               (* the REXX public port          *)

    errTrap *  : E.APTR;               (* Error trap address            *)
    stackPtr * : E.APTR;               (* stack pointer for traps       *)

    header1 *  : E.List;               (* Environment list              *)
    header2 *  : E.List;               (* Memory freelist               *)
    header3 *  : E.List;               (* Memory allocation list        *)
    header4 *  : E.List;               (* Files list                    *)
    header5 *  : E.List;               (* Message Ports List            *)
  END; (* RexxTask *)

CONST

(* Definitions for RexxTask flag bits                                   *)
  rtfTrace   * = 0;                 (* external trace flag           *)
  rtfHalt    * = 1;                 (* external halt flag            *)
  rtfSusp    * = 2;                 (* suspend task?         *)
  rtfTCUse   * = 3;                 (* trace console in use? *)
  rtfWait    * = 6;                 (* waiting for reply?            *)
  rtfClose   * = 7;                 (* task completed?               *)

(* Definitions for memory allocation constants                          *)
  memQuant  * = 16;                  (* quantum of memory space       *)
  memMask   * = 0FFFFFFF0H;           (* mask for rounding the size    *)

  memQuick  * = {0};           (* EXEC flags: public       *)
  memClear  * = {16};          (* EXEC flags: memClear        *)

(* The SrcNode is a temporary structure used to hold values destined for
 * a segment array.  It is also used to maintain the memory freelist.
 *)

TYPE

  SrcNodePtr * = CPOINTER TO SrcNode;
  SrcNode * = RECORD
    succ * : SrcNodePtr;            (* next node                     *)
    pred * : SrcNodePtr;            (* previous node                 *)
    ptr *  : E.APTR;                (* pointer value                 *)
    size * : LONGINT;               (* size of object                *)
  END; (* SrcNode *)                (* size: 16 bytes                *)


(*
**      $VER: rexxio.h 1.4 (8.11.91)
**
**      Header file for ARexx Input/Output related structures
*)


CONST

  rxBuffSz  * = 204;                  (* buffer length         *)

(*
 * The IoBuff is a resource node used to maintain the File List.  Nodes
 * are allocated and linked into the list whenever a file is opened.
 *)

TYPE

  IoBuffPtr * = CPOINTER TO IoBuff;
  IoBuff * = RECORD (RexxRsrc)           (* structure for files/strings   *)
    rpt *  : E.APTR;                     (* read/write pointer            *)
    rct *  : LONGINT;                    (* character count               *)
    dFH *  : D.FileHandlePtr;            (* DOS filehandle                *)
    lock * : D.FileLockPtr;              (* DOS lock                      *)
    bct *  : LONGINT;                    (* buffer length                 *)
    area * : ARRAY rxBuffSz OF SYS.BYTE; (* buffer area                   *)
  END; (* IoBuff *)                      (* size: 256 bytes               *)

CONST

(* Access mode definitions                                              *)
  ioExist   * = -1;                (* an external filehandle        *)
  ioStrF    * = 0;                 (* a "string file"               *)
  ioRead    * = 1;                 (* read-only access              *)
  ioWrite   * = 2;                 (* write mode                    *)
  ioAppend  * = 3;                 (* append mode (existing file)   *)

(*
 * Offset anchors for SeekF()
 *)
  ioBegin   * = -1;               (* relative to start             *)
  ioCurr    * = 0;        (* relative to current position  *)
  ioEnd     * = 1;        (* relative to end               *)

(* The Library List contains just plain resource nodes.         *)

(*
 * The RexxClipNode structure is used to maintain the Clip List.  The value
 * string is stored as an argstring in the rrArg1 field.
 *)

(*
 * A message port structure, maintained as a resource node.  The ReplyList
 * holds packets that have been received but haven't been replied.
 *)

TYPE

  RexxMsgPortPtr * = CPOINTER TO RexxMsgPort;
  RexxMsgPort * = RECORD (RexxRsrc)   (* linkage node                  *)
    port *      : E.MsgPort;          (* the message port              *)
    replyList * : E.List;             (* messages awaiting reply       *)
  END; (* RexxMsgPort *)

CONST

(*
 * DOS Device types
 *)

  dtDev    * = 0;                   (* a device                      *)
  dtDir    * = 1;                   (* an ASSIGNed directory *)
  dtVol    * = 2;                   (* a volume                      *)

(*
 * Private DOS packet types
 *)

  actionStack * = 2002;             (* stack a line                  *)
  actionQueue * = 2003;             (* queue a line                  *)


(*
**      $VER: errors.h 1.4 (8.11.91)
**
**      Definitions for ARexx error codes
*)

CONST

  errcMsg  * = 0;                 (*  error code offset           *)
  err10001 * = errcMsg+1;         (*  program not found           *)
  err10002 * = errcMsg+2;         (*  execution halted            *)
  err10003 * = errcMsg+3;         (*  no memory available         *)
  err10004 * = errcMsg+4;         (*  invalid character in program*)
  err10005 * = errcMsg+5;         (*  unmatched quote             *)
  err10006 * = errcMsg+6;         (*  unterminated comment        *)
  err10007 * = errcMsg+7;         (*  clause too long             *)
  err10008 * = errcMsg+8;         (*  unrecognized token          *)
  err10009 * = errcMsg+9;         (*  symbol or string too long   *)

  err10010 * = errcMsg+10;        (*  invalid message packet      *)
  err10011 * = errcMsg+11;        (*  command string error        *)
  err10012 * = errcMsg+12;        (*  error return from function  *)
  err10013 * = errcMsg+13;        (*  host environment not found  *)
  err10014 * = errcMsg+14;        (*  required library not found  *)
  err10015 * = errcMsg+15;        (*  function not found          *)
  err10016 * = errcMsg+16;        (*  no return value             *)
  err10017 * = errcMsg+17;        (*  wrong number of arguments   *)
  err10018 * = errcMsg+18;        (*  invalid argument to function*)
  err10019 * = errcMsg+19;        (*  invalid PROCEDURE           *)

  err10020 * = errcMsg+20;        (*  unexpected THEN/ELSE        *)
  err10021 * = errcMsg+21;        (*  unexpected WHEN/OTHERWISE   *)
  err10022 * = errcMsg+22;        (*  unexpected LEAVE or ITERATE *)
  err10023 * = errcMsg+23;        (*  invalid statement in SELECT *)
  err10024 * = errcMsg+24;        (*  missing THEN clauses        *)
  err10025 * = errcMsg+25;        (*  missing OTHERWISE           *)
  err10026 * = errcMsg+26;        (*  missing or unexpected END   *)
  err10027 * = errcMsg+27;        (*  symbol mismatch on END      *)
  err10028 * = errcMsg+28;        (*  invalid DO syntax           *)
  err10029 * = errcMsg+29;        (*  incomplete DO/IF/SELECT     *)

  err10030 * = errcMsg+30;        (*  label not found             *)
  err10031 * = errcMsg+31;        (*  symbol expected             *)
  err10032 * = errcMsg+32;        (*  string or symbol expected   *)
  err10033 * = errcMsg+33;        (*  invalid sub-keyword         *)
  err10034 * = errcMsg+34;        (*  required keyword missing    *)
  err10035 * = errcMsg+35;        (*  extraneous characters       *)
  err10036 * = errcMsg+36;        (*  sub-keyword conflict        *)
  err10037 * = errcMsg+37;        (*  invalid template            *)
  err10038 * = errcMsg+38;        (*  invalid TRACE request       *)
  err10039 * = errcMsg+39;        (*  uninitialized variable      *)

  err10040 * = errcMsg+40;        (*  invalid variable name       *)
  err10041 * = errcMsg+41;        (*  invalid expression          *)
  err10042 * = errcMsg+42;        (*  unbalanced parentheses      *)
  err10043 * = errcMsg+43;        (*  nesting level exceeded      *)
  err10044 * = errcMsg+44;        (*  invalid expression result   *)
  err10045 * = errcMsg+45;        (*  expression required         *)
  err10046 * = errcMsg+46;        (*  boolean value not 0 or 1    *)
  err10047 * = errcMsg+47;        (*  arithmetic conversion error *)
  err10048 * = errcMsg+48;        (*  invalid operand             *)

(*
 * Return Codes for general use
 *)
  rcOk     * = 0;                   (*  success                     *)
  rcWarn   * = 5;                   (*  warning only        *)
  rcError  * = 10;                  (*  something's wrong           *)
  rcFatal  * = 20;                  (*  complete or severe failure  *)


(*
**      $VER: rxslib.h 1.6 (8.11.91)
**
**      The header file for the REXX Systems Library
*)


CONST

  name  * = "rexxsyslib.library";
  dir   * = "REXX";
  tName * = "ARexx";

(* The REXX systems library structure.  This should be considered as    *)
(* semi-private and read-only, except for documented exceptions.        *)

TYPE

  RxsLibPtr * = CPOINTER TO RxsLib;
  RxsLib * = RECORD (E.Library)      (* EXEC library node             *)
    rlFlags *    : E.BSET;           (* global flags                  *)
    shadow *     : E.BSET;           (* shadow flags                  *)
    sysBase *    : E.LibraryPtr;     (* EXEC library base             *)
    dosBase *    : D.DosLibraryPtr;  (* DOS library base              *)
    ieeeDPBase * : E.LibraryPtr;     (* IEEE DP math library base     *)
    segList *    : SYS.BPTR;         (* library seglist               *)
    nil *        : D.FileHandlePtr;  (* global NIL: filehandle        *)
    chunk *      : LONGINT;          (* allocation quantum            *)
    maxNest *    : LONGINT;          (* maximum expression nesting    *)
    null *       : NexxStrPtr;       (* static string: NULL           *)
    false *      : NexxStrPtr;       (* static string: FALSE          *)
    true *       : NexxStrPtr;       (* static string: TRUE           *)
    rexx *       : NexxStrPtr;       (* static string: REXX           *)
    command *    : NexxStrPtr;       (* static string: COMMAND        *)
    stdin *      : NexxStrPtr;       (* static string: STDIN          *)
    stdout *     : NexxStrPtr;       (* static string: STDOUT         *)
    stderr *     : NexxStrPtr;       (* static string: STDERR         *)
    rlVersion *  : E.STRPTR;         (* version string                *)

    taskName *   : E.STRPTR;         (* name string for tasks *)
    taskPri *    : LONGINT;          (* starting priority             *)
    taskSeg *    : SYS.BPTR;         (* startup seglist               *)
    stackSize *  : LONGINT;          (* stack size                    *)
    rexxDir *    : E.STRPTR;         (* REXX directory                *)
    cTable *     : E.STRPTR;         (* character attribute table     *)
    notice *     : E.STRPTR;         (* copyright notice              *)

    rexxPort *   : E.MsgPort;        (* REXX public port              *)
    readLock *   : E.UWORD;          (* lock count                    *)
    traceFH *    : D.FileHandlePtr;  (* global trace console          *)
    taskList *   : E.List;           (* REXX task list                *)
    numTask *    : INTEGER;          (* task count                    *)
    libList *    : E.List;           (* Library List header           *)
    numLib *     : INTEGER;          (* library count                 *)
    clipList *   : E.List;           (* ClipList header               *)
    numClip *    : INTEGER;          (* clip node count               *)
    msgList *    : E.List;           (* pending messages              *)
    numMsg *     : INTEGER;          (* pending count                 *)
    pgmList *    : E.List;           (* cached programs               *)
    numPgm *     : INTEGER;          (* program count                 *)

    traceCnt *   : E.UWORD;          (* usage count for trace console *)
    avail *      : INTEGER;
  END; (* RxsLib *)

CONST

(* Global flag bit definitions for RexxMaster                           *)
  rlfTrace * = rtfTrace;        (* interactive tracing?          *)
  rlfHalt  * = rtfHalt;         (* halt execution?               *)
  rlfSusp  * = rtfSusp;         (* suspend execution?            *)
  rlfStop  * = 6;               (* deny further invocations      *)
  rlfClose * = 7;               (* close the master              *)

  rlfMask    * = { rlfTrace, rlfHalt, rlfSusp };

(* Initialization constants                                             *)
  chunk   * = 1024;        (* allocation quantum            *)
  nest    * = 32;          (* expression nesting limit      *)
  tPri    * = 0;           (* task priority         *)
  stack   * = 4096;        (* stack size                    *)

(* Character attribute flag bits used in REXX.                          *)
  ctSpace   * = 0;                  (* white space characters        *)
  ctDigit   * = 1;                  (* decimal digits 0-9            *)
  ctAlpha   * = 2;                  (* alphabetic characters *)
  ctRexxSym * = 3;                  (* REXX symbol characters        *)
  ctRexxOpr * = 4;                  (* REXX operator characters      *)
  ctRexxSpc * = 5;                  (* REXX special symbols          *)
  ctUpper   * = 6;                  (* UPPERCASE alphabetic          *)
  ctLower   * = 7;                  (* lowercase alphabetic          *)

END Rexx.
