/* print.c - print statement. Sor of like Basic's.
 *  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 __xdata floatOrInt IACC;
extern __xdata floatOrInt FACC;
extern __bit              errorThrown;
extern uint16_t           DREG;
extern __xdata uint8_t    D[];

extern __xdata uint16_t   PC;
extern __bit              doit;



void print(void)
{
  uint8_t ch;
  
 loop:
  incPC();
  parseExpression();
  if (errorThrown)
  {
    if (doit) putstring("*****\n");
    return;
  }
  // putstring("  at PC = "); puthex16(PC); terpri();

  if (doit)
  {
    DREG = popST();
    //    putstring("  PRINT tag "); putbyte(tag());  putstring(" at "); puthex16(DREG); terpri();
    switch (tag()) {
    case DESC_INT:
      getIACC();
      putint32(IACC.i);
      break;

    case DESC_FLOAT:
      getFACC();
      putfloat(FACC.f);
      break;

    case DESC_STRING:
      putstring((char *) &D[DREG + 3]);
      break;

    case DESC_BYTEVECTOR:
      putstring("<BYTEVECTOR ");
      putbyte(D[DREG + 3]);
      putch('>');
      break;

    case DESC_FLOATVECTOR:
      putstring("<FLOATVECTOR ");
      putbyte(D[DREG + 3]);
      putch('>');
      break;
    
    default:
      puthexbyte(tag());
      putstring(" bad type");
    }
  }

  ch = getPByte();
  // putstring("ch = 0x"); puthexbyte(ch); terpri();
  if (ch == COMMA)
  {
    if (doit) putch(' ');
    goto loop;
  }

  // No spaces if |.
  else if (ch == COLON) goto loop;

  // Semicolon means we're done.
  else if (ch == SEMICOLON)
  {
    if (doit) terpri();
    return;
  }

  // 
  terpri();
  puthex16(PC);
  putstring(" 0x");
  putbyte(ch);
  putstring(" bad format\n");
  errorThrown = 1;
  return;
}


// EOF
