/* vector.c - Functions for working with vectors.
 *  Copyright (C) 2022 by Jed Marti
 *   This program is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU General Public License as published by
 *  the Free Software Foundation, either version 3 of the License, or
 *   (at your option) any later version.
 *
 *  This program is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU General Public License for more details.
 *
 *  You should have received a copy of the GNU General Public License
 *  along with this program.  If not, see https://www.gnu.org/licenses/.
 */

#include <C8051F380.h>
#include <stdint.h>

#include "lfxmit.h"
#include "serial.h"
#include "storage.h"


extern __bit               errorThrown;
extern __bit               doit;
extern __xdata floatOrInt  IACC;
extern __xdata floatOrInt  IACCB;
extern uint16_t            DREG;
extern __xdata uint8_t     D[];
extern __xdata SymtabEntry S[];


void subscriptCheck(uint8_t s)
//     Verify a proper subscript of a vector.
//  DREG: points to vector, get its size (32 bits)
//  The stack should have an integer value on it.
{
  IACC.i = (int32_t) D[DREG + 3];

  DREG = popST();
  if (tag() != DESC_INT)
  {
    DREG = S[s].pname;
    putstring((char *) &D[DREG + 3]);
    putstring(" index not Int\n");
    errorThrown = 1;
    return;
  }
  
  getIACCB();

  // Range check and error.
  if (IACCB.i < 0 || IACCB.i >= IACC.i)
  {
    DREG = S[s].pname;
    putstring((char *) &D[DREG + 3]);
    putstring(" bounds error\n");
    errorThrown = 1;
    return;
  }
}



void getVector(uint8_t s)
//     Check for a vector and return the value from it. The two types are decoded elsewhere
//   and the check above called from there. An error is detected if not a vector.
{
  uint8_t tg;

  // Punt if not executing.
  if (!doit) return;

  // Address of vector data.
  DREG = S[s].addr;
  tg = tag();
  if (tg == DESC_BYTEVECTOR) getByteVector(s);
  else if (tg == DESC_FLOATVECTOR) getFloatVector(s);
  else
  {
    DREG = S[s].pname;
    putstring((char *) &D[DREG + 3]);
    putstring(" not a vector\n");
    errorThrown = 1;
    return;
  }
}


// EOF
