Esempio n. 1
0
char *
next_token()
{
	char *result = NULL;
	while (g_pos < g_len && result == NULL) {
		if (g_text[g_pos] & 0x80) { /*	ch character */
			result = get_ch_word();
		} else if (isalnum(g_text[g_pos])) {
			result = get_ascii_word();
		} else {
			g_pos++;
		}
	}
	return result;
}
/* load_egg_cmd:
 *  Reads a list of commands.
 */
static EGG_COMMAND *load_egg_cmd(EGG *egg, int root, char *error)
{
   EGG_COMMAND *cmd = NULL;
   EGG_COMMAND *tail = NULL;
   EGG_TYPE *type;
   char buf[1024];
   char buf2[256];


   /* helper macro for inserting new commands into the list */
   #define ADD_COMMAND(_type_)                                 \
   {                                                           \
      if (tail) {                                              \
	 tail->next = malloc(sizeof(EGG_COMMAND));             \
	 tail = tail->next;                                    \
      }                                                        \
      else                                                     \
	 tail = cmd = malloc(sizeof(EGG_COMMAND));             \
							       \
      tail->type = _type_;                                     \
      tail->line = egg_line;                                   \
      tail->var = NULL;                                        \
      tail->exp = NULL;                                        \
      tail->cmd = NULL;                                        \
      tail->cmd2 = NULL;                                       \
      tail->next = NULL;                                       \
   }


   while ((!egg_eof()) && (!error[0])) {
      get_word(buf);

      if (strcmp(buf, "}") == 0) {
	 /* block end marker */
	 if (root)
	    egg_error(error, "Unexpected '}'");
	 else
	    return cmd;
      }
      else if (strcmp(buf, "if") == 0) {
	 /* parse an if statement */
	 get_word(buf);

	 if (strcmp(buf, "(") != 0) {
	    egg_error(error, "Missing '('");
	 }
	 else {
	    get_formula(buf, ')', error);

	    if (!error[0]) {
	       get_brace(error);

	       if (!error[0]) {
		  ADD_COMMAND(EGG_COMMAND_IF);

		  tail->exp = malloc(strlen(buf)+1);
		  strcpy(tail->exp, buf);

		  tail->cmd = load_egg_cmd(egg, FALSE, error);
	       }
	    }
	 }
      }
      else if (strcmp(buf, "else") == 0) {
	 /* parse an else statement */
	 if ((!tail) || (tail->type != EGG_COMMAND_IF) || (tail->cmd2)) {
	    egg_error(error, "Invalid context for 'else'");
	 }
	 else {
	    get_brace(error);

	    if (!error[0])
	       tail->cmd2 = load_egg_cmd(egg, FALSE, error);
	 }
      }
      else if (strcmp(buf, "lay") == 0) {
	 /* parse a lay statement */
	 ADD_COMMAND(EGG_COMMAND_LAY);

	 get_word(buf);

	 if (strcmp(buf, "(") == 0) {
	    get_formula(buf, ')', error);

	    if (!error[0]) {
	       tail->exp = malloc(strlen(buf)+1);
	       strcpy(tail->exp, buf);

	       get_word(buf);
	    }
	 }

	 if (!error[0]) {
	    check_ascii_word(buf, error);

	    if (!error[0]) {
	       tail->var = malloc(strlen(buf)+1);
	       strcpy(tail->var, buf);

	       get_word(buf);

	       if (strcmp(buf, "{") == 0)
		  tail->cmd = load_egg_cmd(egg, FALSE, error);
	       else if (strcmp(buf, ";") != 0)
		  egg_error(error, "Expecting '{' or ';'");
	    }
	 }
      }
      else if (strcmp(buf, "die") == 0) {
	 /* parse a die statement */
	 ADD_COMMAND(EGG_COMMAND_DIE);

	 get_word(buf);

	 if (strcmp(buf, ";") != 0)
	    egg_error(error, "Missing ';'");
      }
      else if (strcmp(buf, "type") == 0) {
	 /* parse a type definition */
	 if (!root) {
	    egg_error(error, "Nested type definition");
	 }
	 else {
	    get_ascii_word(buf, error);

	    if (!error[0]) {
	       type = malloc(sizeof(EGG_TYPE));

	       type->name = malloc(strlen(buf)+1);
	       strcpy(type->name, buf);

	       type->cmd = NULL;
	       type->next = NULL;

	       get_brace(error);

	       if (error[0]) {
		  free(type->name);
		  free(type);
	       }
	       else {
		  type->cmd = load_egg_cmd(egg, FALSE, error);

		  if (error[0]) {
		     free(type->name);
		     free(type);
		  }
		  else {
		     type->next = egg->type;
		     egg->type = type;
		  }
	       }
	    }
	 }
      }
      else if (buf[0]) {
	 /* this must be a variable assignment */
	 check_ascii_word(buf, error);

	 if (!error[0]) {
	    get_word(buf2);

	    if (strcmp(buf2, "=") == 0) {
	       ADD_COMMAND(EGG_COMMAND_SET);
	    }
	    else if (strcmp(buf2, ":") == 0) {
	       get_word(buf2);

	       if (strcmp(buf2, "=") != 0) {
		  egg_error(error, "Missing '='");
	       }
	       else {
		  ADD_COMMAND(EGG_COMMAND_INIT);
	       }
	    }
	    else {
	       egg_error(error, "F****d up syntax ");
	    }

	    if (!error[0]) {
	       tail->var = malloc(strlen(buf)+1);
	       strcpy(tail->var, buf);

	       get_formula(buf, ';', error);

	       if (!error[0]) {
		  tail->exp = malloc(strlen(buf)+1);
		  strcpy(tail->exp, buf);
	       }
	    }
	 }
      }
   }

   if ((!error[0]) && (egg_eof()) && (!root))
      egg_error(error, "Unexpected EOF");

   if (error[0]) {
      destroy_egg_cmd(cmd);
      return NULL;
   }

   return cmd;
}