Getting started

As the very first part I want an “interactive” editor, with a prompt, where I can enter commands, and it’ll execute them and respond with READY, until I enter the command QUIT.

Should be simple.

#include <stdio.h>
#include <string.h>

int main()
{
  printf("Welcome to BASIC\\n");
  char inputline[255] = "";

  do
  {
    printf("ready.\\n");
    printf(">");

    fgets(inputline, 255, stdin);
    // remove last newline
    inputline[strlen(inputline) - 1] = '\\0';

    printf("You entered '%s'\\n", inputline);
  } while (strncmp(inputline, "QUIT", 4) != 0);

  return 0;
}

Adding keywords

I want to recognize if a known keywoard has been entered - so I’ll need a list

const char* keywords[] = {"NEW", "LIST", "RUN", "END", "REM", "LET", "PRINT", "INPUT"};

Just a more or less randomly selected group for now.

I want to check if the inputline contains any of these words - as the first word, and ignoring leading whitespace. In BASIC you didn’t have to have spaces after keywords, you could write FORA=1TO10 just as well as FOR A = 1 TO 10, and I want to retain that option. Also I want to ignore upper/lowercase in entry.

So first I make a pointer to the inputline, so that I can point anywhere inside it:

char *inp = inputline;

And then skip the whitespace - for now just spaces and tabs

while (*inp == ' ' || *inp == '\\t')
      inp++;

inp should now point to the first character of a keyword - to make it easier for me to compare the inp to any keyword ignoring case, I’ve made a little helper function:

int startsWithIgnoreCase(char *string, const char *word)
{
  while (*word)
  {
    if (toupper(*string++) != *word++)
    {
      return 0;
    }
  }
  return 1;
}

Then a very simple, hardcoded loop to go through the list of keywords, and check each one:

for (int kw = 0; kw < 8; kw++)
{
  if (startsWithIgnoreCase(inp, keywords[kw]))
  {
    printf("Recognized keyword: %s in %s\\n", keywords[kw], inp);
  }
}

Note that this would prevent having keywords that were part of another keyword, like PRINT and PRINT# - in that case # would need to be a parameter to PRINT.

→ continue to Implementing (some) commands