#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include "setup.h"

/* ----------------------------------------------------- */

void openFile (char* kcodeFile)
{
  infile = fopen(kcodeFile,"r");
  if (infile == NULL)
  {
    printf ("unable to open %s!\n",kcodeFile);
    exit (EXIT_FAILURE);
  }
  done = 0;
}

void closeFile (void)
{
  fclose (infile);
}

/* ----------------------------------------------------- */

void readLine (void)
{
  fgets (buffer,BUFFER_SIZE,infile);
  if (!feof(infile))
  {
    pos = 0;
    skipBlanks ();
  }
  else
    done = 1;
}

void skipBlanks (void)
{
  while ((pos < strlen(buffer)) && isblank(buffer[pos]))
    pos++;
}

int isBlankLine (void)
{
  if ((pos < strlen(buffer)) &&
      ((buffer[pos] == '\n')|| (buffer[pos] == '#')))
    return 1;
  else
    return 0;
}

/* ----------------------------------------------------- */

char* getCode (void)
{
  char* result = (char*) malloc (LITERAL_SIZE);
  int i = 0;
  if (buffer[pos] == '_')
  {
  // KCODE directive
    while (isalpha(buffer[pos]) || (buffer[pos] == '_'))
      result[i++] = toupper(buffer[pos++]);
    result[i] = '\0';
    skipBlanks ();
  }
  else if (isalpha(buffer[pos]))
  {
  // KCODE instruction
    while (isalnum(buffer[pos]))
      result[i++] = toupper(buffer[pos++]);
    result[i] = '\0';
    skipBlanks ();
  }
  else
  {
  // invalid KCODE entry
    printf ("invalid line: %s\n",buffer);
    exit (EXIT_FAILURE);
  }
  return result;
}

/* ----------------------------------------------------- */

char* getOperand (void)
{
  char* result = (char*) malloc (LITERAL_SIZE);
  int i = 0;
  if (isBlankLine())
  {
    result[0] = '\0';
    return result;
  }
  else if (isalpha(buffer[pos]))
  {
  // label or identifier
    while (isalnum(buffer[pos]))
      result[i++] = toupper(buffer[pos++]);
    result[i] = '\0';
    skipBlanks ();
  }
  else if ((buffer[pos] == '\"') ||
           (buffer[pos] == '\''))
  {
  // character or string literal
    char terminal = buffer[pos];
    result[i++] = buffer[pos++];
    while (buffer[pos] != terminal)
      result[i++] = buffer[pos++];
    result[i++] = buffer[pos++];
    result[i] = '\0';
    skipBlanks ();
  }
  else if ((buffer[pos] == '+') ||
           (buffer[pos] == '-') ||
           (isdigit(buffer[pos])))
  {
    // numeric literal: integer
    if ((buffer[pos] == '+') || (buffer[pos] == '-'))
      result[i++] = buffer[pos++];
    while (isdigit(buffer[pos]))
      result[i++] = buffer[pos++];
    // numeric literal: floating point
    if (buffer[pos] == '.')
    {
      result[i++] = buffer[pos++];
      while (isdigit(buffer[pos]))
        result[i++] = buffer[pos++];
    }
    // numeric literal: floating point
    if ((buffer[pos] == 'e') || (buffer[pos] == 'E'))
    {
      result[i++] = buffer[pos++];
      if ((buffer[pos] == '+') || (buffer[pos] == '-'))
      {
        result[i++] = buffer[pos++];
        while (isdigit(buffer[pos]))
          result[i++] = buffer[pos++];
      }
    }
    result[i] = '\0';
    skipBlanks ();
  }
  else if (buffer[pos] == '=')
  {
  // memory address
    result[i++] = buffer[pos++];
    while (isalnum(buffer[pos]))
      result[i++] = toupper(buffer[pos++]);
    result[i] = '\0';
    skipBlanks ();
  }
  else
  {
    result[i] = '\0';
    skipBlanks ();
  }
  return result;
}

/* ----------------------------------------------------- */
