예제 #1
0
static NormPtr expand_parse_template (NormPtr i)
{
	Template *t = tpls [CODE [i++] - IDENTBASE];
	Token **argv = (Token**) alloca (t->argc * sizeof (Token*)), *argvv;
	int argc, c;
	NormPtr s;

	if (CODE [i++] != '(') parse_error (i, "template invokation");
	for (argc = 0; argc < t->argc; i++) {
		s = i;
		while (CODE [i] != ',' && CODE [i] != ')')
			i++;
		argv [argc++] = argvv = (Token*) alloca ((1 + i - s) * sizeof (Token));
		intextract (argvv, &CODE [s], i - s);
		for (c = 0; argvv [c] != -1; c++)
			if (!tokcmp (argvv [c], TEMPLATE_COMMA))
				argvv [c] = ',';
			else if (!tokcmp (argvv [c], TEMPLATE_PARENTH))
				argvv [c] = ')';
		if (CODE [i] == ')') break;
	}
	if (argc < t->argc) parse_error (i, "too few arguments to template");
	if (CODE [i] != ')') parse_error (i, "too many arguments to template");
	expand_template (t, argv);

	return i;
}
예제 #2
0
////////////////////////////////////////////////////////////////////////////////
// static classNum - returns the number of a class name
//
// Parameters:
//    aclass : string to scan, prefix should be a class name
//    pos    : returns length of the found class name if result != 0
//
// Returns:
//    The number of a class (CLASS_...)
//
//    pos: see above
//
int TParameterDeclaration::classNum(const char *aclass, size_t &pos) {
	int i;
	if ( !aclass ) return 0;
	for ( i = 1; i < N_CLASSNAMES; ++i ) {
		if ( !tokcmp(m_classNames[i], aclass) ) {
			pos = strlen(m_classNames[i]);
			return i;
		}
	}
	return 0;
}
예제 #3
0
////////////////////////////////////////////////////////////////////////////////
// static typeNum - returns the number of a type given by name
//
// Parameters:
//    aclass : string to scan, prefix should be a type name
//    pos    : returns length of the found type name if result != 0
//
// Returns:
//    The number of a class (TYPE_...)
//
//    pos: see above
//
int TParameterDeclaration::typeNum(const char *type, size_t &pos) {
	int i;
	if ( !type ) return 0;
	for ( i = 1; i < N_TYPESIZES; ++i ) {
		if ( !tokcmp(m_typeNames[i], type) ) {
			pos = strlen(m_typeNames[i]);
			// let int be integer
			if ( i == TYPE_INT ) i = TYPE_INTEGER;
			return i;
		}
	}
	return 0;
}
예제 #4
0
파일: shell.c 프로젝트: netspencer/FACT
void
shell (func_t * scope)
{
  /**
   * shell - when FACT is run by default it comes to here. The
   * main user interface for FACT, this function grabs an
   * expression of input, parses it, runs it, and repeats. It
   * will continue to do so until the user does a C-d, C-c,
   * returns a value from the main scope, or calls the exit
   * function.
   *
   * @scope  - the scope to use when evaluating expressions.
   */
  FACT_t       returned;  // The value returned by the interpreter.
  unsigned int end_line;  // ...
  unsigned int hold_line; // ...

  int  *newlines;
  char *input;
  char *hold_input;   // Used in the main loop to check for else clauses.
  char **tokenized;   // input, tokenized.
  char **hold_tokens; // Also used to check for else clauses.

  /* Before we start, print out the copyright info, logo and
   * a guide to some helpful functions.
   */
  print_logo ();
  printf ("The FACT programming language interactive shell\n"
	  "© 2010, 2011 Matthew Plant, under the GPL version 3.\n");

  hold_input = NULL;
  scope->file_name = "stdin";
  scope->line = 1;
  end_line = 0;
  
  for (;;) // Heh, that looks like a spider.
    {
      /* Set the line number to end_line, in case we missed any while evaluating
       * the last expression.
       */
      scope->line += end_line;
      end_line = 0;

      // Then, get raw input for an entire expression.
      if (hold_input == NULL)
	input = get_input (stdin, &end_line, "S>", "C>");
      else
	{
	  input = hold_input;
	  hold_input = NULL;
	}

      /* We do two checks for EOF signals: once before tokenizing, and once after.
       * I am not completely sure as to why this is the case, but I do remember at
       * some point it didn't exit so I added the second check.
       */
      if (input == NULL)
	break;

      // Tokenize the input.
      tokenized = get_words (input);
      if (tokenized == NULL)
	break;
      
      /* If the first token in the expression is if/on_error, continue to get input
       * as long as the first token is else. I could forsee this being an issue in
       * places where the else is placed erroneosly, but that'll be fixed later I
       * assume.
       */ 
      if ((tokenized[0][0] == '\n'
	   && (!tokcmp (tokenized[1], "if")
	       || !tokcmp (tokenized[1], "error")))
	  || (!tokcmp (tokenized[0], "if")
	      || !tokcmp (tokenized[0], "error")))
	{
	  for (;;)
	    {
	      /* Go through all the steps we went through from the start of the loop
               * down to here.
	       */
	      hold_input = get_input (stdin, &end_line, "?>", "C>");

	      if (hold_input == NULL|| (hold_tokens = get_words (hold_input)) == NULL)
		break;
	      // Check to see if the statement starts with else.
	      if ((hold_tokens[0][0] == '\n'
		   && !tokcmp (hold_tokens[1], "else"))
		  || !tokcmp (hold_tokens[0], "else"))
		{
		  input[strlen (input) - 1] = '\0';
		  input = combine_strs (input, hold_input);
		  hold_input = NULL;
		}
	      else
		break;
	    }
          printf ("\n");
	  tokenized = get_words (input);
	}

      // Get the newlines and parse the string.
      tokenized = parse (tokenized, "stdin", scope->line, &newlines);

      if (tokenized == NULL)
        continue;

      // Reset the instruction pointer.
      reset_ip ();

      // Evaluate the expression.
      returned = eval_expression (scope, make_syn_tree (tokenized, newlines));

      /* If there were errors, print them out. Otherwise,
       * print the value of the variable or the name of
       * the function returned.
       */
      if (returned.type == ERROR_TYPE)
	errorman_dump (returned.error);
      else if (returned.type == VAR_TYPE)
	printf ("Returned value: %s\n", mpc_get_str (returned.v_point->data));
      else
	printf ("Returned object [%s]\n", returned.f_point->name);

      /* Check to see if the value is to be returned, and
       * if so, exit.
       */
      if (returned.return_signal)
	break;
    }
  puts ("\nExiting...");
}