Ejemplo n.º 1
0
/*Used to determine what type is coming next in the stream
 *Inputs:
 *  in - the stream to read from
 *  c - the first non-whitespace character to look at*/
object_type next_type(FILE *in, char c){
  int next_char;
  if(c == EOF){
    printf("Got EOF, exiting\n");
    exit(0);
  }
  if(c == '#'){ /*a boolean or character*/
    next_char = peek(in);
    switch(next_char){
      case 't':
      case 'f':
        return BOOLEAN;
      case '\\':
        return CHARACTER;
      default:
        fprintf(stderr,
            "Unknown boolean or character literal\n");
        exit(1);
    }
  }else if (isdigit(c) || (c == '-' && isdigit(peek(in)))){
    ungetc(c, in);
    return FIXNUM;
  }else if(c == '('){
    if(peek(in) == ')'){
      return EMPTY_LIST;
    }else{
      return PAIR;
    }
  }else if(c == '"'){
    return STRING;
  /*if this is the start of a symbol*/
  }else if(is_symbol_start(c) ||
    /*or +/- by themselves*/
    ((c == '+' || c == '-') && is_delimiter(peek(in)))){
      //put this first character back
      ungetc(c, in);
      return SYMBOL;
  }else{
    fprintf(stderr, "Bad input. Unexpected '%c'\n", c);
    exit(1);
  }
  fprintf(stderr, "No object type, no error... wtf?\n");
  exit(1);
}
Ejemplo n.º 2
0
static void pgn_read_token(pgn_t * pgn) {

   ASSERT(pgn!=NULL);

   // skip white-space characters

   pgn_skip_blanks(pgn);

   // init

   pgn->token_type = TOKEN_ERROR;
   strcpy(pgn->token_string,"");
   pgn->token_length = 0;
   pgn->token_line = pgn->char_line;
   pgn->token_column = pgn->char_column;

   // determine token type

   if (false) {

   } else if (pgn->char_hack == CHAR_EOF) {

      pgn->token_type = TOKEN_EOF;

   } else if (strchr(".[]()<>",pgn->char_hack) != NULL) {

      // single-character token

      pgn->token_type = pgn->char_hack;
      sprintf(pgn->token_string,"%c",pgn->char_hack);
      pgn->token_length = 1;

   } else if (pgn->char_hack == '*') {

      pgn->token_type = TOKEN_RESULT;
      sprintf(pgn->token_string,"%c",pgn->char_hack);
      pgn->token_length = 1;

   } else if (pgn->char_hack == '!') {

      pgn_char_read(pgn);

      if (false) {

      } else if (pgn->char_hack == '!') { // "!!"

         pgn->token_type = TOKEN_NAG;
         strcpy(pgn->token_string,"3");
         pgn->token_length = 1;

      } else if (pgn->char_hack == '?') { // "!?"

         pgn->token_type = TOKEN_NAG;
         strcpy(pgn->token_string,"5");
         pgn->token_length = 1;

      } else { // "!"

         pgn_char_unread(pgn);

         pgn->token_type = TOKEN_NAG;
         strcpy(pgn->token_string,"1");
         pgn->token_length = 1;
      }

   } else if (pgn->char_hack == '?') {

      pgn_char_read(pgn);

      if (false) {

      } else if (pgn->char_hack == '?') { // "??"

         pgn->token_type = TOKEN_NAG;
         strcpy(pgn->token_string,"4");
         pgn->token_length = 1;

      } else if (pgn->char_hack == '!') { // "?!"

         pgn->token_type = TOKEN_NAG;
         strcpy(pgn->token_string,"6");
         pgn->token_length = 1;

      } else { // "?"

         pgn_char_unread(pgn);

         pgn->token_type = TOKEN_NAG;
         strcpy(pgn->token_string,"2");
         pgn->token_length = 1;
      }

   } else if (is_symbol_start(pgn->char_hack)) {

      // symbol, integer, or result

      pgn->token_type = TOKEN_INTEGER;
      pgn->token_length = 0;

      do {

         if (pgn->token_length >= PGN_STRING_SIZE-1) {
            my_fatal("pgn_read_token(): symbol too long at line %d, column %d\n",pgn->char_line,pgn->char_column);
         }

         if (!isdigit(pgn->char_hack)) pgn->token_type = TOKEN_SYMBOL;

         pgn->token_string[pgn->token_length++] = pgn->char_hack;

         pgn_char_read(pgn);

      } while (is_symbol_next(pgn->char_hack));

      pgn_char_unread(pgn);

      ASSERT(pgn->token_length>0&&pgn->token_length<PGN_STRING_SIZE);
      pgn->token_string[pgn->token_length] = '\0';

      if (my_string_equal(pgn->token_string,"1-0")
       || my_string_equal(pgn->token_string,"0-1")
       || my_string_equal(pgn->token_string,"1/2-1/2")) {
         pgn->token_type = TOKEN_RESULT;
      }

   } else if (pgn->char_hack == '"') {

      // string

      pgn->token_type = TOKEN_STRING;
      pgn->token_length = 0;

      while (true) {

         pgn_char_read(pgn);

         if (pgn->char_hack == CHAR_EOF) {
            my_fatal("pgn_read_token(): EOF in string at line %d, column %d\n",pgn->char_line,pgn->char_column);
         }

         if (pgn->char_hack == '"') break;

         if (pgn->char_hack == '\\') {

            pgn_char_read(pgn);

            if (pgn->char_hack == CHAR_EOF) {
               my_fatal("pgn_read_token(): EOF in string at line %d, column %d\n",pgn->char_line,pgn->char_column);
            }

            if (pgn->char_hack != '"' && pgn->char_hack != '\\') {

               // bad escape, ignore

               if (pgn->token_length >= PGN_STRING_SIZE-1) {
                  my_fatal("pgn_read_token(): string too long at line %d, column %d\n",pgn->char_line,pgn->char_column);
               }

               pgn->token_string[pgn->token_length++] = '\\';
            }
         }

         if (pgn->token_length >= PGN_STRING_SIZE-1) {
            my_fatal("pgn_read_token(): string too long at line %d, column %d\n",pgn->char_line,pgn->char_column);
         }

         pgn->token_string[pgn->token_length++] = pgn->char_hack;
      }

      ASSERT(pgn->token_length>=0&&pgn->token_length<PGN_STRING_SIZE);
      pgn->token_string[pgn->token_length] = '\0';

   } else if (pgn->char_hack == '$') {

      // NAG

      pgn->token_type = TOKEN_NAG;
      pgn->token_length = 0;

      while (true) {

         pgn_char_read(pgn);

         if (!isdigit(pgn->char_hack)) break;

         if (pgn->token_length >= 3) {
            my_fatal("pgn_read_token(): NAG too long at line %d, column %d\n",pgn->char_line,pgn->char_column);
         }

         pgn->token_string[pgn->token_length++] = pgn->char_hack;
      }

      pgn_char_unread(pgn);

      if (pgn->token_length == 0) {
         my_fatal("pgn_read_token(): malformed NAG at line %d, column %d\n",pgn->char_line,pgn->char_column);
      }

      ASSERT(pgn->token_length>0&&pgn->token_length<=3);
      pgn->token_string[pgn->token_length] = '\0';

   } else {

      // unknown token

      // my_fatal("lexical error at line %d, column %d\n",pgn->char_line,pgn->char_column);
   }
}