예제 #1
0
/*-------------------------------------------------------------------------*
 * PL_NAME_2                                                               *
 *                                                                         *
 *-------------------------------------------------------------------------*/
Bool
Pl_Name_2(WamWord atomic_word, WamWord codes_word)
{
  WamWord word, tag_mask;
  int syn_flag;
  Bool is_number;
  char *str;


  DEREF(atomic_word, word, tag_mask);
  if (tag_mask == TAG_ATM_MASK)
    return Pl_Atom_Codes_2(word, codes_word);

  if (tag_mask == TAG_INT_MASK || tag_mask == TAG_FLT_MASK)
    return Pl_Number_Codes_2(word, codes_word);

  if (tag_mask != TAG_REF_MASK)
    Pl_Err_Type(pl_type_atomic, word);


  str = Pl_Rd_Codes_Check(codes_word);

  syn_flag = Flag_Value(syntax_error);
  Flag_Value(syntax_error) = PF_ERR_FAIL;

  is_number = String_To_Number(str, word);	/* only fails on syn err */

  Flag_Value(syntax_error) = syn_flag;

  if (is_number)
    return TRUE;

  return Pl_Un_String(str, word);
}
예제 #2
0
파일: term_supp.c 프로젝트: adinho/Testing
/*-------------------------------------------------------------------------*
 * PL_GET_PRED_INDICATOR                                                   *
 *                                                                         *
 * returns the functor and initializes the arity of the predicate indicator*
 * func= -1 if it is a variable, arity= -1 if it is a variable             *
 *-------------------------------------------------------------------------*/
int
Pl_Get_Pred_Indicator(WamWord pred_indic_word, Bool must_be_ground, int *arity)
{
    WamWord word, tag_mask;
    int func;

    DEREF(pred_indic_word, word, tag_mask);
    if (tag_mask == TAG_REF_MASK && must_be_ground)
        Pl_Err_Instantiation();

    if (!Pl_Get_Structure(ATOM_CHAR('/'), 2, pred_indic_word))
    {
        if (!Flag_Value(FLAG_STRICT_ISO) &&
                Pl_Rd_Callable(word, &func, arity) != NULL)
            return func;

        Pl_Err_Type(pl_type_predicate_indicator, pred_indic_word);
    }

    pl_pi_name_word = Pl_Unify_Variable();
    pl_pi_arity_word = Pl_Unify_Variable();

    if (must_be_ground)
        func = Pl_Rd_Atom_Check(pl_pi_name_word);
    else
    {
        DEREF(pl_pi_name_word, word, tag_mask);
        if (tag_mask == TAG_REF_MASK)
            func = -1;
        else
            func = Pl_Rd_Atom_Check(pl_pi_name_word);
    }

    if (must_be_ground)
    {
        *arity = Pl_Rd_Positive_Check(pl_pi_arity_word);

        if (*arity > MAX_ARITY)
            Pl_Err_Representation(pl_representation_max_arity);
    }
    else
    {
        DEREF(pl_pi_arity_word, word, tag_mask);
        if (tag_mask == TAG_REF_MASK)
            *arity = -1;
        else
        {
            *arity = Pl_Rd_Positive_Check(pl_pi_arity_word);

            if (*arity > MAX_ARITY)
                Pl_Err_Representation(pl_representation_max_arity);
        }
    }

    return func;
}
예제 #3
0
/*-------------------------------------------------------------------------*
 * STRING_TO_NUMBER                                                        *
 *                                                                         *
 *-------------------------------------------------------------------------*/
