/*****************************************************
 * PROJECT:       BBB interpreter
 * ORGANIZATION:  Microfluffy Corp.
 * LANGUAGE:      any ANSI C/C++ complaint
 * FILE:          bbb.cpp
 * DESCRIPTION:   Main file. Global execution loop
 * VERSION:       1.0
 *****************************************************/

#include <iostream.h>
#include <fstream.h>
#include <stdlib.h>
#include "bbb.h"

/* The main data structure for holding the program text */
struct {
  int LineNumber;
  char Line[MAX_LINE];
} ProgBuf[MAX_PROG];

TokenType Token;                /* current token */
int IntValue;                   /* if current token is T_NUM, this */
				/* holds its value */
char StrValue[MAX_STRVARLEN];   /* if current token is T_STRING, this */
				/* holds its value */
int TotalLines;                 /* Total lines in the program */
int CurrentIndex;               /* Index of the current line */
int CurrentLine;                /* Number of the current line */


/* prints out an error message of the form "Error: (line <num>) <message>".
   ErrStr contains the message to display, and LineNum the line number
   that the error occurred on.  If LineNum nonpositive, then the error
   message will not include a line number.  After printing out the
   error message, the program ends.  */
void PrintError (char* ErrStr, int LineNum)
{
  if (LineNum <= 0)  {
    cout << "Error: " << ErrStr << endl;
    exit(1);
  }
  else {
    cout << "Error: (line " << LineNum << ") " << ErrStr << endl;
    exit(1);
  }
}

/* Reads in the program text file.  It first prompts for the filename,
   then reads in the file. */
void ReadProgText(void)
{
  int i;
  char InFileName[256];
  ifstream InFile;
    
  i = 0;
  cout << "Enter BBB source code file name: ";
  cin >> InFileName;

  InFile.open(InFileName, ios::in);

  while (!InFile.eof())
    {
      InFile >> ProgBuf[i].LineNumber;
      InFile.get(ProgBuf[i].Line, MAX_LINE);
      
      if ((ProgBuf[i].LineNumber < 0) || (ProgBuf[i].LineNumber > 32760))
	PrintError(e_badline, ProgBuf[i].LineNumber);
      i++;
    }
  TotalLines = i;
  InFile.close();
}


int main()
{
  int i, NextLine;

  InitScanner();
  InitSymtab();
  ReadProgText();

  CurrentIndex = 0;
  CurrentLine = ProgBuf[CurrentIndex].LineNumber;
  while (CurrentIndex <= TotalLines)
    {
      NextLine = ParseLine(ProgBuf[CurrentIndex].Line);
      if (NextLine == NEXT_LINE) {
	CurrentIndex++;
	CurrentLine = ProgBuf[CurrentIndex].LineNumber;
      }
      else {
	i = 0;
	/* search for the line number being jumped to */
	while (ProgBuf[i].LineNumber != NextLine) i++;
	if (ProgBuf[i].LineNumber != NextLine)
	  PrintError(e_badline, ProgBuf[CurrentIndex].LineNumber);
	else {
	  CurrentIndex = i;
	  CurrentLine = ProgBuf[CurrentIndex].LineNumber;
	}
      }
    }
  return 0;
}

