/* chain.c - chain programs together.
 *  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 "fs.h"
#include "serial.h"
#include "storage.h"

extern uint16_t         DREG;
extern __bit            errorThrown;
extern __bit            doit;
extern __xdata uint8_t  infh;
extern __xdata uint8_t  D[];
extern __xdata uint16_t PC;


void runChain(void)
//     Run the chain command (or just parse it). Syntax
//           CHAIN <string>;
//   Clear the dynamic space and the symbol table and reset all other indices. Then load and start
// the new program. All Files are closed.
{
  uint8_t fh;

  // Expression should be a string. We need to parse even if we're not running.
  incPC();
  parseExpression();
  if (errorThrown || !doit) return;

  // Verify string or identifier.
  DREG = popST();
  if (tag() != DESC_STRING)
  {
    putstring("CHAIN no string\n");
    errorThrown = 1;
    return;
  }

  // This effectively chops off any open files. Not a safe close on write files.
  clearHandles();
  
  // Open the file for "compilation"
  if ((fh = openFile(&D[DREG + 3])) == 255)
  {
    putstring("can't load ");
    putstring(&D[DREG + 3]);
    terpri();
    errorThrown = 1;
    return;
  }

  // This switches the lexical scanner to our open file.
  infh = fh;

  // Reset system as though nothing has happened.
  initDynamic();
  initSymtab();
  initInts();
  initParse();
  resetFOR();


  // Load it up, we start executing in the caller.
  PC = 0;
  loadProgramFile();
  return;
}

  
    
// EOF