static Bool
String_To_Number(char *str, WamWord number_word)
{
  WamWord word;
  int stm;
  StmInf *pstm;
  Bool eof;

  Pl_Check_For_Un_Number(number_word);

/* #if 0 since layout leading chars allowed in ISO cf. number_chars */
#if 0
  if (!isdigit(*str) && *str != '-')
    {
      Pl_Set_Last_Syntax_Error("", 1, 1, "non numeric character");
      goto err;
    }
#endif

  stm = Pl_Add_Str_Stream(str, TERM_STREAM_ATOM);
  pstm = pl_stm_tbl[stm];

  word = Pl_Read_Number(pstm);
  eof = (Pl_Stream_Peekc(pstm) == EOF);

  if (word != NOT_A_WAM_WORD && !eof)
    Pl_Set_Last_Syntax_Error(pl_atom_tbl[pstm->atom_file_name].name,
			  pstm->line_count + 1, pstm->line_pos + 1,
			  "non numeric character");

  Pl_Delete_Str_Stream(stm);

  if (word == NOT_A_WAM_WORD || !eof)
    {
#if 0
    err:
#endif
      Pl_Syntax_Error(Flag_Value(syntax_error));
      return FALSE;
    }

  return Pl_Unify(word, number_word);
}
예제 #4
0
/*-------------------------------------------------------------------------*
 * PL_SCAN_NEXT_ATOM                                                       *
 *                                                                         *
 * Scan the next atom.                                                     *
 *-------------------------------------------------------------------------*/
char *
Pl_Scan_Next_Atom(StmInf *pstm)
{
  char *s;

  err_msg = NULL;

  do
    Read_Next_Char(pstm, TRUE);
  while (c_type == LA);		/* layout character */

  pl_token.line = pstm->line_count + 1;
  pl_token.col = pstm->line_pos;

  switch (c_type)
    {
    case SL:			/* small letter */
      s = pl_token.name;
      do
	{
	  *s++ = c;
	  Read_Next_Char(pstm, TRUE);
	}
      while (c_type & (UL | CL | SL | DI));
      *s = '\0';
      Unget_Last_Char;
      break;

    case DQ:			/* double quote */
      if ((Flag_Value(double_quotes) & PF_QUOT_AS_PART_MASK) != PF_QUOT_AS_ATOM)
	goto error;
      goto do_scan_quoted;

    case BQ:			/* back quote */
      if ((Flag_Value(back_quotes) & PF_QUOT_AS_PART_MASK) != PF_QUOT_AS_ATOM)
	goto error;
    case QT:			/* quote */
    do_scan_quoted:
      err_msg = NULL;
      Scan_Quoted(pstm);
      if (err_msg)
	return err_msg;
      break;

    case GR:			/* graphic */
      s = pl_token.name;
      while (c_type == GR)
	{
	  *s++ = c;
	  Read_Next_Char(pstm, TRUE);
	}
      *s = '\0';
      Unget_Last_Char;
      break;

    case SC:			/* solo character */
      pl_token.name[0] = c;
      pl_token.name[1] = '\0';
      break;

    default:
    error:
      Unget_Last_Char;
      return "cannot start an atom (use quotes ?)";
    }

  pl_token.type = TOKEN_NAME;
  return NULL;
}
예제 #5
0
/*-------------------------------------------------------------------------*
 * SCAN_QUOTED_CHAR                                                        *
 *                                                                         *
 *-------------------------------------------------------------------------*/
