2001-04-09 20:54:03 +01:00
|
|
|
|
/*************************************************************************
|
|
|
|
|
* *
|
|
|
|
|
* YAP Prolog *
|
|
|
|
|
* *
|
|
|
|
|
* Yap Prolog was developed at NCCUP - Universidade do Porto *
|
|
|
|
|
* *
|
2003-01-22 17:23:18 +00:00
|
|
|
|
* Copyright L.Damas, V.S.Costa and Universidade do Porto 1985-2003 *
|
2001-04-09 20:54:03 +01:00
|
|
|
|
* *
|
|
|
|
|
**************************************************************************
|
|
|
|
|
* *
|
|
|
|
|
* File: %W% %G% *
|
2003-01-22 17:23:18 +00:00
|
|
|
|
* Last rev: 22-1-03 *
|
2001-04-09 20:54:03 +01:00
|
|
|
|
* mods: *
|
|
|
|
|
* comments: Prolog's scanner *
|
|
|
|
|
* *
|
|
|
|
|
*************************************************************************/
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
* Description:
|
|
|
|
|
*
|
|
|
|
|
* This module produces a list of tokens for use by the parser. The calling
|
|
|
|
|
* program should supply a routine int nextch(charpos) int *charpos; which,
|
|
|
|
|
* when called should produce the next char or -1 if none availlable. The
|
|
|
|
|
* scanner will stop producing tokens when it either finds an end of file
|
|
|
|
|
* (-1) or a token consisting of just '.' followed by a blank or control
|
|
|
|
|
* char. Scanner errors will be signalled by the scanner exiting with a non-
|
|
|
|
|
* zero ErrorMsg and ErrorPos. Note that, even in this case, the scanner
|
|
|
|
|
* will try to find the end of the term. A function char
|
|
|
|
|
* *AllocScannerMemory(nbytes) should be supplied for allocating (temporary)
|
|
|
|
|
* space for strings and for the table of prolog variables occurring in the
|
|
|
|
|
* term.
|
|
|
|
|
*
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
#include "Yap.h"
|
|
|
|
|
#include "Yatom.h"
|
2009-10-23 14:22:17 +01:00
|
|
|
|
#include "YapHeap.h"
|
2011-02-15 07:39:27 +00:00
|
|
|
|
#include "SWI-Stream.h"
|
2001-04-09 20:54:03 +01:00
|
|
|
|
#include "yapio.h"
|
|
|
|
|
#include "alloc.h"
|
|
|
|
|
#include "eval.h"
|
2002-08-28 15:02:35 +01:00
|
|
|
|
#if _MSC_VER || defined(__MINGW32__)
|
|
|
|
|
#if HAVE_FINITE==1
|
|
|
|
|
#undef HAVE_FINITE
|
|
|
|
|
#endif
|
|
|
|
|
#include <windows.h>
|
|
|
|
|
#endif
|
2002-06-17 16:28:01 +01:00
|
|
|
|
#include "iopreds.h"
|
2001-04-09 20:54:03 +01:00
|
|
|
|
#if HAVE_STRING_H
|
|
|
|
|
#include <string.h>
|
|
|
|
|
#endif
|
2010-05-05 12:51:38 +01:00
|
|
|
|
#if HAVE_WCTYPE_H
|
|
|
|
|
#include <wctype.h>
|
|
|
|
|
#endif
|
2001-04-09 20:54:03 +01:00
|
|
|
|
|
|
|
|
|
/* You just can't trust some machines */
|
2007-12-29 12:26:41 +00:00
|
|
|
|
#define my_isxdigit(C,SU,SL) (chtype(C) == NU || (C >= 'A' && \
|
2001-04-09 20:54:03 +01:00
|
|
|
|
C <= (SU)) || (C >= 'a' && C <= (SL)))
|
|
|
|
|
#define my_isupper(C) ( C >= 'A' && C <= 'Z' )
|
2003-01-08 16:45:35 +00:00
|
|
|
|
#define my_islower(C) ( C >= 'a' && C <= 'z' )
|
2001-04-09 20:54:03 +01:00
|
|
|
|
|
2009-01-12 15:08:26 +00:00
|
|
|
|
STATIC_PROTO(Term float_send, (char *, int));
|
2011-02-15 07:39:27 +00:00
|
|
|
|
STATIC_PROTO(Term get_num, (int *, int *, IOSTREAM *,char *,UInt,int));
|
2001-04-09 20:54:03 +01:00
|
|
|
|
|
|
|
|
|
/* token table with some help from Richard O'Keefe's PD scanner */
|
|
|
|
|
static char chtype0[NUMBER_OF_CHARS+1] =
|
|
|
|
|
{
|
|
|
|
|
EF,
|
|
|
|
|
/* nul soh stx etx eot enq ack bel bs ht nl vt np cr so si */
|
|
|
|
|
BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS,
|
|
|
|
|
|
|
|
|
|
/* dle dc1 dc2 dc3 dc4 nak syn etb can em sub esc fs gs rs us */
|
|
|
|
|
BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS,
|
|
|
|
|
|
|
|
|
|
/* sp ! " # $ % & ' ( ) * + , - . / */
|
|
|
|
|
BS, SL, DC, SY, LC, CC, SY, QT, BK, BK, SY, SY, BK, SY, SY, SY,
|
|
|
|
|
|
|
|
|
|
/* 0 1 2 3 4 5 6 7 8 9 : ; < = > ? */
|
|
|
|
|
NU, NU, NU, NU, NU, NU, NU, NU, NU, NU, SY, SL, SY, SY, SY, SY,
|
|
|
|
|
|
|
|
|
|
/* @ A B C D E F G H I J K L M N O */
|
|
|
|
|
SY, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC,
|
|
|
|
|
|
|
|
|
|
/* P Q R S T U V W X Y Z [ \ ] ^ _ */
|
|
|
|
|
UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, BK, SY, BK, SY, UL,
|
|
|
|
|
|
|
|
|
|
/* ` a b c d e f g h i j k l m n o */
|
|
|
|
|
SY, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC,
|
|
|
|
|
|
|
|
|
|
/* p q r s t u v w x y z { | } ~ del */
|
|
|
|
|
LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, BK, BK, BK, SY, BS,
|
|
|
|
|
|
|
|
|
|
/* 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 */
|
|
|
|
|
BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS,
|
|
|
|
|
|
|
|
|
|
/* 144 145 <20> 147 148 149 150 151 152 153 154 155 156 157 158 159 */
|
|
|
|
|
BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS, BS,
|
|
|
|
|
|
|
|
|
|
/* <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> */
|
|
|
|
|
BS, SY, SY, SY, SY, SY, SY, SY, SY, SY, LC, SY, SY, SY, SY, SY,
|
|
|
|
|
|
|
|
|
|
/* <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> */
|
|
|
|
|
SY, SY, LC, LC, SY, SY, SY, SY, SY, LC, LC, SY, SY, SY, SY, SY,
|
|
|
|
|
|
|
|
|
|
/* <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> */
|
|
|
|
|
UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC,
|
|
|
|
|
|
|
|
|
|
/* <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> */
|
|
|
|
|
#ifdef vms
|
|
|
|
|
UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, UC, LC,
|
|
|
|
|
#else
|
|
|
|
|
UC, UC, UC, UC, UC, UC, UC, SY, UC, UC, UC, UC, UC, UC, UC, LC,
|
|
|
|
|
#endif
|
|
|
|
|
/* <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> */
|
|
|
|
|
LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC,
|
|
|
|
|
|
2002-01-23 05:01:06 +00:00
|
|
|
|
/* <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> <20> cannot write the last three because of lcc */
|
2001-04-09 20:54:03 +01:00
|
|
|
|
#ifdef vms
|
|
|
|
|
LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC, LC
|
|
|
|
|
#else
|
|
|
|
|
LC, LC, LC, LC, LC, LC, LC, SY, LC, LC, LC, LC, LC, LC, LC, LC
|
|
|
|
|
#endif
|
|
|
|
|
};
|
|
|
|
|
|
2010-05-05 12:45:11 +01:00
|
|
|
|
|
2002-11-18 18:18:05 +00:00
|
|
|
|
char *Yap_chtype = chtype0+1;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
|
2010-05-05 12:45:11 +01:00
|
|
|
|
int
|
|
|
|
|
Yap_wide_chtype(Int ch) {
|
2010-05-05 12:51:38 +01:00
|
|
|
|
#if HAVE_WCTYPE_H
|
2010-05-05 12:45:11 +01:00
|
|
|
|
if (iswalnum(ch)) {
|
|
|
|
|
if (iswlower(ch)) return LC;
|
|
|
|
|
if (iswdigit(ch)) return NU;
|
|
|
|
|
return UC;
|
|
|
|
|
}
|
|
|
|
|
if (iswpunct(ch)) return SY;
|
2010-05-05 12:51:38 +01:00
|
|
|
|
#endif
|
2010-05-05 12:45:11 +01:00
|
|
|
|
return BS;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2011-02-15 07:39:27 +00:00
|
|
|
|
static inline int
|
|
|
|
|
getchr__(IOSTREAM *inp)
|
|
|
|
|
{ int c = Sgetcode(inp);
|
|
|
|
|
|
|
|
|
|
if ( !CharConversionTable || c < 0 || c >= 256 )
|
|
|
|
|
return c;
|
|
|
|
|
|
|
|
|
|
return CharConversionTable[c];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
#define getchr(inp) getchr__(inp)
|
|
|
|
|
#define getchrq(inp) Sgetcode(inp)
|
|
|
|
|
|
|
|
|
|
EXTERN inline int
|
|
|
|
|
GetCurInpPos (IOSTREAM *inp_stream)
|
|
|
|
|
{
|
|
|
|
|
return inp_stream->posbuf.lineno;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
2010-05-05 12:45:11 +01:00
|
|
|
|
|
2004-12-28 22:20:37 +00:00
|
|
|
|
/* in case there is an overflow */
|
|
|
|
|
typedef struct scanner_extra_alloc {
|
|
|
|
|
struct scanner_extra_alloc *next;
|
|
|
|
|
void *filler;
|
|
|
|
|
} ScannerExtraBlock;
|
|
|
|
|
|
2002-11-11 17:38:10 +00:00
|
|
|
|
static char *
|
2001-04-09 20:54:03 +01:00
|
|
|
|
AllocScannerMemory(unsigned int size)
|
|
|
|
|
{
|
2011-03-07 16:02:55 +00:00
|
|
|
|
CACHE_REGS
|
2001-04-09 20:54:03 +01:00
|
|
|
|
char *AuxSpScan;
|
|
|
|
|
|
2004-10-28 21:12:23 +01:00
|
|
|
|
AuxSpScan = ScannerStack;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
size = AdjustSize(size);
|
2004-12-28 22:20:37 +00:00
|
|
|
|
if (ScannerExtraBlocks) {
|
|
|
|
|
struct scanner_extra_alloc *ptr;
|
|
|
|
|
|
|
|
|
|
if (!(ptr = (struct scanner_extra_alloc *)malloc(size+sizeof(ScannerExtraBlock)))) {
|
2004-11-22 22:28:06 +00:00
|
|
|
|
return NULL;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
}
|
2004-12-28 22:20:37 +00:00
|
|
|
|
ptr->next = ScannerExtraBlocks;
|
|
|
|
|
ScannerExtraBlocks = ptr;
|
|
|
|
|
return (char *)(ptr+1);
|
|
|
|
|
} else if (Yap_TrailTop <= AuxSpScan+size) {
|
2010-05-11 12:25:49 +01:00
|
|
|
|
UInt alloc_size = sizeof(CELL) * K16;
|
2004-12-28 22:20:37 +00:00
|
|
|
|
|
|
|
|
|
if (size > alloc_size)
|
|
|
|
|
alloc_size = size;
|
2006-04-28 17:14:05 +01:00
|
|
|
|
if(!Yap_growtrail(alloc_size, TRUE)) {
|
2004-12-28 22:20:37 +00:00
|
|
|
|
struct scanner_extra_alloc *ptr;
|
|
|
|
|
|
|
|
|
|
if (!(ptr = (struct scanner_extra_alloc *)malloc(size+sizeof(ScannerExtraBlock)))) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
ptr->next = ScannerExtraBlocks;
|
|
|
|
|
ScannerExtraBlocks = ptr;
|
|
|
|
|
return (char *)(ptr+1);
|
|
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
|
}
|
2004-12-28 22:20:37 +00:00
|
|
|
|
ScannerStack = AuxSpScan+size;
|
2004-10-28 21:12:23 +01:00
|
|
|
|
return AuxSpScan;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
2004-12-28 22:20:37 +00:00
|
|
|
|
static void
|
|
|
|
|
PopScannerMemory(char *block, unsigned int size)
|
|
|
|
|
{
|
2011-03-07 16:02:55 +00:00
|
|
|
|
CACHE_REGS
|
2004-12-28 22:20:37 +00:00
|
|
|
|
if (block == ScannerStack-size) {
|
|
|
|
|
ScannerStack -= size;
|
|
|
|
|
} else if (block == (char *)(ScannerExtraBlocks+1)) {
|
|
|
|
|
struct scanner_extra_alloc *ptr = ScannerExtraBlocks;
|
|
|
|
|
|
|
|
|
|
ScannerExtraBlocks = ptr->next;
|
|
|
|
|
free(ptr);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2002-11-11 17:38:10 +00:00
|
|
|
|
char *
|
2002-11-18 18:18:05 +00:00
|
|
|
|
Yap_AllocScannerMemory(unsigned int size)
|
2002-11-11 17:38:10 +00:00
|
|
|
|
{
|
2004-10-28 21:12:23 +01:00
|
|
|
|
/* I assume memory has been initialised */
|
2002-11-11 17:38:10 +00:00
|
|
|
|
return AllocScannerMemory(size);
|
|
|
|
|
}
|
|
|
|
|
|
2001-04-09 20:54:03 +01:00
|
|
|
|
extern double atof(const char *);
|
|
|
|
|
|
|
|
|
|
static Term
|
2009-01-12 15:08:26 +00:00
|
|
|
|
float_send(char *s, int sign)
|
2001-04-09 20:54:03 +01:00
|
|
|
|
{
|
|
|
|
|
Float f = (Float)atof(s);
|
|
|
|
|
#if HAVE_FINITE
|
|
|
|
|
if (yap_flags[LANGUAGE_MODE_FLAG] == 1) { /* iso */
|
|
|
|
|
if (!finite(f)) {
|
2011-03-07 16:02:55 +00:00
|
|
|
|
CACHE_REGS
|
2002-11-18 18:18:05 +00:00
|
|
|
|
Yap_ErrorMessage = "Float overflow while scanning";
|
2001-04-09 20:54:03 +01:00
|
|
|
|
return(MkEvalFl(0.0));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
#endif
|
2009-01-12 15:08:26 +00:00
|
|
|
|
return (MkEvalFl(f*sign));
|
2001-04-09 20:54:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* we have an overflow at s */
|
|
|
|
|
static Term
|
2009-01-12 15:08:26 +00:00
|
|
|
|
read_int_overflow(const char *s, Int base, Int val, int sign)
|
2001-04-09 20:54:03 +01:00
|
|
|
|
{
|
|
|
|
|
#ifdef USE_GMP
|
|
|
|
|
/* try to scan it as a bignum */
|
2006-01-02 02:16:19 +00:00
|
|
|
|
mpz_t new;
|
|
|
|
|
Term t;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
|
|
|
|
|
mpz_init_set_str (new, s, base);
|
2009-01-12 15:08:26 +00:00
|
|
|
|
if (sign < 0)
|
|
|
|
|
mpz_neg(new, new);
|
2006-01-02 02:16:19 +00:00
|
|
|
|
t = Yap_MkBigIntTerm(new);
|
2006-01-18 15:34:54 +00:00
|
|
|
|
mpz_clear(new);
|
2006-01-02 02:16:19 +00:00
|
|
|
|
return t;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
#else
|
|
|
|
|
/* try to scan it as a float */
|
2006-01-16 02:57:52 +00:00
|
|
|
|
return MkIntegerTerm(val);
|
2001-04-09 20:54:03 +01:00
|
|
|
|
#endif
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-07 16:02:55 +00:00
|
|
|
|
static int
|
|
|
|
|
send_error_message(char s[])
|
|
|
|
|
{
|
|
|
|
|
CACHE_REGS
|
|
|
|
|
Yap_ErrorMessage = s;
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
2011-02-15 07:39:27 +00:00
|
|
|
|
|
2006-11-27 17:42:03 +00:00
|
|
|
|
static wchar_t
|
2011-02-15 07:39:27 +00:00
|
|
|
|
read_quoted_char(int *scan_nextp, IOSTREAM *inp_stream)
|
2003-01-08 16:45:35 +00:00
|
|
|
|
{
|
|
|
|
|
int ch;
|
|
|
|
|
|
|
|
|
|
/* escape sequence */
|
|
|
|
|
restart:
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchrq(inp_stream);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
switch (ch) {
|
|
|
|
|
case 10:
|
2010-06-23 11:46:16 +01:00
|
|
|
|
do {
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchrq(inp_stream);
|
2010-06-23 11:46:16 +01:00
|
|
|
|
if (ch == '\\') goto restart;
|
|
|
|
|
if (chtype(ch) != BS || ch == 10) {
|
|
|
|
|
return ch;
|
|
|
|
|
}
|
|
|
|
|
} while (TRUE);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
case 'a':
|
|
|
|
|
return '\a';
|
|
|
|
|
case 'b':
|
|
|
|
|
return '\b';
|
|
|
|
|
case 'c':
|
|
|
|
|
if (yap_flags[CHARACTER_ESCAPE_FLAG] == ISO_CHARACTER_ESCAPES) {
|
2011-03-07 16:02:55 +00:00
|
|
|
|
return send_error_message("invalid escape sequence \\c");
|
2003-01-08 16:45:35 +00:00
|
|
|
|
} else {
|
|
|
|
|
/* sicstus */
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchrq(inp_stream);
|
2007-12-29 12:26:41 +00:00
|
|
|
|
if (chtype(ch) == SL) {
|
2003-01-08 16:45:35 +00:00
|
|
|
|
goto restart;
|
|
|
|
|
} else {
|
|
|
|
|
return 'c';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
case 'd':
|
|
|
|
|
return 127;
|
|
|
|
|
case 'e':
|
2003-01-22 17:23:18 +00:00
|
|
|
|
return '\x1B'; /* <ESC>, a.k.a. \e */
|
2003-01-08 16:45:35 +00:00
|
|
|
|
case 'f':
|
|
|
|
|
return '\f';
|
|
|
|
|
case 'n':
|
|
|
|
|
return '\n';
|
|
|
|
|
case 'r':
|
|
|
|
|
return '\r';
|
|
|
|
|
case 't':
|
|
|
|
|
return '\t';
|
2006-11-27 17:42:03 +00:00
|
|
|
|
case 'u':
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
wchar_t wc='\0';
|
|
|
|
|
|
|
|
|
|
for (i=0; i< 4; i++) {
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchrq(inp_stream);
|
2006-11-27 17:42:03 +00:00
|
|
|
|
if (ch>='0' && ch <= '9') {
|
|
|
|
|
wc += (ch-'0')<<((3-i)*4);
|
|
|
|
|
} else if (ch>='a' && ch <= 'f') {
|
|
|
|
|
wc += ((ch-'a')+10)<<((3-i)*4);
|
|
|
|
|
} else if (ch>='A' && ch <= 'F') {
|
|
|
|
|
wc += ((ch-'A')+10)<<((3-i)*4);
|
|
|
|
|
} else {
|
2011-03-07 16:02:55 +00:00
|
|
|
|
return send_error_message("invalid escape sequence");
|
2006-11-27 17:42:03 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return wc;
|
|
|
|
|
}
|
|
|
|
|
case 'U':
|
|
|
|
|
{
|
|
|
|
|
int i;
|
|
|
|
|
wchar_t wc='\0';
|
|
|
|
|
|
|
|
|
|
for (i=0; i< 8; i++) {
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchrq(inp_stream);
|
2006-11-27 17:42:03 +00:00
|
|
|
|
if (ch>='0' && ch <= '9') {
|
|
|
|
|
wc += (ch-'0')<<((7-i)*4);
|
|
|
|
|
} else if (ch>='a' && ch <= 'f') {
|
|
|
|
|
wc += ((ch-'a')+10)<<((7-i)*4);
|
|
|
|
|
} else if (ch>='A' && ch <= 'F') {
|
|
|
|
|
wc += ((ch-'A')+10)<<((7-i)*4);
|
|
|
|
|
} else {
|
2011-03-07 16:02:55 +00:00
|
|
|
|
return send_error_message("invalid escape sequence");
|
2006-11-27 17:42:03 +00:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return wc;
|
|
|
|
|
}
|
2003-01-08 16:45:35 +00:00
|
|
|
|
case 'v':
|
|
|
|
|
return '\v';
|
|
|
|
|
case '\\':
|
|
|
|
|
return '\\';
|
|
|
|
|
case '\'':
|
|
|
|
|
return '\'';
|
|
|
|
|
case '"':
|
|
|
|
|
return '"';
|
|
|
|
|
case '`':
|
|
|
|
|
return '`';
|
|
|
|
|
case '^':
|
|
|
|
|
if (yap_flags[CHARACTER_ESCAPE_FLAG] == ISO_CHARACTER_ESCAPES) {
|
2011-03-07 16:02:55 +00:00
|
|
|
|
return send_error_message("invalid escape sequence");
|
2003-01-08 16:45:35 +00:00
|
|
|
|
} else {
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchrq(inp_stream);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
if (ch == '?') {/* delete character */
|
|
|
|
|
return 127;
|
2011-03-14 20:37:17 +00:00
|
|
|
|
} else if (ch >= 'a' && ch < 'z') {/* hexa */
|
2003-01-08 16:45:35 +00:00
|
|
|
|
return ch - 'a';
|
2011-03-14 20:37:17 +00:00
|
|
|
|
} else if (ch >= 'A' && ch < 'Z') {/* hexa */
|
2003-01-08 16:45:35 +00:00
|
|
|
|
return ch - 'A';
|
|
|
|
|
} else {
|
|
|
|
|
return '^';
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
case '0':
|
|
|
|
|
case '1':
|
|
|
|
|
case '2':
|
|
|
|
|
case '3':
|
|
|
|
|
case '4':
|
|
|
|
|
case '5':
|
|
|
|
|
case '6':
|
|
|
|
|
case '7':
|
|
|
|
|
/* character in octal: maximum of 3 digits, terminates with \ */
|
2011-03-14 20:37:17 +00:00
|
|
|
|
/* follow ISO */
|
|
|
|
|
if (TRUE || yap_flags[CHARACTER_ESCAPE_FLAG] == ISO_CHARACTER_ESCAPES) {
|
2003-01-08 16:45:35 +00:00
|
|
|
|
unsigned char so_far = ch-'0';
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchrq(inp_stream);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
if (ch >= '0' && ch < '8') {/* octal */
|
|
|
|
|
so_far = so_far*8+(ch-'0');
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchrq(inp_stream);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
if (ch >= '0' && ch < '8') { /* octal */
|
|
|
|
|
so_far = so_far*8+(ch-'0');
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchrq(inp_stream);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
if (ch != '\\') {
|
2011-03-07 16:02:55 +00:00
|
|
|
|
return send_error_message("invalid octal escape sequence");
|
2003-01-08 16:45:35 +00:00
|
|
|
|
}
|
2011-03-14 20:37:17 +00:00
|
|
|
|
return so_far;
|
2003-01-08 16:45:35 +00:00
|
|
|
|
} else if (ch == '\\') {
|
|
|
|
|
return so_far;
|
|
|
|
|
} else {
|
2011-03-07 16:02:55 +00:00
|
|
|
|
return send_error_message("invalid octal escape sequence");
|
2003-01-08 16:45:35 +00:00
|
|
|
|
}
|
|
|
|
|
} else if (ch == '\\') {
|
|
|
|
|
return so_far;
|
|
|
|
|
} else {
|
2011-03-07 16:02:55 +00:00
|
|
|
|
return send_error_message("invalid octal escape sequence");
|
2003-01-08 16:45:35 +00:00
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
/* sicstus */
|
|
|
|
|
unsigned char so_far = ch-'0';
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchrq(inp_stream);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
if (ch >= '0' && ch < '8') {/* octal */
|
|
|
|
|
so_far = so_far*8+(ch-'0');
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchrq(inp_stream);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
if (ch >= '0' && ch < '8') { /* octal */
|
|
|
|
|
return so_far*8+(ch-'0');
|
|
|
|
|
} else {
|
|
|
|
|
*scan_nextp = FALSE;
|
|
|
|
|
return so_far;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
*scan_nextp = FALSE;
|
|
|
|
|
return so_far;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
case 'x':
|
|
|
|
|
/* hexadecimal character (YAP allows empty hexadecimal */
|
|
|
|
|
if (yap_flags[CHARACTER_ESCAPE_FLAG] == ISO_CHARACTER_ESCAPES) {
|
|
|
|
|
unsigned char so_far = 0;
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchrq(inp_stream);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
if (my_isxdigit(ch,'f','F')) {/* hexa */
|
2007-12-29 12:26:41 +00:00
|
|
|
|
so_far = so_far * 16 + (chtype(ch) == NU ? ch - '0' :
|
2003-01-08 16:45:35 +00:00
|
|
|
|
(my_isupper(ch) ? ch - 'A' : ch - 'a') + 10);
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchrq(inp_stream);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
if (my_isxdigit(ch,'f','F')) { /* hexa */
|
2007-12-29 12:26:41 +00:00
|
|
|
|
so_far = so_far * 16 + (chtype(ch) == NU ? ch - '0' :
|
2003-01-08 16:45:35 +00:00
|
|
|
|
(my_isupper(ch) ? ch - 'A' : ch - 'a') + 10);
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchrq(inp_stream);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
if (ch == '\\') {
|
|
|
|
|
return so_far;
|
|
|
|
|
} else {
|
2011-03-07 16:02:55 +00:00
|
|
|
|
return send_error_message("invalid hexadecimal escape sequence");
|
2003-01-08 16:45:35 +00:00
|
|
|
|
}
|
|
|
|
|
} else if (ch == '\\') {
|
|
|
|
|
return so_far;
|
|
|
|
|
} else {
|
2011-03-07 16:02:55 +00:00
|
|
|
|
return send_error_message("invalid hexadecimal escape sequence");
|
2003-01-08 16:45:35 +00:00
|
|
|
|
}
|
|
|
|
|
} else if (ch == '\\') {
|
|
|
|
|
return so_far;
|
|
|
|
|
} else {
|
2011-03-07 16:02:55 +00:00
|
|
|
|
return send_error_message("invalid hexadecimal escape sequence");
|
2003-01-08 16:45:35 +00:00
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
/* sicstus mode */
|
|
|
|
|
unsigned char so_far = 0;
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchrq(inp_stream);
|
2007-12-29 12:26:41 +00:00
|
|
|
|
so_far = (chtype(ch) == NU ? ch - '0' :
|
2003-01-08 16:45:35 +00:00
|
|
|
|
my_isupper(ch) ? ch - 'A' + 10 :
|
|
|
|
|
my_islower(ch) ? ch - 'a' +10 : 0);
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchrq(inp_stream);
|
2007-12-29 12:26:41 +00:00
|
|
|
|
return so_far*16 + (chtype(ch) == NU ? ch - '0' :
|
2003-01-08 16:45:35 +00:00
|
|
|
|
my_isupper(ch) ? ch - 'A' +10 :
|
|
|
|
|
my_islower(ch) ? ch - 'a' + 10 : 0);
|
|
|
|
|
}
|
|
|
|
|
default:
|
|
|
|
|
/* accept sequence. Note that the ISO standard does not
|
|
|
|
|
consider this sequence legal, whereas SICStus would
|
|
|
|
|
eat up the escape sequence. */
|
|
|
|
|
if (yap_flags[CHARACTER_ESCAPE_FLAG] == ISO_CHARACTER_ESCAPES) {
|
2011-03-07 16:02:55 +00:00
|
|
|
|
return send_error_message("invalid escape sequence");
|
2003-01-08 16:45:35 +00:00
|
|
|
|
} else {
|
|
|
|
|
/* sicstus */
|
2007-12-29 12:26:41 +00:00
|
|
|
|
if (chtype(ch) == SL) {
|
2003-01-08 16:45:35 +00:00
|
|
|
|
goto restart;
|
|
|
|
|
} else {
|
|
|
|
|
return ch;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2011-03-07 16:02:55 +00:00
|
|
|
|
static int
|
|
|
|
|
num_send_error_message(char s[])
|
|
|
|
|
{
|
|
|
|
|
CACHE_REGS
|
|
|
|
|
Yap_ErrorMessage = s;
|
|
|
|
|
return TermNil;
|
|
|
|
|
}
|
|
|
|
|
|
2001-04-09 20:54:03 +01:00
|
|
|
|
/* reads a number, either integer or float */
|
|
|
|
|
|
2011-03-07 16:02:55 +00:00
|
|
|
|
|
2001-04-09 20:54:03 +01:00
|
|
|
|
static Term
|
2011-02-15 07:39:27 +00:00
|
|
|
|
get_num(int *chp, int *chbuffp, IOSTREAM *inp_stream, char *s, UInt max_size, int sign)
|
2001-04-09 20:54:03 +01:00
|
|
|
|
{
|
2004-12-28 22:20:37 +00:00
|
|
|
|
char *sp = s;
|
2003-01-08 16:45:35 +00:00
|
|
|
|
int ch = *chp;
|
2006-01-26 19:13:24 +00:00
|
|
|
|
Int val = 0L, base = ch - '0';
|
2001-04-09 20:54:03 +01:00
|
|
|
|
int might_be_float = TRUE, has_overflow = FALSE;
|
|
|
|
|
|
|
|
|
|
*sp++ = ch;
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchr(inp_stream);
|
2001-04-09 20:54:03 +01:00
|
|
|
|
/*
|
|
|
|
|
* because of things like 00'2, 03'2 and even better 12'2, I need to
|
|
|
|
|
* do this (have mercy)
|
|
|
|
|
*/
|
2007-12-29 12:26:41 +00:00
|
|
|
|
if (chtype(ch) == NU) {
|
2001-04-09 20:54:03 +01:00
|
|
|
|
*sp++ = ch;
|
2004-11-22 22:28:06 +00:00
|
|
|
|
if (--max_size == 0) {
|
2011-03-07 16:02:55 +00:00
|
|
|
|
return num_send_error_message("Number Too Long");
|
2004-11-22 22:28:06 +00:00
|
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
|
base = 10 * base + ch - '0';
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchr(inp_stream);
|
2001-04-09 20:54:03 +01:00
|
|
|
|
}
|
|
|
|
|
if (ch == '\'') {
|
|
|
|
|
if (base > 36) {
|
2011-03-07 16:02:55 +00:00
|
|
|
|
return num_send_error_message("Admissible bases are 0..36");
|
2001-04-09 20:54:03 +01:00
|
|
|
|
}
|
|
|
|
|
might_be_float = FALSE;
|
2004-11-22 22:28:06 +00:00
|
|
|
|
if (--max_size == 0) {
|
2011-03-07 16:02:55 +00:00
|
|
|
|
return num_send_error_message("Number Too Long");
|
2004-11-22 22:28:06 +00:00
|
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
|
*sp++ = ch;
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchr(inp_stream);
|
2001-04-09 20:54:03 +01:00
|
|
|
|
if (base == 0) {
|
2006-11-27 17:42:03 +00:00
|
|
|
|
wchar_t ascii = ch;
|
2003-01-08 16:45:35 +00:00
|
|
|
|
int scan_extra = TRUE;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
|
2001-04-17 22:07:41 +01:00
|
|
|
|
if (ch == '\\' &&
|
|
|
|
|
yap_flags[CHARACTER_ESCAPE_FLAG] != CPROLOG_CHARACTER_ESCAPES) {
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ascii = read_quoted_char(&scan_extra, inp_stream);
|
2001-04-17 22:07:41 +01:00
|
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
|
/* a quick way to represent ASCII */
|
2003-01-08 16:45:35 +00:00
|
|
|
|
if (scan_extra)
|
2011-02-15 07:39:27 +00:00
|
|
|
|
*chp = getchr(inp_stream);
|
2009-01-12 15:08:26 +00:00
|
|
|
|
if (sign == -1) {
|
|
|
|
|
return MkIntegerTerm(-ascii);
|
|
|
|
|
}
|
2006-11-27 17:42:03 +00:00
|
|
|
|
return MkIntegerTerm(ascii);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
} else if (base >= 10 && base <= 36) {
|
2001-04-09 20:54:03 +01:00
|
|
|
|
int upper_case = 'A' - 11 + base;
|
|
|
|
|
int lower_case = 'a' - 11 + base;
|
|
|
|
|
|
|
|
|
|
while (my_isxdigit(ch, upper_case, lower_case)) {
|
|
|
|
|
Int oval = val;
|
2008-04-03 23:27:29 +01:00
|
|
|
|
int chval = (chtype(ch) == NU ? ch - '0' :
|
|
|
|
|
(my_isupper(ch) ? ch - 'A' : ch - 'a') + 10);
|
2004-11-22 22:28:06 +00:00
|
|
|
|
if (--max_size == 0) {
|
2011-03-07 16:02:55 +00:00
|
|
|
|
return num_send_error_message("Number Too Long");
|
2004-11-22 22:28:06 +00:00
|
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
|
*sp++ = ch;
|
2008-04-03 23:27:29 +01:00
|
|
|
|
val = oval * base + chval;
|
|
|
|
|
if (oval != (val-chval)/base) /* overflow */
|
2001-04-09 20:54:03 +01:00
|
|
|
|
has_overflow = (has_overflow || TRUE);
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchr(inp_stream);
|
2001-04-09 20:54:03 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
2010-11-21 21:55:58 +00:00
|
|
|
|
} else if (ch == 'x' && base == 0) {
|
2001-04-09 20:54:03 +01:00
|
|
|
|
might_be_float = FALSE;
|
2004-11-22 22:28:06 +00:00
|
|
|
|
if (--max_size == 0) {
|
2011-03-07 16:02:55 +00:00
|
|
|
|
return num_send_error_message("Number Too Long");
|
2004-11-22 22:28:06 +00:00
|
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
|
*sp++ = ch;
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchr(inp_stream);
|
2001-04-09 20:54:03 +01:00
|
|
|
|
while (my_isxdigit(ch, 'F', 'f')) {
|
|
|
|
|
Int oval = val;
|
2008-04-03 23:27:29 +01:00
|
|
|
|
int chval = (chtype(ch) == NU ? ch - '0' :
|
|
|
|
|
(my_isupper(ch) ? ch - 'A' : ch - 'a') + 10);
|
2004-11-22 22:28:06 +00:00
|
|
|
|
if (--max_size == 0) {
|
2011-03-07 16:02:55 +00:00
|
|
|
|
return num_send_error_message("Number Too Long");
|
2004-11-22 22:28:06 +00:00
|
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
|
*sp++ = ch;
|
2008-04-03 23:27:29 +01:00
|
|
|
|
val = val * 16 + chval;
|
|
|
|
|
if (oval != (val-chval)/16) /* overflow */
|
|
|
|
|
has_overflow = TRUE;
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchr(inp_stream);
|
2001-04-09 20:54:03 +01:00
|
|
|
|
}
|
2003-01-08 16:45:35 +00:00
|
|
|
|
*chp = ch;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
}
|
2010-11-21 21:55:58 +00:00
|
|
|
|
else if (ch == 'o' && base == 0) {
|
2001-04-09 20:54:03 +01:00
|
|
|
|
might_be_float = FALSE;
|
|
|
|
|
base = 8;
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchr(inp_stream);
|
2010-11-21 21:55:58 +00:00
|
|
|
|
} else if (ch == 'b' && base == 0) {
|
2010-04-18 20:48:25 +01:00
|
|
|
|
might_be_float = FALSE;
|
|
|
|
|
base = 2;
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchr(inp_stream);
|
2010-04-18 20:48:25 +01:00
|
|
|
|
} else {
|
2001-04-09 20:54:03 +01:00
|
|
|
|
val = base;
|
|
|
|
|
base = 10;
|
|
|
|
|
}
|
2007-12-29 12:26:41 +00:00
|
|
|
|
while (chtype(ch) == NU) {
|
2001-04-09 20:54:03 +01:00
|
|
|
|
Int oval = val;
|
2008-04-03 23:27:29 +01:00
|
|
|
|
if (!(val == 0 && ch == '0') || has_overflow) {
|
2004-11-22 22:28:06 +00:00
|
|
|
|
if (--max_size == 0) {
|
2011-03-07 16:02:55 +00:00
|
|
|
|
return num_send_error_message("Number Too Long");
|
2004-11-22 22:28:06 +00:00
|
|
|
|
}
|
2004-02-05 16:57:02 +00:00
|
|
|
|
*sp++ = ch;
|
2004-08-11 17:14:55 +01:00
|
|
|
|
}
|
2009-01-12 15:08:26 +00:00
|
|
|
|
if (ch - '0' >= base) {
|
|
|
|
|
if (sign == -1)
|
|
|
|
|
return MkIntegerTerm(-val);
|
2004-08-11 17:14:55 +01:00
|
|
|
|
return MkIntegerTerm(val);
|
2009-01-12 15:08:26 +00:00
|
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
|
val = val * base + ch - '0';
|
2003-02-24 11:01:01 +00:00
|
|
|
|
if (val/base != oval || val -oval*base != ch-'0') /* overflow */
|
2008-04-03 23:27:29 +01:00
|
|
|
|
has_overflow = TRUE;
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchr(inp_stream);
|
2001-04-09 20:54:03 +01:00
|
|
|
|
}
|
2010-11-22 12:51:02 +00:00
|
|
|
|
if (might_be_float && ( ch == '.' || ch == 'e' || ch == 'E')) {
|
|
|
|
|
if (yap_flags[STRICT_ISO_FLAG] && (ch == 'e' || ch == 'E')) {
|
2011-03-07 16:02:55 +00:00
|
|
|
|
return num_send_error_message("Float format not allowed in ISO mode");
|
2010-11-22 12:51:02 +00:00
|
|
|
|
}
|
|
|
|
|
if (ch == '.') {
|
2004-11-22 22:28:06 +00:00
|
|
|
|
if (--max_size == 0) {
|
2011-03-07 16:02:55 +00:00
|
|
|
|
return num_send_error_message("Number Too Long");
|
2004-11-22 22:28:06 +00:00
|
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
|
*sp++ = '.';
|
2011-02-15 07:39:27 +00:00
|
|
|
|
if (chtype(ch = getchr(inp_stream)) != NU) {
|
2003-01-08 16:45:35 +00:00
|
|
|
|
*chbuffp = '.';
|
|
|
|
|
*chp = ch;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
*--sp = '\0';
|
|
|
|
|
if (has_overflow)
|
2009-01-12 15:08:26 +00:00
|
|
|
|
return read_int_overflow(s,base,val,sign);
|
|
|
|
|
if (sign == -1)
|
|
|
|
|
return MkIntegerTerm(-val);
|
2004-12-28 22:20:37 +00:00
|
|
|
|
return MkIntegerTerm(val);
|
2001-04-09 20:54:03 +01:00
|
|
|
|
}
|
2004-11-22 22:28:06 +00:00
|
|
|
|
do {
|
|
|
|
|
if (--max_size == 0) {
|
2011-03-07 16:02:55 +00:00
|
|
|
|
return num_send_error_message("Number Too Long");
|
2004-11-22 22:28:06 +00:00
|
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
|
*sp++ = ch;
|
2004-11-22 22:28:06 +00:00
|
|
|
|
}
|
2011-02-15 07:39:27 +00:00
|
|
|
|
while (chtype(ch = getchr(inp_stream)) == NU);
|
2001-04-09 20:54:03 +01:00
|
|
|
|
}
|
2010-11-22 12:51:02 +00:00
|
|
|
|
if (ch == 'e' || ch == 'E') {
|
2003-01-08 16:45:35 +00:00
|
|
|
|
char *sp0 = sp;
|
|
|
|
|
char cbuff = ch;
|
2004-11-22 22:28:06 +00:00
|
|
|
|
|
|
|
|
|
if (--max_size == 0) {
|
2011-03-07 16:02:55 +00:00
|
|
|
|
return num_send_error_message("Number Too Long");
|
2004-11-22 22:28:06 +00:00
|
|
|
|
}
|
2003-01-08 16:45:35 +00:00
|
|
|
|
*sp++ = ch;
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchr(inp_stream);
|
2001-04-09 20:54:03 +01:00
|
|
|
|
if (ch == '-') {
|
2003-01-08 16:45:35 +00:00
|
|
|
|
cbuff = '-';
|
2004-11-22 22:28:06 +00:00
|
|
|
|
if (--max_size == 0) {
|
2011-03-07 16:02:55 +00:00
|
|
|
|
return num_send_error_message("Number Too Long");
|
2004-11-22 22:28:06 +00:00
|
|
|
|
}
|
2003-01-08 16:45:35 +00:00
|
|
|
|
*sp++ = '-';
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchr(inp_stream);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
} else if (ch == '+') {
|
|
|
|
|
cbuff = '+';
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchr(inp_stream);
|
2001-04-09 20:54:03 +01:00
|
|
|
|
}
|
2007-12-29 12:26:41 +00:00
|
|
|
|
if (chtype(ch) != NU) {
|
2003-01-08 16:45:35 +00:00
|
|
|
|
/* error */
|
|
|
|
|
char *sp;
|
|
|
|
|
*chp = ch;
|
2010-11-21 21:55:58 +00:00
|
|
|
|
*chbuffp = cbuff;
|
2003-01-08 16:45:35 +00:00
|
|
|
|
*sp0 = '\0';
|
|
|
|
|
for (sp = s; sp < sp0; sp++) {
|
|
|
|
|
if (*sp == '.')
|
2009-01-12 15:08:26 +00:00
|
|
|
|
return float_send(s,sign);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
}
|
2009-01-12 15:08:26 +00:00
|
|
|
|
return MkIntegerTerm(sign*val);
|
2001-04-09 20:54:03 +01:00
|
|
|
|
}
|
2003-01-08 16:45:35 +00:00
|
|
|
|
do {
|
2004-11-22 22:28:06 +00:00
|
|
|
|
if (--max_size == 0) {
|
2011-03-07 16:02:55 +00:00
|
|
|
|
return num_send_error_message("Number Too Long");
|
2004-11-22 22:28:06 +00:00
|
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
|
*sp++ = ch;
|
2011-02-15 07:39:27 +00:00
|
|
|
|
} while (chtype(ch = getchr(inp_stream)) == NU);
|
2001-04-09 20:54:03 +01:00
|
|
|
|
}
|
|
|
|
|
*sp = '\0';
|
2003-01-08 16:45:35 +00:00
|
|
|
|
*chp = ch;
|
2009-01-12 15:08:26 +00:00
|
|
|
|
return float_send(s,sign);
|
2001-04-09 20:54:03 +01:00
|
|
|
|
} else if (has_overflow) {
|
|
|
|
|
*sp = '\0';
|
|
|
|
|
/* skip base */
|
2003-01-08 16:45:35 +00:00
|
|
|
|
*chp = ch;
|
2010-11-21 21:55:58 +00:00
|
|
|
|
if (s[0] == '0' && s[1] == 'x')
|
2009-01-12 15:08:26 +00:00
|
|
|
|
return read_int_overflow(s+2,16,val,sign);
|
2010-11-21 21:55:58 +00:00
|
|
|
|
else if (s[0] == '0' && s[1] == 'o')
|
2010-04-18 20:48:25 +01:00
|
|
|
|
return read_int_overflow(s+2,8,val,sign);
|
2010-11-21 21:55:58 +00:00
|
|
|
|
else if (s[0] == '0' && s[1] == 'b')
|
2010-04-18 20:48:25 +01:00
|
|
|
|
return read_int_overflow(s+2,2,val,sign);
|
2001-04-09 20:54:03 +01:00
|
|
|
|
if (s[1] == '\'')
|
2009-01-12 15:08:26 +00:00
|
|
|
|
return read_int_overflow(s+2,base,val,sign);
|
2001-04-09 20:54:03 +01:00
|
|
|
|
if (s[2] == '\'')
|
2009-01-12 15:08:26 +00:00
|
|
|
|
return read_int_overflow(s+3,base,val,sign);
|
|
|
|
|
return read_int_overflow(s,base,val,sign);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
} else {
|
|
|
|
|
*chp = ch;
|
2009-01-12 15:08:26 +00:00
|
|
|
|
return MkIntegerTerm(val*sign);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
2011-02-15 07:39:27 +00:00
|
|
|
|
/* given a function getchr scan until we either find the number
|
2001-04-09 20:54:03 +01:00
|
|
|
|
or end of file */
|
|
|
|
|
Term
|
2011-02-15 07:39:27 +00:00
|
|
|
|
Yap_scan_num(IOSTREAM *inp)
|
2001-04-09 20:54:03 +01:00
|
|
|
|
{
|
2011-03-07 16:02:55 +00:00
|
|
|
|
CACHE_REGS
|
2001-04-09 20:54:03 +01:00
|
|
|
|
Term out;
|
|
|
|
|
int sign = 1;
|
2007-01-28 14:26:37 +00:00
|
|
|
|
int ch, cherr;
|
2004-12-28 22:20:37 +00:00
|
|
|
|
char *ptr;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
|
2002-11-18 18:18:05 +00:00
|
|
|
|
Yap_ErrorMessage = NULL;
|
2004-10-28 21:12:23 +01:00
|
|
|
|
ScannerStack = (char *)TR;
|
2004-12-28 22:20:37 +00:00
|
|
|
|
ScannerExtraBlocks = NULL;
|
|
|
|
|
if (!(ptr = AllocScannerMemory(4096))) {
|
|
|
|
|
Yap_ErrorMessage = "Trail Overflow";
|
2005-12-17 03:25:39 +00:00
|
|
|
|
Yap_Error_TYPE = OUT_OF_TRAIL_ERROR;
|
2004-12-28 22:20:37 +00:00
|
|
|
|
return TermNil;
|
2004-11-22 22:28:06 +00:00
|
|
|
|
}
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchr(inp);
|
2011-01-20 18:03:38 +00:00
|
|
|
|
while (chtype(ch) == BS) {
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchr(inp);
|
2011-01-20 18:03:38 +00:00
|
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
|
if (ch == '-') {
|
|
|
|
|
sign = -1;
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchr(inp);
|
2001-04-09 20:54:03 +01:00
|
|
|
|
} else if (ch == '+') {
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchr(inp);
|
2001-04-09 20:54:03 +01:00
|
|
|
|
}
|
2007-12-29 12:26:41 +00:00
|
|
|
|
if (chtype(ch) != NU) {
|
2005-11-08 13:51:15 +00:00
|
|
|
|
Yap_clean_tokenizer(NULL, NULL, NULL);
|
|
|
|
|
return TermNil;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
}
|
2006-11-27 17:42:03 +00:00
|
|
|
|
cherr = '\0';
|
2005-12-17 03:25:39 +00:00
|
|
|
|
if (ASP-H < 1024)
|
|
|
|
|
return TermNil;
|
2011-02-15 07:39:27 +00:00
|
|
|
|
out = get_num(&ch, &cherr, inp, ptr, 4096, sign); /* */
|
2004-12-28 22:20:37 +00:00
|
|
|
|
PopScannerMemory(ptr, 4096);
|
2005-11-08 13:51:15 +00:00
|
|
|
|
Yap_clean_tokenizer(NULL, NULL, NULL);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
if (Yap_ErrorMessage != NULL || ch != -1 || cherr)
|
2004-11-18 22:32:40 +00:00
|
|
|
|
return TermNil;
|
2007-01-28 14:26:37 +00:00
|
|
|
|
return out;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
}
|
|
|
|
|
|
2006-11-27 17:42:03 +00:00
|
|
|
|
|
|
|
|
|
static wchar_t *
|
|
|
|
|
ch_to_wide(char *base, char *charp)
|
|
|
|
|
{
|
2011-03-07 16:02:55 +00:00
|
|
|
|
CACHE_REGS
|
2006-11-27 17:42:03 +00:00
|
|
|
|
int n = charp-base, i;
|
|
|
|
|
wchar_t *nb = (wchar_t *)base;
|
|
|
|
|
|
|
|
|
|
if ((nb+n) + 1024 > (wchar_t *)AuxSp) {
|
|
|
|
|
Yap_Error_TYPE = OUT_OF_AUXSPACE_ERROR;
|
|
|
|
|
Yap_ErrorMessage = "Heap Overflow While Scanning: please increase code space (-h)";
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
for (i=n; i > 0; i--) {
|
2011-03-07 22:10:20 +00:00
|
|
|
|
nb[i-1] = (unsigned char)base[i-1];
|
2006-11-27 17:42:03 +00:00
|
|
|
|
}
|
|
|
|
|
return nb+n;
|
|
|
|
|
}
|
|
|
|
|
|
2010-05-05 12:45:11 +01:00
|
|
|
|
#define add_ch_to_buff(ch) \
|
|
|
|
|
if (wcharp) { *wcharp++ = (ch); charp = (char *)wcharp; } \
|
|
|
|
|
else { \
|
|
|
|
|
if (ch > MAX_ISO_LATIN1 && !wcharp) { \
|
|
|
|
|
/* does not fit in ISO-LATIN */ \
|
|
|
|
|
wcharp = ch_to_wide(TokImage, charp); \
|
|
|
|
|
if (!wcharp) goto huge_var_error; \
|
|
|
|
|
*wcharp++ = (ch); charp = (char *)wcharp; \
|
|
|
|
|
} else *charp++ = ch; \
|
|
|
|
|
}
|
|
|
|
|
|
2001-04-09 20:54:03 +01:00
|
|
|
|
TokEntry *
|
2011-02-15 07:39:27 +00:00
|
|
|
|
Yap_tokenizer(IOSTREAM *inp_stream, Term *tposp)
|
2001-04-09 20:54:03 +01:00
|
|
|
|
{
|
2011-03-07 16:02:55 +00:00
|
|
|
|
CACHE_REGS
|
2001-04-09 20:54:03 +01:00
|
|
|
|
TokEntry *t, *l, *p;
|
|
|
|
|
enum TokenKinds kind;
|
|
|
|
|
int solo_flag = TRUE;
|
2007-01-28 14:26:37 +00:00
|
|
|
|
int ch;
|
|
|
|
|
wchar_t *wcharp;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
|
2002-11-18 18:18:05 +00:00
|
|
|
|
Yap_ErrorMessage = NULL;
|
2006-08-07 19:51:44 +01:00
|
|
|
|
Yap_Error_Size = 0;
|
2002-11-18 18:18:05 +00:00
|
|
|
|
Yap_VarTable = NULL;
|
|
|
|
|
Yap_AnonVarTable = NULL;
|
|
|
|
|
Yap_eot_before_eof = FALSE;
|
2004-10-28 21:12:23 +01:00
|
|
|
|
ScannerStack = (char *)TR;
|
2004-12-28 22:20:37 +00:00
|
|
|
|
ScannerExtraBlocks = NULL;
|
2004-11-22 22:28:06 +00:00
|
|
|
|
l = NULL;
|
|
|
|
|
p = NULL; /* Just to make lint happy */
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchr(inp_stream);
|
2008-10-23 22:17:45 +01:00
|
|
|
|
while (chtype(ch) == BS) {
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchr(inp_stream);
|
2008-10-23 22:17:45 +01:00
|
|
|
|
}
|
|
|
|
|
*tposp = Yap_StreamPosition(inp_stream);
|
2011-02-15 14:43:28 +00:00
|
|
|
|
StartLine = inp_stream->posbuf.lineno;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
do {
|
2006-11-27 17:42:03 +00:00
|
|
|
|
wchar_t och;
|
|
|
|
|
int quote, isvar;
|
2003-01-08 16:45:35 +00:00
|
|
|
|
char *charp, *mp;
|
|
|
|
|
unsigned int len;
|
|
|
|
|
char *TokImage = NULL;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
t = (TokEntry *) AllocScannerMemory(sizeof(TokEntry));
|
2003-01-08 16:45:35 +00:00
|
|
|
|
t->TokNext = NULL;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
if (t == NULL) {
|
2004-11-22 22:28:06 +00:00
|
|
|
|
Yap_ErrorMessage = "Trail Overflow";
|
2005-12-17 03:25:39 +00:00
|
|
|
|
Yap_Error_TYPE = OUT_OF_TRAIL_ERROR;
|
2004-11-22 22:28:06 +00:00
|
|
|
|
if (p)
|
2005-12-17 03:25:39 +00:00
|
|
|
|
p->Tok = Ord(kind = eot_tok);
|
2001-04-09 20:54:03 +01:00
|
|
|
|
/* serious error now */
|
2004-11-22 22:28:06 +00:00
|
|
|
|
return l;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
}
|
2005-12-17 03:25:39 +00:00
|
|
|
|
if (!l)
|
2001-04-09 20:54:03 +01:00
|
|
|
|
l = t;
|
|
|
|
|
else
|
|
|
|
|
p->TokNext = t;
|
|
|
|
|
p = t;
|
2003-01-08 16:45:35 +00:00
|
|
|
|
restart:
|
2007-12-29 12:26:41 +00:00
|
|
|
|
while (chtype(ch) == BS) {
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchr(inp_stream);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
}
|
2003-02-14 10:56:56 +00:00
|
|
|
|
t->TokPos = GetCurInpPos(inp_stream);
|
2001-04-09 20:54:03 +01:00
|
|
|
|
|
2007-12-29 12:26:41 +00:00
|
|
|
|
switch (chtype(ch)) {
|
2001-04-09 20:54:03 +01:00
|
|
|
|
|
2003-01-08 16:45:35 +00:00
|
|
|
|
case CC:
|
2011-02-15 07:39:27 +00:00
|
|
|
|
while ((ch = getchr(inp_stream)) != 10 && chtype(ch) != EF);
|
2007-12-29 12:26:41 +00:00
|
|
|
|
if (chtype(ch) != EF) {
|
2003-01-08 16:45:35 +00:00
|
|
|
|
/* blank space */
|
2008-10-23 22:17:45 +01:00
|
|
|
|
if (t == l) {
|
|
|
|
|
/* we found a comment before reading characters */
|
|
|
|
|
while (chtype(ch) == BS) {
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchr(inp_stream);
|
2008-10-23 22:17:45 +01:00
|
|
|
|
}
|
|
|
|
|
*tposp = Yap_StreamPosition(inp_stream);
|
|
|
|
|
}
|
2003-01-08 16:45:35 +00:00
|
|
|
|
goto restart;
|
|
|
|
|
} else {
|
|
|
|
|
t->Tok = Ord(kind = eot_tok);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case UC:
|
|
|
|
|
case UL:
|
|
|
|
|
case LC:
|
|
|
|
|
och = ch;
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchr(inp_stream);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
scan_name:
|
|
|
|
|
TokImage = ((AtomEntry *) ( Yap_PreAllocCodeSpace()))->StrOfAE;
|
|
|
|
|
charp = TokImage;
|
2010-05-05 12:45:11 +01:00
|
|
|
|
wcharp = NULL;
|
2007-12-29 12:26:41 +00:00
|
|
|
|
isvar = (chtype(och) != LC);
|
2010-05-05 12:45:11 +01:00
|
|
|
|
add_ch_to_buff(och);
|
2011-02-15 07:39:27 +00:00
|
|
|
|
for (; chtype(ch) <= NU; ch = getchr(inp_stream)) {
|
2005-12-17 03:25:39 +00:00
|
|
|
|
if (charp == (char *)AuxSp-1024) {
|
2008-02-07 23:09:13 +00:00
|
|
|
|
huge_var_error:
|
2005-12-17 03:25:39 +00:00
|
|
|
|
/* huge atom or variable, we are in trouble */
|
|
|
|
|
Yap_ErrorMessage = "Code Space Overflow due to huge atom";
|
|
|
|
|
Yap_Error_TYPE = OUT_OF_AUXSPACE_ERROR;
|
2006-02-01 13:58:30 +00:00
|
|
|
|
Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage);
|
2005-12-17 03:25:39 +00:00
|
|
|
|
if (p)
|
|
|
|
|
p->Tok = Ord(kind = eot_tok);
|
|
|
|
|
/* serious error now */
|
|
|
|
|
return l;
|
|
|
|
|
}
|
2010-05-05 12:45:11 +01:00
|
|
|
|
add_ch_to_buff(ch);
|
2005-12-17 03:25:39 +00:00
|
|
|
|
}
|
2008-02-07 23:09:13 +00:00
|
|
|
|
while (ch == '\'' && isvar && yap_flags[VARS_CAN_HAVE_QUOTE_FLAG]) {
|
|
|
|
|
if (charp == (char *)AuxSp-1024) {
|
|
|
|
|
goto huge_var_error;
|
|
|
|
|
}
|
2010-05-05 12:45:11 +01:00
|
|
|
|
add_ch_to_buff(ch);
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchr(inp_stream);
|
2008-02-07 23:09:13 +00:00
|
|
|
|
}
|
2010-05-05 12:45:11 +01:00
|
|
|
|
add_ch_to_buff('\0');
|
2003-01-08 16:45:35 +00:00
|
|
|
|
if (!isvar) {
|
2010-05-05 12:45:11 +01:00
|
|
|
|
Atom ae;
|
2003-01-08 16:45:35 +00:00
|
|
|
|
/* don't do this in iso */
|
2010-05-05 12:45:11 +01:00
|
|
|
|
if (wcharp) {
|
|
|
|
|
ae = Yap_LookupWideAtom((wchar_t *)TokImage);
|
|
|
|
|
} else {
|
|
|
|
|
ae = Yap_LookupAtom(TokImage);
|
|
|
|
|
}
|
2005-03-01 22:25:09 +00:00
|
|
|
|
if (ae == NIL) {
|
2006-02-01 13:58:30 +00:00
|
|
|
|
Yap_Error_TYPE = OUT_OF_HEAP_ERROR;
|
2005-03-01 22:25:09 +00:00
|
|
|
|
Yap_ErrorMessage = "Code Space Overflow";
|
|
|
|
|
if (p)
|
2005-12-17 03:25:39 +00:00
|
|
|
|
t->Tok = Ord(kind = eot_tok);
|
2005-03-01 22:25:09 +00:00
|
|
|
|
/* serious error now */
|
|
|
|
|
return l;
|
|
|
|
|
}
|
|
|
|
|
t->TokInfo = Unsigned(ae);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage);
|
|
|
|
|
if (ch == '(')
|
|
|
|
|
solo_flag = FALSE;
|
|
|
|
|
t->Tok = Ord(kind = Name_tok);
|
|
|
|
|
} else {
|
|
|
|
|
t->TokInfo = Unsigned(Yap_LookupVar(TokImage));
|
|
|
|
|
Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage);
|
|
|
|
|
t->Tok = Ord(kind = Var_tok);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case NU:
|
|
|
|
|
{
|
2007-01-28 14:26:37 +00:00
|
|
|
|
int cherr;
|
|
|
|
|
int cha = ch;
|
2004-12-28 22:20:37 +00:00
|
|
|
|
char *ptr;
|
|
|
|
|
|
2003-01-08 16:45:35 +00:00
|
|
|
|
cherr = 0;
|
2004-12-28 22:20:37 +00:00
|
|
|
|
if (!(ptr = AllocScannerMemory(4096))) {
|
|
|
|
|
Yap_ErrorMessage = "Trail Overflow";
|
2005-12-17 03:25:39 +00:00
|
|
|
|
Yap_Error_TYPE = OUT_OF_TRAIL_ERROR;
|
2004-12-28 22:20:37 +00:00
|
|
|
|
if (p)
|
2005-12-17 03:25:39 +00:00
|
|
|
|
t->Tok = Ord(kind = eot_tok);
|
|
|
|
|
/* serious error now */
|
|
|
|
|
return l;
|
|
|
|
|
}
|
2006-03-03 23:11:30 +00:00
|
|
|
|
if (ASP-H < 1024) {
|
2005-12-17 03:25:39 +00:00
|
|
|
|
Yap_ErrorMessage = "Stack Overflow";
|
|
|
|
|
Yap_Error_TYPE = OUT_OF_STACK_ERROR;
|
2006-08-07 19:51:44 +01:00
|
|
|
|
Yap_Error_Size = 0L;
|
2005-12-17 03:25:39 +00:00
|
|
|
|
if (p)
|
|
|
|
|
p->Tok = Ord(kind = eot_tok);
|
2004-12-28 22:20:37 +00:00
|
|
|
|
/* serious error now */
|
|
|
|
|
return l;
|
2004-11-22 22:28:06 +00:00
|
|
|
|
}
|
2011-02-15 07:39:27 +00:00
|
|
|
|
if ((t->TokInfo = get_num(&cha,&cherr,inp_stream,ptr,4096,1)) == 0L) {
|
2006-03-03 23:11:30 +00:00
|
|
|
|
if (p)
|
|
|
|
|
p->Tok = Ord(kind = eot_tok);
|
|
|
|
|
/* serious error now */
|
|
|
|
|
return l;
|
|
|
|
|
}
|
2004-12-28 22:20:37 +00:00
|
|
|
|
PopScannerMemory(ptr, 4096);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
ch = cha;
|
|
|
|
|
if (cherr) {
|
|
|
|
|
TokEntry *e;
|
|
|
|
|
t->Tok = Number_tok;
|
2003-02-14 10:56:56 +00:00
|
|
|
|
t->TokPos = GetCurInpPos(inp_stream);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
e = (TokEntry *) AllocScannerMemory(sizeof(TokEntry));
|
|
|
|
|
if (e == NULL) {
|
2004-11-22 22:28:06 +00:00
|
|
|
|
Yap_ErrorMessage = "Trail Overflow";
|
2005-12-17 03:25:39 +00:00
|
|
|
|
Yap_Error_TYPE = OUT_OF_TRAIL_ERROR;
|
2004-11-22 22:28:06 +00:00
|
|
|
|
if (p)
|
2005-12-17 03:25:39 +00:00
|
|
|
|
p->Tok = Ord(kind = eot_tok);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
/* serious error now */
|
2004-11-22 22:28:06 +00:00
|
|
|
|
return l;
|
2004-02-05 16:57:02 +00:00
|
|
|
|
} else {
|
|
|
|
|
e->TokNext = NULL;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
}
|
2003-01-08 16:45:35 +00:00
|
|
|
|
t->TokNext = e;
|
|
|
|
|
t = e;
|
|
|
|
|
p = e;
|
|
|
|
|
switch (cherr) {
|
|
|
|
|
case 'e':
|
|
|
|
|
case 'E':
|
|
|
|
|
och = cherr;
|
|
|
|
|
goto scan_name;
|
2002-11-19 17:10:45 +00:00
|
|
|
|
break;
|
2003-01-08 16:45:35 +00:00
|
|
|
|
case '=':
|
|
|
|
|
case '_':
|
|
|
|
|
/* handle error while parsing a float */
|
|
|
|
|
{
|
|
|
|
|
TokEntry *e2;
|
|
|
|
|
|
|
|
|
|
t->Tok = Ord(Var_tok);
|
|
|
|
|
t->TokInfo = Unsigned(Yap_LookupVar("E"));
|
2003-02-14 10:56:56 +00:00
|
|
|
|
t->TokPos = GetCurInpPos(inp_stream);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
e2 = (TokEntry *) AllocScannerMemory(sizeof(TokEntry));
|
|
|
|
|
if (e2 == NULL) {
|
2004-11-22 22:28:06 +00:00
|
|
|
|
Yap_ErrorMessage = "Trail Overflow";
|
2005-12-17 03:25:39 +00:00
|
|
|
|
Yap_Error_TYPE = OUT_OF_TRAIL_ERROR;
|
2004-11-22 22:28:06 +00:00
|
|
|
|
if (p)
|
2005-12-17 03:25:39 +00:00
|
|
|
|
p->Tok = Ord(kind = eot_tok);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
/* serious error now */
|
2004-11-22 22:28:06 +00:00
|
|
|
|
return l;
|
2004-02-05 16:57:02 +00:00
|
|
|
|
} else {
|
|
|
|
|
e2->TokNext = NULL;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
}
|
2003-01-08 16:45:35 +00:00
|
|
|
|
t->TokNext = e2;
|
|
|
|
|
t = e2;
|
|
|
|
|
p = e2;
|
|
|
|
|
if (cherr == '=')
|
|
|
|
|
och = '+';
|
|
|
|
|
else
|
|
|
|
|
och = '-';
|
|
|
|
|
}
|
|
|
|
|
goto enter_symbol;
|
|
|
|
|
case '+':
|
|
|
|
|
case '-':
|
|
|
|
|
/* handle error while parsing a float */
|
|
|
|
|
{
|
|
|
|
|
TokEntry *e2;
|
|
|
|
|
|
|
|
|
|
t->Tok = Name_tok;
|
|
|
|
|
if (ch == '(')
|
|
|
|
|
solo_flag = FALSE;
|
2008-12-23 01:53:52 +00:00
|
|
|
|
t->TokInfo = Unsigned(AtomE);
|
2003-02-14 10:56:56 +00:00
|
|
|
|
t->TokPos = GetCurInpPos(inp_stream);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
e2 = (TokEntry *) AllocScannerMemory(sizeof(TokEntry));
|
|
|
|
|
if (e2 == NULL) {
|
2004-11-22 22:28:06 +00:00
|
|
|
|
Yap_ErrorMessage = "Trail Overflow";
|
2005-12-17 03:25:39 +00:00
|
|
|
|
Yap_Error_TYPE = OUT_OF_TRAIL_ERROR;
|
|
|
|
|
t->Tok = Ord(kind = eot_tok);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
/* serious error now */
|
2004-11-22 22:28:06 +00:00
|
|
|
|
return l;
|
2004-02-05 16:57:02 +00:00
|
|
|
|
} else {
|
|
|
|
|
e2->TokNext = NULL;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
}
|
2003-01-08 16:45:35 +00:00
|
|
|
|
t->TokNext = e2;
|
|
|
|
|
t = e2;
|
|
|
|
|
p = e2;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
}
|
2003-01-08 16:45:35 +00:00
|
|
|
|
default:
|
|
|
|
|
och = cherr;
|
|
|
|
|
goto enter_symbol;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
}
|
2003-01-08 16:45:35 +00:00
|
|
|
|
} else {
|
|
|
|
|
t->Tok = Ord(kind = Number_tok);
|
2001-04-09 20:54:03 +01:00
|
|
|
|
}
|
2003-01-08 16:45:35 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case QT:
|
|
|
|
|
case DC:
|
|
|
|
|
TokImage = ((AtomEntry *) ( Yap_PreAllocCodeSpace()))->StrOfAE;
|
|
|
|
|
charp = TokImage;
|
|
|
|
|
quote = ch;
|
|
|
|
|
len = 0;
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchrq(inp_stream);
|
2006-11-27 17:42:03 +00:00
|
|
|
|
wcharp = NULL;
|
|
|
|
|
|
|
|
|
|
while (TRUE) {
|
2010-05-05 12:45:11 +01:00
|
|
|
|
if (charp + 1024 > (char *)AuxSp) {
|
2005-12-17 03:25:39 +00:00
|
|
|
|
Yap_Error_TYPE = OUT_OF_AUXSPACE_ERROR;
|
2003-01-08 16:45:35 +00:00
|
|
|
|
Yap_ErrorMessage = "Heap Overflow While Scanning: please increase code space (-h)";
|
|
|
|
|
break;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
}
|
2003-01-08 16:45:35 +00:00
|
|
|
|
if (ch == 10 && yap_flags[CHARACTER_ESCAPE_FLAG] == ISO_CHARACTER_ESCAPES) {
|
|
|
|
|
/* in ISO a new line terminates a string */
|
|
|
|
|
Yap_ErrorMessage = "layout character \n inside quotes";
|
|
|
|
|
break;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
}
|
2003-01-08 16:45:35 +00:00
|
|
|
|
if (ch == quote) {
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchrq(inp_stream);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
if (ch != quote)
|
2001-04-09 20:54:03 +01:00
|
|
|
|
break;
|
2010-05-05 12:45:11 +01:00
|
|
|
|
add_ch_to_buff(ch);
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchrq(inp_stream);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
} else if (ch == '\\' && yap_flags[CHARACTER_ESCAPE_FLAG] != CPROLOG_CHARACTER_ESCAPES) {
|
|
|
|
|
int scan_next = TRUE;
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = read_quoted_char(&scan_next, inp_stream);
|
2010-05-05 12:45:11 +01:00
|
|
|
|
add_ch_to_buff(ch);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
if (scan_next) {
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchrq(inp_stream);
|
2001-04-09 20:54:03 +01:00
|
|
|
|
}
|
2007-12-29 12:26:41 +00:00
|
|
|
|
} else if (chtype(ch) == EF && ch <= MAX_ISO_LATIN1) {
|
2002-11-18 18:18:05 +00:00
|
|
|
|
Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
t->Tok = Ord(kind = eot_tok);
|
2003-03-13 18:30:33 +00:00
|
|
|
|
break;
|
2003-01-08 16:45:35 +00:00
|
|
|
|
} else {
|
2010-05-05 12:45:11 +01:00
|
|
|
|
add_ch_to_buff(ch);
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchrq(inp_stream);
|
2001-04-09 20:54:03 +01:00
|
|
|
|
}
|
2003-01-08 16:45:35 +00:00
|
|
|
|
++len;
|
|
|
|
|
if (charp > (char *)AuxSp - 1024) {
|
|
|
|
|
/* Not enough space to read in the string. */
|
2005-12-17 03:25:39 +00:00
|
|
|
|
Yap_Error_TYPE = OUT_OF_AUXSPACE_ERROR;
|
|
|
|
|
Yap_ErrorMessage = "not enough space to read in string or quoted atom";
|
2003-01-08 16:45:35 +00:00
|
|
|
|
/* serious error now */
|
|
|
|
|
Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage);
|
|
|
|
|
t->Tok = Ord(kind = eot_tok);
|
2004-11-22 22:28:06 +00:00
|
|
|
|
return l;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
}
|
2003-01-08 16:45:35 +00:00
|
|
|
|
}
|
2007-10-02 13:32:46 +01:00
|
|
|
|
if (wcharp) {
|
|
|
|
|
*wcharp = '\0';
|
|
|
|
|
} else {
|
2006-11-27 17:42:03 +00:00
|
|
|
|
*charp = '\0';
|
2007-10-02 13:32:46 +01:00
|
|
|
|
}
|
2003-01-08 16:45:35 +00:00
|
|
|
|
if (quote == '"') {
|
2006-11-27 17:42:03 +00:00
|
|
|
|
if (wcharp) {
|
|
|
|
|
mp = AllocScannerMemory(sizeof(wchar_t)*(len+1));
|
|
|
|
|
} else {
|
|
|
|
|
mp = AllocScannerMemory(len + 1);
|
|
|
|
|
}
|
2003-01-08 16:45:35 +00:00
|
|
|
|
if (mp == NULL) {
|
2005-12-17 03:25:39 +00:00
|
|
|
|
Yap_ErrorMessage = "not enough heap space to read in string or quoted atom";
|
2003-01-08 16:45:35 +00:00
|
|
|
|
Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage);
|
|
|
|
|
t->Tok = Ord(kind = eot_tok);
|
2004-11-22 22:28:06 +00:00
|
|
|
|
return l;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
}
|
2006-11-27 17:42:03 +00:00
|
|
|
|
if (wcharp)
|
|
|
|
|
wcscpy((wchar_t *)mp,(wchar_t *)TokImage);
|
|
|
|
|
else
|
|
|
|
|
strcpy(mp, TokImage);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
t->TokInfo = Unsigned(mp);
|
|
|
|
|
Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage);
|
2006-11-27 17:42:03 +00:00
|
|
|
|
if (wcharp) {
|
|
|
|
|
t->Tok = Ord(kind = WString_tok);
|
|
|
|
|
} else {
|
|
|
|
|
t->Tok = Ord(kind = String_tok);
|
|
|
|
|
}
|
2003-01-08 16:45:35 +00:00
|
|
|
|
} else {
|
2006-11-27 17:42:03 +00:00
|
|
|
|
if (wcharp) {
|
|
|
|
|
t->TokInfo = Unsigned(Yap_LookupWideAtom((wchar_t *)TokImage));
|
|
|
|
|
} else {
|
|
|
|
|
t->TokInfo = Unsigned(Yap_LookupAtom(TokImage));
|
2010-05-05 12:45:11 +01:00
|
|
|
|
}
|
|
|
|
|
if (!(t->TokInfo)) {
|
|
|
|
|
Yap_Error_TYPE = OUT_OF_HEAP_ERROR;
|
|
|
|
|
Yap_ErrorMessage = "Code Space Overflow";
|
|
|
|
|
if (p)
|
|
|
|
|
t->Tok = Ord(kind = eot_tok);
|
|
|
|
|
/* serious error now */
|
|
|
|
|
return l;
|
2006-11-27 17:42:03 +00:00
|
|
|
|
}
|
2003-01-08 16:45:35 +00:00
|
|
|
|
Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage);
|
|
|
|
|
t->Tok = Ord(kind = Name_tok);
|
2001-04-09 20:54:03 +01:00
|
|
|
|
if (ch == '(')
|
|
|
|
|
solo_flag = FALSE;
|
2003-01-08 16:45:35 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case SY:
|
|
|
|
|
och = ch;
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchr(inp_stream);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
if (och == '/' && ch == '*') {
|
2007-12-29 12:26:41 +00:00
|
|
|
|
while ((och != '*' || ch != '/') && chtype(ch) != EF) {
|
2003-01-08 16:45:35 +00:00
|
|
|
|
och = ch;
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchr(inp_stream);
|
2001-04-09 20:54:03 +01:00
|
|
|
|
}
|
2007-12-29 12:26:41 +00:00
|
|
|
|
if (chtype(ch) == EF) {
|
2003-01-08 16:45:35 +00:00
|
|
|
|
t->Tok = Ord(kind = eot_tok);
|
2001-04-09 20:54:03 +01:00
|
|
|
|
}
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchr(inp_stream);
|
2008-10-23 22:17:45 +01:00
|
|
|
|
if (t == l) {
|
|
|
|
|
/* we found a comment before reading characters */
|
|
|
|
|
while (chtype(ch) == BS) {
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchr(inp_stream);
|
2008-10-23 22:17:45 +01:00
|
|
|
|
}
|
|
|
|
|
*tposp = Yap_StreamPosition(inp_stream);
|
|
|
|
|
}
|
2003-01-08 16:45:35 +00:00
|
|
|
|
goto restart;
|
|
|
|
|
}
|
|
|
|
|
enter_symbol:
|
2007-12-29 12:26:41 +00:00
|
|
|
|
if (och == '.' && (chtype(ch) == BS || chtype(ch) == EF
|
|
|
|
|
|| chtype(ch) == CC)) {
|
2003-01-08 16:45:35 +00:00
|
|
|
|
Yap_eot_before_eof = TRUE;
|
2007-12-29 12:26:41 +00:00
|
|
|
|
if (chtype(ch) == CC)
|
2011-02-15 07:39:27 +00:00
|
|
|
|
while ((ch = getchr(inp_stream)) != 10 && chtype(ch) != EF);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
t->Tok = Ord(kind = eot_tok);
|
|
|
|
|
}
|
|
|
|
|
else {
|
|
|
|
|
TokImage = ((AtomEntry *) ( Yap_PreAllocCodeSpace()))->StrOfAE;
|
|
|
|
|
charp = TokImage;
|
|
|
|
|
*charp++ = och;
|
2011-02-15 07:39:27 +00:00
|
|
|
|
for (; chtype(ch) == SY; ch = getchr(inp_stream))
|
2003-01-08 16:45:35 +00:00
|
|
|
|
*charp++ = ch;
|
|
|
|
|
*charp = '\0';
|
|
|
|
|
t->TokInfo = Unsigned(Yap_LookupAtom(TokImage));
|
2007-04-18 07:30:41 +01:00
|
|
|
|
if (t->TokInfo == (CELL)NIL) {
|
|
|
|
|
Yap_Error_TYPE = OUT_OF_HEAP_ERROR;
|
|
|
|
|
Yap_ErrorMessage = "Code Space Overflow";
|
|
|
|
|
if (p)
|
|
|
|
|
t->Tok = Ord(kind = eot_tok);
|
|
|
|
|
/* serious error now */
|
|
|
|
|
return l;
|
|
|
|
|
}
|
2003-01-08 16:45:35 +00:00
|
|
|
|
Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage);
|
|
|
|
|
t->Tok = Ord(kind = Name_tok);
|
|
|
|
|
if (ch == '(')
|
|
|
|
|
solo_flag = FALSE;
|
2010-02-18 09:19:29 +00:00
|
|
|
|
else
|
|
|
|
|
solo_flag = TRUE;
|
2003-01-08 16:45:35 +00:00
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case SL:
|
|
|
|
|
{
|
|
|
|
|
char chs[2];
|
|
|
|
|
chs[0] = ch;
|
|
|
|
|
chs[1] = '\0';
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchr(inp_stream);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
t->TokInfo = Unsigned(Yap_LookupAtom(chs));
|
|
|
|
|
t->Tok = Ord(kind = Name_tok);
|
|
|
|
|
if (ch == '(')
|
|
|
|
|
solo_flag = FALSE;
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
case BK:
|
|
|
|
|
och = ch;
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchr(inp_stream);
|
2008-03-10 14:11:38 +00:00
|
|
|
|
t->TokInfo = och;
|
|
|
|
|
if (t->TokInfo == '(' && !solo_flag) {
|
|
|
|
|
t->TokInfo = 'l';
|
|
|
|
|
solo_flag = TRUE;
|
2009-12-03 22:51:29 +00:00
|
|
|
|
} else if (och == '[') {
|
2011-02-15 07:39:27 +00:00
|
|
|
|
while (chtype(ch) == BS) { ch = getchr(inp_stream); };
|
2009-12-03 22:51:29 +00:00
|
|
|
|
if (ch == ']') {
|
|
|
|
|
t->TokInfo = Unsigned(AtomNil);
|
|
|
|
|
t->Tok = Ord(kind = Name_tok);
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchr(inp_stream);
|
2009-12-03 22:51:29 +00:00
|
|
|
|
solo_flag = FALSE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
} else if (och == '{') {
|
2011-02-15 07:39:27 +00:00
|
|
|
|
while (chtype(ch) == BS) { ch = getchr(inp_stream); };
|
2009-12-03 22:51:29 +00:00
|
|
|
|
if (ch == '}') {
|
|
|
|
|
t->TokInfo = Unsigned(AtomBraces);
|
|
|
|
|
t->Tok = Ord(kind = Name_tok);
|
2011-02-15 07:39:27 +00:00
|
|
|
|
ch = getchr(inp_stream);
|
2009-12-03 22:51:29 +00:00
|
|
|
|
solo_flag = FALSE;
|
|
|
|
|
break;
|
|
|
|
|
}
|
2003-01-08 16:45:35 +00:00
|
|
|
|
}
|
2008-03-10 14:11:38 +00:00
|
|
|
|
t->Tok = Ord(kind = Ponctuation_tok);
|
2003-01-08 16:45:35 +00:00
|
|
|
|
break;
|
2001-04-09 20:54:03 +01:00
|
|
|
|
|
2003-01-08 16:45:35 +00:00
|
|
|
|
case EF:
|
|
|
|
|
t->Tok = Ord(kind = eot_tok);
|
|
|
|
|
break;
|
|
|
|
|
|
|
|
|
|
default:
|
2001-04-09 20:54:03 +01:00
|
|
|
|
#ifdef DEBUG
|
2007-12-29 12:26:41 +00:00
|
|
|
|
fprintf(Yap_stderr, "\n++++ token: wrong char type %c %d\n", ch, chtype(ch));
|
2001-04-09 20:54:03 +01:00
|
|
|
|
#endif
|
2003-01-08 16:45:35 +00:00
|
|
|
|
t->Tok = Ord(kind = eot_tok);
|
2001-04-09 20:54:03 +01:00
|
|
|
|
}
|
|
|
|
|
#ifdef DEBUG
|
2003-01-08 16:45:35 +00:00
|
|
|
|
if(Yap_Option[2]) fprintf(Yap_stderr,"[Token %d %ld]",Ord(kind),(unsigned long int)t->TokInfo);
|
2001-04-09 20:54:03 +01:00
|
|
|
|
#endif
|
2002-11-19 17:10:45 +00:00
|
|
|
|
if (Yap_ErrorMessage) {
|
2003-10-06 15:16:23 +01:00
|
|
|
|
/* insert an error token to inform the system of what happened */
|
2002-11-19 17:10:45 +00:00
|
|
|
|
TokEntry *e = (TokEntry *) AllocScannerMemory(sizeof(TokEntry));
|
|
|
|
|
if (e == NULL) {
|
2004-11-22 22:28:06 +00:00
|
|
|
|
Yap_ErrorMessage = "Trail Overflow";
|
2005-12-17 03:25:39 +00:00
|
|
|
|
Yap_Error_TYPE = OUT_OF_TRAIL_ERROR;
|
|
|
|
|
p->Tok = Ord(kind = eot_tok);
|
2002-11-19 17:10:45 +00:00
|
|
|
|
/* serious error now */
|
2004-11-22 22:28:06 +00:00
|
|
|
|
return l;
|
2002-11-19 17:10:45 +00:00
|
|
|
|
}
|
|
|
|
|
p->TokNext = e;
|
|
|
|
|
e->Tok = Error_tok;
|
|
|
|
|
e->TokInfo = MkAtomTerm(Yap_LookupAtom(Yap_ErrorMessage));
|
2003-02-14 10:56:56 +00:00
|
|
|
|
e->TokPos = GetCurInpPos(inp_stream);
|
2004-02-05 16:57:02 +00:00
|
|
|
|
e->TokNext = NULL;
|
2002-11-19 17:10:45 +00:00
|
|
|
|
Yap_ErrorMessage = NULL;
|
|
|
|
|
p = e;
|
|
|
|
|
}
|
2001-04-09 20:54:03 +01:00
|
|
|
|
} while (kind != eot_tok);
|
|
|
|
|
return (l);
|
|
|
|
|
}
|
2004-02-05 16:57:02 +00:00
|
|
|
|
|
|
|
|
|
void
|
|
|
|
|
Yap_clean_tokenizer(TokEntry *tokstart, VarEntry *vartable, VarEntry *anonvartable)
|
|
|
|
|
{
|
2011-03-07 16:02:55 +00:00
|
|
|
|
CACHE_REGS
|
2005-01-28 23:14:41 +00:00
|
|
|
|
struct scanner_extra_alloc *ptr = ScannerExtraBlocks;
|
2004-12-28 22:20:37 +00:00
|
|
|
|
while (ptr) {
|
2005-01-28 23:14:41 +00:00
|
|
|
|
struct scanner_extra_alloc *next = ptr->next;
|
2004-12-28 22:20:37 +00:00
|
|
|
|
free(ptr);
|
|
|
|
|
ptr = next;
|
|
|
|
|
}
|
2004-02-05 16:57:02 +00:00
|
|
|
|
}
|
2005-11-08 13:51:15 +00:00
|
|
|
|
|