static int
Scan_Quoted_Char(StmInf *pstm, Bool convert, int c0, Bool no_escape)
{
  int radix;
  char *p, *f;
  int x, i;

  Read_Next_Char(pstm, convert);
  if (c == c0)
    {
      if (Pl_Scan_Peek_Char(pstm, convert) != c0)	/* '' or "" or `` */
	return -1;					/* closing quote */

      Read_Next_Char(pstm, convert);
      return c;
    }

  if (c == EOF)
    {
      if (err_msg == NULL)
	{
	  Unget_Last_Char;
	  pl_token.line = pstm->line_count + 1;
	  pl_token.col = pstm->line_pos + 1;
	  err_msg = "unexpected end of file";
	}
      return -3;		/* -3 means EOF */
    }

  if (c == '\n')
    {
      if (err_msg == NULL)
	{
	  Unget_Last_Char;
	  pl_token.line = pstm->line_count + 1;
	  pl_token.col = pstm->line_pos + 1;
	  err_msg = "unexpected newline";
	}
      return -4;		/* -4 means newline */
    }

  if (c == '\t')
    {
      if (err_msg == NULL)
	{
	  Unget_Last_Char;
	  pl_token.line = pstm->line_count + 1;
	  pl_token.col = pstm->line_pos + 1;
	  err_msg = "unexpected tab";
	}
      return -5;		/* -5 means tab */
    }

  if (c != '\\' || no_escape)
    return c;

  				/* \...  escape sequences */

  Read_Next_Char(pstm, convert);

  if (c == '\n')		/* \ followed by newline */
    return -2;			/* -2 means \ newline */

  if (strchr("\\'\"`", c))	/* \\ or \' or \" or \` */
    return c;

  if ((p = (char *) strchr(pl_escape_symbol, c)))	/* \a \b \f \n \r \t \v */
    return pl_escape_char[p - pl_escape_symbol];

  if (!Flag_Value(strict_iso))
    {
      if (c == 's')		/* \s = space */
	return ' ';

      if (c == 'e')		/* ESCAPE */
	return 27;
    }

  if (c == 'x' || ('0' <= c && c <= '7'))	/* \xnn\ \nn\ */
    {
      if (c == 'x')
	{
	  radix = 16;
	  f = "0123456789abcdefABCDEF";
	  x = 0;
	}
      else
	{
	  radix = 8;
	  f = "01234567";
	  x = c - '0';
	}

      Read_Next_Char(pstm, convert);
      while ((p = strchr(f, c)) != NULL)
	{
	  i = p - f;
	  if (i >= 16)
	    i -= 6;
	  x = x * radix + i;
	  Read_Next_Char(pstm, convert);
	}

      if (!Is_Valid_Code(x))
	{
	  if (err_msg == NULL)
	    {
	      pl_token.line = pstm->line_count + 1;
	      pl_token.col = pstm->line_pos;
	      err_msg = "invalid character code in \\constant\\ sequence";
	    }
	  goto pump;
	}

      if (c != '\\')
	{
	  if (err_msg == NULL)
	    {
	      pl_token.line = pstm->line_count + 1;
	      pl_token.col = pstm->line_pos;
	      err_msg = "\\ expected in \\constant\\ sequence";
	    }

	  /* pump until \ or closing quote or newline is found */
	pump:
	  while(c != '\\' && c != c0 && c != EOF && c != '\n')
	    Read_Next_Char(pstm, convert);
	  if (c == c0)
	    Unget_Last_Char;	/* to be able to continue in the parent's loop */

	  return -6;		/* -6 means other error */
	}

      return (int) (unsigned char) x;
    }

  if (err_msg == NULL)
    {
      pl_token.line = pstm->line_count + 1;
      pl_token.col = pstm->line_pos;
      err_msg = "unknown escape sequence";
    }

  return -6;		/* -6 means other error */
}
예제 #6
0
/*-------------------------------------------------------------------------*
 * SCAN_QUOTED                                                             *
 *                                                                         *
 *-------------------------------------------------------------------------*/
static void
Scan_Quoted(StmInf *pstm)
{
  int c0;
  char *s;
  Bool convert = (c_orig != '\'');
  Bool no_escape;
  Bool error_found = FALSE;
  int i = 0;

  if (c_type == QT)
    {
      pl_token.type = TOKEN_NAME;
      pl_token.quoted = TRUE;
      i = 0;
    }
  else if (c_type == DQ)
    {
      pl_token.type = TOKEN_STRING;
      i = Flag_Value(double_quotes);
    }
  else
    {
      pl_token.type = TOKEN_BACK_QUOTED;
      i = Flag_Value(back_quotes);
    }

  s = pl_token.name;
  c0 = c;
  no_escape = i >> PF_QUOT_NO_ESCAPE_BIT;

  for (;;)
    {
      c = Scan_Quoted_Char(pstm, convert, c0, no_escape);
      if (c == -1)		/* closing quote */
	{
	  if (error_found)
	    break;

	  *s = '\0';
	  return;
	}

      if (c == -2)		/* \ followed by newline */
	continue;

      if (c == -3 || c == -4)	/* EOF   newline */
	{
	  pl_token.type = TOKEN_FULL_STOP; /* to stop immediately Pl_Recover_After_Error */
	  *s = '\0';
	  return;
	}

      if (c == -5 || c == -6)	/* tab or other error */
	{
	  error_found = TRUE;
	  continue;	        /* continue to try to catch the closing quote */
	}

      if (!error_found)
	*s++ = c;
    }

  /* error */

  *s = '\0';

  if (err_msg != NULL)		/* this test should now always succeed */
    return;

  /* thus this should never been used - to be checked */

  Unget_Last_Char;

  pl_token.line = pstm->line_count + 1;
  pl_token.col = pstm->line_pos + 1;

  switch (pl_token.type)
    {
    case TOKEN_NAME:
      err_msg = "quote character expected here";
      break;

    case TOKEN_BACK_QUOTED:
      err_msg = "back quote character expected here";
      break;

    case TOKEN_STRING:
      err_msg = "double quote character expected here";
      break;

    default:                    /* to avoid compiler warning */
      ;
    }
}
예제 #7
0
/*-------------------------------------------------------------------------*
 * SCAN_NUMBER                                                             *
 *                                                                         *
 *-------------------------------------------------------------------------*/
static void
Scan_Number(StmInf *pstm, Bool integer_only)
{
  int lg;
  int radix;
  char *p, *f;
  int c_orig0;

  /* at entry: c is a digit */

  p = pl_token.name;
  do
    {
      *p++ = c;
      Read_Next_Char(pstm, TRUE);
    }
  while (c_type == DI);
  lg = p - pl_token.name;

  if (!integer_only &&		/* float if . and digit */
      c == '.' && isdigit(Pl_Scan_Peek_Char(pstm, TRUE)))
    goto is_a_float;

  /* integer number */
  pl_token.type = TOKEN_INTEGER;
  *p = '\0';


  /* if case of an underflow/overflow strtol() returns LONG_MIN/LONG_MAX and
   * sets errno to ERANGE. We dont test it because LONG_MIN is < INT_LOWEST_VALUE
   * and LONG_MAX is > INT_GREATEST_VALUE. We will detect it at return from
   * this function.
   */
  pl_token.int_num = Str_To_PlLong(pl_token.name, &p, 10);

  if (lg != 1 || pl_token.int_num != 0 || strchr("'box", c) == NULL)
    goto push_back;

  if (c == '\'')		/* 0'<character> */
    {
      c = Scan_Quoted_Char(pstm, TRUE, '\'', FALSE);
      if (c == -1)		/* <character> is ' */
	{
	  /* STRICT ISO does not allow 0'' one should write 0''' or 0'\' */
	  if (Flag_Value(strict_iso))
	    {

	    /* do not emit an error since 0'' is valid if '' is a postif/infix op 
	     * (this is the only case) - simply return the integer 0 
	     */
#if 1
	      if (Check_Oper(pl_atom_void, INFIX) || Check_Oper(pl_atom_void, POSTFIX))
		{
		  Pl_Stream_Ungetc('\'', pstm);	/* push back last ' */
		  Pl_Stream_Ungetc('\'', pstm); /* push back first ' */
		  return;
		}
#endif
	      pl_token.line = pstm->line_count + 1;
	      pl_token.col = pstm->line_pos + 1;
	      err_msg = "quote character expected here";
	      return;
	    }
	  else
	    c = '\'';
	}

      if (c < 0) 		/* \ newline   EOF   newline   tab    other error */
	{
	  Unget_Last_Char;

	  pl_token.type = TOKEN_FULL_STOP; /* to stop immediately Pl_Recover_After_Error */
	  pl_token.line = pstm->line_count + 1;
	  pl_token.col = pstm->line_pos + 1;
	  err_msg = "character expected here";
	}

      pl_token.int_num = c;
      return;
    }

  radix = (c == 'b') ? (f = "01", 2) :
    (c == 'o') ? (f = "01234567", 8)
    : (f = "0123456789abcdefABCDEF", 16);
  p = pl_token.name;
  Read_Next_Char(pstm, TRUE);
  while (strchr(f, c) != NULL)
    {
      *p++ = c;
      Read_Next_Char(pstm, TRUE);
    }
  *p = '\0';

  pl_token.int_num = Str_To_PlLong(pl_token.name, &p, radix);
  goto push_back;


 is_a_float:			/* float number */

  pl_token.type = TOKEN_FLOAT;
  *p++ = '.';
  Read_Next_Char(pstm, TRUE);
  while (c_type == DI)
    {
      *p++ = c;
      Read_Next_Char(pstm, TRUE);
    }

  if (c == 'e' || c == 'E')
    {
      c_orig0 = c_orig;
      Read_Next_Char(pstm, TRUE);
      if (!(c_type == DI || ((c == '+' || c == '-') &&
			     isdigit(Pl_Scan_Peek_Char(pstm, TRUE)))))
	{
	  Unget_Last_Char;
	  c_orig = c_orig0;
	  goto end_float;
	}

      *p++ = 'e';
      *p++ = c;

      Read_Next_Char(pstm, TRUE);
      while (c_type == DI)
	{
	  *p++ = c;
	  Read_Next_Char(pstm, TRUE);
	}
    }


 end_float:
  *p = '\0';
  sscanf(pl_token.name, "%lf", &pl_token.float_num);

 push_back:
  Unget_Last_Char;
}
예제 #8
0
/*-------------------------------------------------------------------------*
 * PL_EMIT_SYNTAX_ERROR                                                    *
 *                                                                         *
 *-------------------------------------------------------------------------*/
void
Pl_Emit_Syntax_Error(char *file_name, int err_line, int err_col, char *err_msg)
{
  Pl_Set_Last_Syntax_Error(file_name, err_line, err_col, err_msg);
  Pl_Syntax_Error(Flag_Value(FLAG_SYNTAX_ERROR));
}
예제 #9
0
파일: pred_c.c 프로젝트: adinho/Testing
/*-------------------------------------------------------------------------*
 * PL_CURRENT_PREDICATE_2                                                  *
 *                                                                         *
 *-------------------------------------------------------------------------*/
Bool
Pl_Current_Predicate_2(WamWord pred_indic_word, WamWord which_preds_word)
{
  WamWord name_word, arity_word;
  HashScan scan;
  PredInf *pred;
  int func, arity;
  int func1, arity1;
  int which_preds;		/* 0=user, 1=user+bips, 2=user+bips+system */
  Bool all;

  func = Pl_Get_Pred_Indicator(pred_indic_word, FALSE, &arity);
  name_word = pl_pi_name_word;
  arity_word = pl_pi_arity_word;

  which_preds = Pl_Rd_Integer(which_preds_word);

  if (which_preds == 0 && !Flag_Value(FLAG_STRICT_ISO))
    which_preds = 1;

#define Pred_Is_Ok(pred, func, which_preds) \
  (which_preds == 2 || (pl_atom_tbl[func].name[0] != '$' && \
   (which_preds == 1 || !(pred->prop & MASK_PRED_ANY_BUILTIN))))

  if (func >= 0 && arity >= 0)
    {
      pred = Pl_Lookup_Pred(func, arity);
      return pred && Pred_Is_Ok(pred, func, which_preds);
    }

				/* here func or arity == -1 (or both) */
  all = (func == -1 && arity == -1);

  pred = (PredInf *) Pl_Hash_First(pl_pred_tbl, &scan);
  for (;;)
    {
      if (pred == NULL)
	return FALSE;

      func1 = Functor_Of(pred->f_n);
      arity1 = Arity_Of(pred->f_n);

      if ((all || func == func1 || arity == arity1) &&
	  Pred_Is_Ok(pred, func1, which_preds))
	break;

      pred = (PredInf *) Pl_Hash_Next(&scan);
    }

				/* non deterministic case */
  A(0) = name_word;
  A(1) = arity_word;
  A(2) = which_preds;
  A(3) = (WamWord) scan.endt;
  A(4) = (WamWord) scan.cur_t;
  A(5) = (WamWord) scan.cur_p;
  Pl_Create_Choice_Point((CodePtr) Prolog_Predicate(CURRENT_PREDICATE_ALT, 0),
		      6);
  return Pl_Get_Atom(Functor_Of(pred->f_n), name_word) &&
    Pl_Get_Integer(Arity_Of(pred->f_n), arity_word);
  /*
  return Pl_Un_Atom_Check(Functor_Of(pred->f_n), name_word) &&
    Pl_Un_Integer_Check(Arity_Of(pred->f_n), arity_word);
  */
}