diff --git a/C/c_interface.c b/C/c_interface.c index 1f9c8abbe..67e98db7e 100644 --- a/C/c_interface.c +++ b/C/c_interface.c @@ -21,6 +21,7 @@ #include "Yap.h" #include "clause.h" #include "yapio.h" +#include "iopreds.h" #define HAS_YAP_H 1 #include "yap_structs.h" #ifdef YAPOR @@ -788,12 +789,22 @@ YAP_Read(int (*mygetc)(void)) { Term t; tr_fr_ptr old_TR; + int sno; BACKUP_MACHINE_REGS(); do_getf = mygetc; old_TR = TR; - Yap_tokptr = Yap_toktide = Yap_tokenizer(do_yap_getc, do_yap_getc); + for (sno = 0; sno < MaxStreams; ++sno) + if (Stream[sno].status & Free_Stream_f) + break; + if (sno == MaxStreams) { + Yap_Error(SYSTEM_ERROR,TermNil, "new stream not available for YAP_Read"); + return TermNil; + } + Stream[sno].stream_getc_for_read = Stream[sno].stream_getc = do_yap_getc; + Yap_tokptr = Yap_toktide = Yap_tokenizer(sno); + Stream[sno].status = Free_Stream_f; if (Yap_ErrorMessage) { TR = old_TR; diff --git a/C/init.c b/C/init.c index b45c115e6..4aaf66dff 100644 --- a/C/init.c +++ b/C/init.c @@ -662,7 +662,7 @@ InitFlags(void) yap_flags[STRICT_ISO_FLAG] = FALSE; yap_flags[SPY_CREEP_FLAG] = 0; yap_flags[SOURCE_MODE_FLAG] = FALSE; - yap_flags[CHARACTER_ESCAPE_FLAG] = ISO_CHARACTER_ESCAPES; + yap_flags[CHARACTER_ESCAPE_FLAG] = SICSTUS_CHARACTER_ESCAPES; yap_flags[WRITE_QUOTED_STRING_FLAG] = FALSE; #if (defined(YAPOR) || defined(THREADS)) && PUREe_YAPOR yap_flags[ALLOW_ASSERTING_STATIC_FLAG] = FALSE; diff --git a/C/iopreds.c b/C/iopreds.c index 52ce28a4a..44d7feac4 100644 --- a/C/iopreds.c +++ b/C/iopreds.c @@ -2936,17 +2936,17 @@ p_get_read_error_handler(void) } static Int -p_read (void) -{ /* '$read'(+Flag,?Term,?Vars,-Pos,-Err) */ +do_read(int inp_stream) +{ Term t, v; - TokEntry *tokstart, *fast_tokenizer (void); + TokEntry *tokstart; #if EMACS int emacs_cares = FALSE; #endif tr_fr_ptr old_TR, TR_before_parse; - if (Stream[Yap_c_input_stream].status & Binary_Stream_f) { - Yap_Error(PERMISSION_ERROR_INPUT_BINARY_STREAM, MkAtomTerm(Stream[Yap_c_input_stream].u.file.name), "read_term/2"); + if (Stream[inp_stream].status & Binary_Stream_f) { + Yap_Error(PERMISSION_ERROR_INPUT_BINARY_STREAM, MkAtomTerm(Stream[inp_stream].u.file.name), "read_term/2"); return(FALSE); } old_TR = TR; @@ -2955,17 +2955,11 @@ p_read (void) /* Scans the term using stack space */ Yap_eot_before_eof = FALSE; - if ((Stream[Yap_c_input_stream].status & (Promptable_Stream_f|Pipe_Stream_f|Socket_Stream_f|Eof_Stream_f|InMemory_Stream_f)) || - CharConversionTable != NULL || - Stream[Yap_c_input_stream].stream_getc != PlGetc) - tokstart = Yap_tokptr = Yap_toktide = Yap_tokenizer (Stream[Yap_c_input_stream].stream_getc_for_read, Stream[Yap_c_input_stream].stream_getc); - else { - tokstart = Yap_tokptr = Yap_toktide = Yap_fast_tokenizer (); - } + tokstart = Yap_tokptr = Yap_toktide = Yap_tokenizer (inp_stream); /* preserve value of H after scanning: otherwise we may lose strings and floats */ old_H = H; - if ((Stream[Yap_c_input_stream].status & Eof_Stream_f) + if ((Stream[inp_stream].status & Eof_Stream_f) && !Yap_eot_before_eof) { if (tokstart != NIL && tokstart->Tok != Ord (eot_tok)) { /* we got the end of file from an abort */ @@ -2974,13 +2968,13 @@ p_read (void) return(FALSE); } /* we need to force the next reading to also give end of file.*/ - Stream[Yap_c_input_stream].status |= Push_Eof_Stream_f; + Stream[inp_stream].status |= Push_Eof_Stream_f; Yap_ErrorMessage = "end of file found before end of term"; } else { /* restore TR */ TR = old_TR; - return (Yap_unify(MkIntegerTerm(StartLine = Stream[Yap_c_input_stream].linecount),ARG4) && + return (Yap_unify(MkIntegerTerm(StartLine = Stream[inp_stream].linecount),ARG4) && Yap_unify_constant (ARG2, MkAtomTerm (AtomEof))); } } @@ -3056,22 +3050,23 @@ p_read (void) } } +static Int +p_read (void) +{ /* '$read'(+Flag,?Term,?Vars,-Pos,-Err) */ + return(do_read(Yap_c_input_stream)); +} + static Int p_read2 (void) { /* '$read2'(+Flag,?Term,?Vars,-Pos,-Err,+Stream) */ - int old_c_stream = Yap_c_input_stream; - Int out; + int inp_stream; /* needs to change Yap_c_output_stream for write */ - Yap_c_input_stream = CheckStream (ARG6, Input_Stream_f, "read/3"); - if (Yap_c_input_stream == -1) { - Yap_c_input_stream = old_c_stream; + inp_stream = CheckStream (ARG6, Input_Stream_f, "read/3"); + if (inp_stream == -1) { return(FALSE); } - out = p_read(); - Yap_c_input_stream = old_c_stream; - return(out); - + return(do_read(inp_stream)); } static Int diff --git a/C/save.c b/C/save.c index dbf5a5bc8..aebe54442 100644 --- a/C/save.c +++ b/C/save.c @@ -311,7 +311,7 @@ get_header_cell(void) int count = 0, n; while (count < sizeof(CELL)) { if ((n = read(splfild, &l, sizeof(CELL)-count)) < 0) { - Yap_ErrorMessage = "corrupt saved state"; + Yap_ErrorMessage = "corrupt saved state (too short)"; return(0L); } count += n; @@ -601,7 +601,7 @@ check_header(CELL *info, CELL *ATrail, CELL *AStack, CELL *AHeap) /* skip the first line */ do { if (read(splfild, pp, 1) < 0) { - Yap_ErrorMessage = "corrupt saved state"; + Yap_ErrorMessage = "corrupt saved state (failed to read first line)"; return(FAIL_RESTORE); } } while (pp[0] != 1); @@ -611,18 +611,18 @@ check_header(CELL *info, CELL *ATrail, CELL *AStack, CELL *AHeap) int count = 0, n, to_read = Unsigned(strlen(msg) + 1); while (count < to_read) { if ((n = read(splfild, pp, to_read-count)) < 0) { - Yap_ErrorMessage = "corrupt saved state"; + Yap_ErrorMessage = "corrupt saved state (header too short)"; return(FAIL_RESTORE); } count += n; } } if (pp[0] != 'Y' && pp[1] != 'A' && pp[0] != 'P') { - Yap_ErrorMessage = "corrupt saved state"; + Yap_ErrorMessage = "corrupt saved state (should say YAP)"; return(FAIL_RESTORE); } if (strcmp(pp, msg) != 0) { - Yap_ErrorMessage = "saved state for different version of YAP"; + Yap_ErrorMessage = "corrupt saved state (different version of YAP)"; return(FAIL_RESTORE); } /* check info on header */ @@ -635,7 +635,7 @@ check_header(CELL *info, CELL *ATrail, CELL *AStack, CELL *AHeap) if (Yap_ErrorMessage) return(FAIL_RESTORE); if (mode != DO_EVERYTHING && mode != DO_ONLY_CODE) { - Yap_ErrorMessage = "corrupt saved state"; + Yap_ErrorMessage = "corrupt saved state (bad type)"; return(FAIL_RESTORE); } /* ignore info on stacks size */ @@ -786,7 +786,7 @@ CopyCode(void) /* skip the local and global data structures */ CELL j = get_cell(); if (j != Unsigned(&GLOBAL) - Unsigned(Yap_HeapBase)) { - Yap_Error(FATAL_ERROR,TermNil,"bad saved state, system corrupted"); + Yap_Error(FATAL_ERROR,TermNil,"bad saved state (code space size does not match)"); } myread(splfild, (char *) Yap_HeapBase, j); #ifdef USE_HEAP @@ -795,7 +795,7 @@ CopyCode(void) #else j = get_cell(); if (j != Unsigned(BaseAllocArea) - Unsigned(&HashChain)) { - Yap_Error(FATAL_ERROR,TermNil,"bad saved state, system corrupted"); + Yap_Error(FATAL_ERROR,TermNil,"bad saved state (Base to Hash does not match)"); } myread(splfild, (char *) &HashChain, j); j = get_cell(); @@ -859,7 +859,7 @@ get_coded(int flag, OPCODE old_ops[]) /* Check CRC */ myread(splfild, my_end_msg, 256); if (strcmp(end_msg,my_end_msg) != 0) - Yap_Error(FATAL_ERROR,TermNil,"bad saved state, system corrupted"); + Yap_Error(FATAL_ERROR,TermNil,"corrupt saved state (bad trailing CRC)"); return(funcs_moved); } @@ -1280,7 +1280,12 @@ OpenRestore(char *inpf, char *YapLibDir, CELL *Astate, CELL *ATrail, CELL *AStac } } } - Yap_Error(SYSTEM_ERROR, TermNil, Yap_ErrorMessage); + /* could not open file */ + if (Yap_ErrorMessage == NULL) { + Yap_Error(SYSTEM_ERROR,TermNil,"could not open %s,",inpf); + } else { + Yap_Error(SYSTEM_ERROR, TermNil, Yap_ErrorMessage); + } Yap_ErrorMessage = NULL; return(FAIL_RESTORE); } diff --git a/C/scanner.c b/C/scanner.c index 468a54c8e..bba1d7a35 100644 --- a/C/scanner.c +++ b/C/scanner.c @@ -57,12 +57,11 @@ static char SccsId[] = "@(#)scanner.c 1.2"; #define my_isxdigit(C,SU,SL) (chtype[C] == NU || (C >= 'A' && \ C <= (SU)) || (C >= 'a' && C <= (SL))) #define my_isupper(C) ( C >= 'A' && C <= 'Z' ) +#define my_islower(C) ( C >= 'a' && C <= 'z' ) -STATIC_PROTO(void my_ungetch, (void)); -STATIC_PROTO(int my_getch, (void)); +STATIC_PROTO(int my_getch, (int (*) (int))); STATIC_PROTO(Term float_send, (char *)); -STATIC_PROTO(Term get_num, (void)); -STATIC_PROTO(enum TokenKinds token, (void)); +STATIC_PROTO(Term get_num, (int *, int *, int, int (*) (int), int (*) (int))); /* token table with some help from Richard O'Keefe's PD scanner */ static char chtype0[NUMBER_OF_CHARS+1] = @@ -127,20 +126,6 @@ EF, #define chtype (chtype0+1) char *Yap_chtype = chtype0+1; -static int ch, chbuff, o_ch; - -static char *TokImage; - -static int BUF = FALSE; - -static Int TokenPos; - -static CELL TokenInfo; - -static int (*Nextch) (int); - -static int (*QuotedNextch) (int); - static char * AllocScannerMemory(unsigned int size) { @@ -165,25 +150,10 @@ Yap_AllocScannerMemory(unsigned int size) return AllocScannerMemory(size); } -inline static void -my_ungetch(void) -{ - chbuff = ch; - ch = o_ch; - BUF = TRUE; -} - inline static int -my_getch(void) +my_getch(int (*Nextch) (int)) { - o_ch = ch; - if (BUF) { - BUF = FALSE; - ch = chbuff; - } - else { - ch = (*Nextch) (Yap_c_input_stream); - } + int ch = (*Nextch) (Yap_c_input_stream); #ifdef DEBUG if (Yap_Option[1]) fprintf(Yap_stderr, "[getch %c]", ch); @@ -191,24 +161,6 @@ my_getch(void) return(ch); } -inline static int -my_get_quoted_ch(void) -{ - o_ch = ch; - if (BUF) { - BUF = FALSE; - ch = chbuff; - } - else { - ch = (*QuotedNextch) (Yap_c_input_stream); - } -#ifdef DEBUG - if (Yap_Option[1]) - fprintf(Yap_stderr, "[getch %c]",ch); -#endif - return (ch); -} - extern double atof(const char *); static Term @@ -242,17 +194,198 @@ read_int_overflow(const char *s, Int base, Int val) #endif } +static unsigned int +read_quoted_char(int *scan_nextp, int inp_stream, int (*QuotedNxtch)(int)) +{ + int ch; + + /* escape sequence */ + restart: + ch = QuotedNxtch(inp_stream); + switch (ch) { + case 10: + goto restart; + case 'a': + return '\a'; + case 'b': + return '\b'; + case 'c': + if (yap_flags[CHARACTER_ESCAPE_FLAG] == ISO_CHARACTER_ESCAPES) { + Yap_ErrorMessage = "invalid escape sequence \\c"; + return 0; + } else { + /* sicstus */ + ch = QuotedNxtch(inp_stream); + if (chtype[ch] == SL) { + goto restart; + } else { + return 'c'; + } + } + case 'd': + return 127; + case 'e': + return '\e'; + case 'f': + return '\f'; + case 'n': + return '\n'; + case 'r': + return '\r'; + case 't': + return '\t'; + case 'v': + return '\v'; + case '\\': + return '\\'; + case '\'': + return '\''; + case '"': + return '"'; + case '`': + return '`'; + case '^': + if (yap_flags[CHARACTER_ESCAPE_FLAG] == ISO_CHARACTER_ESCAPES) { + Yap_ErrorMessage = "invalid escape sequence"; + return 0; + } else { + ch = QuotedNxtch(inp_stream); + if (ch == '?') {/* delete character */ + return 127; + } else if (ch >= 'a' && ch < 'z') {/* octal */ + return ch - 'a'; + ch = QuotedNxtch(inp_stream); + } else if (ch >= 'A' && ch < 'Z') {/* octal */ + 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 \ */ + if (yap_flags[CHARACTER_ESCAPE_FLAG] == ISO_CHARACTER_ESCAPES) { + unsigned char so_far = ch-'0'; + ch = QuotedNxtch(inp_stream); + if (ch >= '0' && ch < '8') {/* octal */ + so_far = so_far*8+(ch-'0'); + ch = QuotedNxtch(inp_stream); + if (ch >= '0' && ch < '8') { /* octal */ + so_far = so_far*8+(ch-'0'); + ch = QuotedNxtch(inp_stream); + if (ch != '\\') { + Yap_ErrorMessage = "invalid octal escape sequence"; + return 0; + } + } else if (ch == '\\') { + return so_far; + } else { + Yap_ErrorMessage = "invalid octal escape sequence"; + return 0; + } + } else if (ch == '\\') { + return so_far; + } else { + Yap_ErrorMessage = "invalid octal escape sequence"; + return 0; + } + } else { + /* sicstus */ + unsigned char so_far = ch-'0'; + ch = QuotedNxtch(inp_stream); + if (ch >= '0' && ch < '8') {/* octal */ + so_far = so_far*8+(ch-'0'); + ch = QuotedNxtch(inp_stream); + 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; + ch = QuotedNxtch(inp_stream); + if (my_isxdigit(ch,'f','F')) {/* hexa */ + so_far = so_far * 16 + (chtype[ch] == NU ? ch - '0' : + (my_isupper(ch) ? ch - 'A' : ch - 'a') + 10); + ch = QuotedNxtch(inp_stream); + if (my_isxdigit(ch,'f','F')) { /* hexa */ + so_far = so_far * 16 + (chtype[ch] == NU ? ch - '0' : + (my_isupper(ch) ? ch - 'A' : ch - 'a') + 10); + ch = QuotedNxtch(inp_stream); + if (ch == '\\') { + return so_far; + } else { + Yap_ErrorMessage = "invalid hexadecimal escape sequence"; + return 0; + } + } else if (ch == '\\') { + return so_far; + } else { + Yap_ErrorMessage = "invalid hexadecimal escape sequence"; + return 0; + } + } else if (ch == '\\') { + return so_far; + } else { + Yap_ErrorMessage = "invalid hexadecimal escape sequence"; + return 0; + } + } else { + /* sicstus mode */ + unsigned char so_far = 0; + ch = QuotedNxtch(inp_stream); + so_far = (chtype[ch] == NU ? ch - '0' : + my_isupper(ch) ? ch - 'A' + 10 : + my_islower(ch) ? ch - 'a' +10 : 0); + ch = QuotedNxtch(inp_stream); + return so_far + (chtype[ch] == NU ? ch - '0' : + 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) { + Yap_ErrorMessage = "invalid escape sequence"; + return 0; + } else { + /* sicstus */ + if (chtype[ch] == SL) { + goto restart; + } else { + return ch; + } + } + } +} + /* reads a number, either integer or float */ static Term -get_num(void) +get_num(int *chp, int *chbuffp, int inp_stream, int (*Nxtch) (int), int (*QuotedNxtch) (int)) { char *s = (char *)TR, *sp = s; + int ch = *chp; Int val = 0, base = ch - '0'; int might_be_float = TRUE, has_overflow = FALSE; *sp++ = ch; - my_getch(); + ch = Nxtch(inp_stream); /* * because of things like 00'2, 03'2 and even better 12'2, I need to * do this (have mercy) @@ -260,7 +393,7 @@ get_num(void) if (chtype[ch] == NU) { *sp++ = ch; base = 10 * base + ch - '0'; - my_getch(); + ch = Nxtch(inp_stream); } if (ch == '\'') { if (base > 36) { @@ -269,123 +402,20 @@ get_num(void) } might_be_float = FALSE; *sp++ = ch; - restart: - my_getch(); + ch = Nxtch(inp_stream); if (base == 0) { Int ascii = ch; + int scan_extra = TRUE; if (ch == '\\' && yap_flags[CHARACTER_ESCAPE_FLAG] != CPROLOG_CHARACTER_ESCAPES) { - /* escape sequence */ - ch = my_get_quoted_ch(); - switch (ch) { - case 10: - goto restart; - case 'a': - ascii = '\a'; - break; - case 'b': - ascii = '\b'; - break; - case 'r': - ascii = '\r'; - break; - case 'f': - ascii = '\f'; - break; - case 't': - ascii = '\t'; - break; - case 'n': - ascii = '\n'; - break; - case 'v': - ascii = '\v'; - break; - case '\\': - ascii = '\\'; - break; - case '\'': - ascii = '\''; - break; - case '"': - ascii = '"'; - break; - case '`': - ascii = '`'; - break; - 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 \ */ - { - unsigned char so_far = ch-'0'; - my_get_quoted_ch(); - if (ch >= '0' && ch < '8') {/* octal */ - so_far = so_far*8+(ch-'0'); - my_get_quoted_ch(); - if (ch >= '0' && ch < '8') { /* octal */ - ascii = so_far*8+(ch-'0'); - my_get_quoted_ch(); - if (ch != '\\') { - Yap_ErrorMessage = "invalid octal escape sequence"; - } - } else if (ch == '\\') { - ascii = so_far; - } else { - Yap_ErrorMessage = "invalid octal escape sequence"; - } - } else if (ch == '\\') { - ascii = so_far; - } else { - Yap_ErrorMessage = "invalid octal escape sequence"; - } - } - break; - case 'x': - /* hexadecimal character (YAP allows empty hexadecimal */ - { - unsigned char so_far = 0; - my_get_quoted_ch(); - if (my_isxdigit(ch,'f','F')) {/* hexa */ - so_far = so_far * 16 + (chtype[ch] == NU ? ch - '0' : - (my_isupper(ch) ? ch - 'A' : ch - 'a') + 10); - my_get_quoted_ch(); - if (my_isxdigit(ch,'f','F')) { /* hexa */ - ascii = so_far * 16 + (chtype[ch] == NU ? ch - '0' : - (my_isupper(ch) ? ch - 'A' : ch - 'a') + 10); - my_get_quoted_ch(); - if (ch != '\\') { - Yap_ErrorMessage = "invalid hexadecimal escape sequence"; - } - } else if (ch == '\\') { - ascii = so_far; - } else { - Yap_ErrorMessage = "invalid hexadecimal escape sequence"; - } - } else if (ch == '\\') { - ascii = so_far; - my_get_quoted_ch(); - } - } - break; - default: - /* accept sequence. Note that the ISO standard does not - consider this sequence legal, whereas SICStus would - eat up the escape sequence. */ - Yap_ErrorMessage = "invalid escape sequence"; - } + ascii = read_quoted_char(&scan_extra, inp_stream, QuotedNxtch); } /* a quick way to represent ASCII */ - my_getch(); + if (scan_extra) + *chp = Nxtch(inp_stream); return (MkIntTerm(ascii)); - } - else if (base >= 10 && base <= 36) { + } else if (base >= 10 && base <= 36) { int upper_case = 'A' - 11 + base; int lower_case = 'a' - 11 + base; @@ -396,14 +426,13 @@ get_num(void) (my_isupper(ch) ? ch - 'A' : ch - 'a') + 10); if (oval >= val && oval != 0) /* overflow */ has_overflow = (has_overflow || TRUE); - my_getch(); + ch = Nxtch(inp_stream); } } - } - else if ((ch == 'x' || ch == 'X') && base == 0) { + } else if ((ch == 'x' || ch == 'X') && base == 0) { might_be_float = FALSE; *sp++ = ch; - my_getch(); + ch = Nxtch(inp_stream); while (my_isxdigit(ch, 'F', 'f')) { Int oval = val; *sp++ = ch; @@ -411,14 +440,15 @@ get_num(void) (my_isupper(ch) ? ch - 'A' : ch - 'a') + 10); if (oval >= val && oval != 0) /* overflow */ has_overflow = (has_overflow || TRUE); - my_getch(); + ch = Nxtch(inp_stream); } + *chp = ch; } else if ((ch == 'o') && base == 0) { might_be_float = FALSE; base = 8; *sp++ = ch; - my_getch(); + *chp = Nxtch(inp_stream); } else { val = base; @@ -432,13 +462,14 @@ get_num(void) val = val * base + ch - '0'; if (oval >= val && oval != 0) /* overflow */ has_overflow = (has_overflow || TRUE); - my_getch(); + ch = Nxtch(inp_stream); } if (might_be_float && (ch == '.' || ch == 'e' || ch == 'E')) { if (ch == '.') { *sp++ = '.'; - if (chtype[my_getch()] != NU) { - my_ungetch(); + if (chtype[ch = Nxtch(inp_stream)] != NU) { + *chbuffp = '.'; + *chp = ch; *--sp = '\0'; if (has_overflow) return(read_int_overflow(s,base,val)); @@ -446,31 +477,52 @@ get_num(void) } do *sp++ = ch; - while (chtype[my_getch()] == NU); + while (chtype[ch = Nxtch(inp_stream)] == NU); } if (ch == 'e' || ch == 'E') { - *sp++ = 'e'; - my_getch(); + char *sp0 = sp; + char cbuff = ch; + *sp++ = ch; + ch = Nxtch(inp_stream); if (ch == '-') { - *sp++ = ch; - my_getch(); + cbuff = '-'; + *sp++ = '-'; + ch = Nxtch(inp_stream); + } else if (ch == '+') { + cbuff = '+'; + ch = Nxtch(inp_stream); } - else if (ch == '+') - my_getch(); if (chtype[ch] != NU) { - my_ungetch(); - *--sp = '\0'; - return (float_send(s)); + /* error */ + char *sp; + *chp = ch; + if (*sp0 == 'E') { + /* code the fact that we have E and not e */ + if (cbuff == '+') + *chbuffp = '='; + else + *chbuffp = '_'; + } else { + *chbuffp = cbuff; + } + *sp0 = '\0'; + for (sp = s; sp < sp0; sp++) { + if (*sp == '.') + return (float_send(s)); + } + return(MkIntegerTerm(val)); } - do + do { *sp++ = ch; - while (chtype[my_getch()] == NU); + } while (chtype[ch = Nxtch(inp_stream)] == NU); } *sp = '\0'; + *chp = ch; return (float_send(s)); } else if (has_overflow) { *sp = '\0'; /* skip base */ + *chp = ch; if (s[0] == '0' && (s[1] == 'x' || s[1] == 'X')) return(read_int_overflow(s+2,16,val)); if (s[1] == '\'') @@ -478,8 +530,10 @@ get_num(void) if (s[2] == '\'') return(read_int_overflow(s+3,base,val)); return(read_int_overflow(s,base,val)); - } else + } else { + *chp = ch; return (MkIntegerTerm(val)); + } } /* given a function Nxtch scan until we either find the number @@ -489,1112 +543,348 @@ Yap_scan_num(int (*Nxtch) (int)) { Term out; int sign = 1; + int ch, cherr; - Nextch = Nxtch; Yap_ErrorMessage = NULL; - ch = Nextch(Yap_c_input_stream); + ch = Nxtch(-1); if (ch == '-') { sign = -1; - ch = Nextch(Yap_c_input_stream); + ch = Nxtch(-1); } else if (ch == '+') { - ch = Nextch(Yap_c_input_stream); + ch = Nxtch(-1); } if (chtype[ch] != NU) { return(TermNil); } - out = get_num(); + cherr = 0; + out = get_num(&ch, &cherr, -1, Nxtch, Nxtch); if (sign == -1) { if (IsIntegerTerm(out)) out = MkIntegerTerm(-IntegerOfTerm(out)); else if (IsFloatTerm(out)) out = MkFloatTerm(-FloatOfTerm(out)); } - if (Yap_ErrorMessage != NULL || ch != -1) + if (Yap_ErrorMessage != NULL || ch != -1 || cherr) return(TermNil); return(out); } -/* gets a token */ - -static enum TokenKinds -token(void) +TokEntry * +Yap_tokenizer(int inp_stream) { - int och, quote, isvar; - char *charp, *mp; - unsigned int len; + TokEntry *t, *l, *p; + enum TokenKinds kind; + int solo_flag = TRUE; + int ch; + int (*Nxtch) (int) = Stream[inp_stream].stream_getc_for_read; + int (*QuotedNxtch) (int) = Stream[inp_stream].stream_getc; - TokImage = ((AtomEntry *) ( Yap_PreAllocCodeSpace()))->StrOfAE; - charp = TokImage; - while (chtype[ch] == BS) - my_getch(); - TokenPos = GetCurInpPos(); - switch (chtype[ch]) { - case CC: - while (my_getch() != 10 && chtype[ch] != EF); - if (chtype[ch] != EF) { - Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage); - return (token()); - } else { - Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage); - return (eot_tok); - } - case UC: - case UL: - case LC: - isvar = (chtype[ch] != LC); - *charp++ = ch; - for (my_getch(); chtype[ch] <= NU; my_getch()) - *charp++ = ch; - *charp++ = '\0'; - if (!isvar) { - /* don't do this in iso */ - TokenInfo = Unsigned(Yap_LookupAtom(TokImage)); - Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage); - return (Name_tok); - } - else { - TokenInfo = Unsigned(Yap_LookupVar(TokImage)); - Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage); - return (Var_tok); - } + Yap_ErrorMessage = NULL; + Yap_VarTable = NULL; + Yap_AnonVarTable = NULL; + Yap_eot_before_eof = FALSE; + l = NIL; + p = NIL; /* Just to make lint happy */ + ch = Nxtch(inp_stream); + do { + int och, quote, isvar; + char *charp, *mp; + unsigned int len; + char *TokImage = NULL; - case NU: - TokenInfo = get_num(); - Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage); - return (Number_tok); - case QT: - case DC: - quote = ch; - len = 0; - my_get_quoted_ch(); - while (1) { - if (charp + 1024 > (char *)AuxSp) { - Yap_ErrorMessage = "Heap Overflow While Scanning: please increase code space (-h)"; - break; - } - 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; - } - if (ch == quote) { - my_get_quoted_ch(); - if (ch != quote) - break; - *charp++ = ch; - my_get_quoted_ch(); - } else if (ch == '\\' && yap_flags[CHARACTER_ESCAPE_FLAG] != CPROLOG_CHARACTER_ESCAPES) { - /* escape sequence */ - ch = my_get_quoted_ch(); - switch (ch) { - case 10: - /* don't add characters */ - my_get_quoted_ch(); - break; - case 'a': - *charp++ = '\a'; - my_get_quoted_ch(); - break; - case 'b': - *charp++ = '\b'; - my_get_quoted_ch(); - break; - case 'r': - *charp++ = '\r'; - my_get_quoted_ch(); - break; - case 'f': - *charp++ = '\f'; - my_get_quoted_ch(); - break; - case 't': - *charp++ = '\t'; - my_get_quoted_ch(); - break; - case 'n': - *charp++ = '\n'; - my_get_quoted_ch(); - break; - case 'v': - *charp++ = '\v'; - my_get_quoted_ch(); - break; - case '\\': - *charp++ = '\\'; - my_get_quoted_ch(); - break; - case '\'': - *charp++ = '\''; - my_get_quoted_ch(); - break; - case '"': - *charp++ = '"'; - my_get_quoted_ch(); - break; - case '`': - *charp++ = '`'; - my_get_quoted_ch(); - break; - 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 \ */ - { - unsigned char so_far = ch-'0'; - my_get_quoted_ch(); - if (ch >= '0' && ch < '8') {/* octal */ - so_far = so_far*8+(ch-'0'); - my_get_quoted_ch(); - if (ch >= '0' && ch < '8') { /* octal */ - *charp++ = so_far*8+(ch-'0'); - my_get_quoted_ch(); - if (ch != '\\') { - Yap_ErrorMessage = "invalid octal escape sequence"; - } else { - my_get_quoted_ch(); - } - } else if (ch == '\\') { - *charp++ = so_far; - my_get_quoted_ch(); - } else { - Yap_ErrorMessage = "invalid octal escape sequence"; - } - } else if (ch == '\\') { - *charp++ = so_far; - my_get_quoted_ch(); - } else { - Yap_ErrorMessage = "invalid octal escape sequence"; - } - } - break; - case 'x': - /* hexadecimal character (YAP allows empty hexadecimal */ - { - unsigned char so_far = 0; - my_get_quoted_ch(); - if (my_isxdigit(ch,'f','F')) {/* hexa */ - so_far = so_far * 16 + (chtype[ch] == NU ? ch - '0' : - (my_isupper(ch) ? ch - 'A' : ch - 'a') + 10); - my_get_quoted_ch(); - if (my_isxdigit(ch,'f','F')) { /* hexa */ - *charp++ = so_far * 16 + (chtype[ch] == NU ? ch - '0' : - (my_isupper(ch) ? ch - 'A' : ch - 'a') + 10); - my_get_quoted_ch(); - if (ch != '\\') { - Yap_ErrorMessage = "invalid hexadecimal escape sequence"; - } else { - my_get_quoted_ch(); - } - } else if (ch == '\\') { - *charp++ = so_far; - my_get_quoted_ch(); - } else { - Yap_ErrorMessage = "invalid hexadecimal escape sequence"; - } - } else if (ch == '\\') { - *charp++ = so_far; - my_get_quoted_ch(); - } else { - Yap_ErrorMessage = "invalid hexadecimal escape sequence"; - } - } - break; - default: - /* accept sequence. Note that the ISO standard does not - consider this sequence legal, whereas SICStus would - eat up the escape sequence. */ - Yap_ErrorMessage = "invalid escape sequence"; - } - } else if (chtype[ch] == EF) { - Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage); - return (eot_tok); + t = (TokEntry *) AllocScannerMemory(sizeof(TokEntry)); + t->TokNext = NULL; + if (t == NULL) { + Yap_ErrorMessage = "not enough stack space to read in term"; + if (p != NIL) + p->TokInfo = eot_tok; + /* serious error now */ + return(l); + } + if (l == NIL) + l = t; + else + p->TokNext = t; + p = t; + restart: + while (chtype[ch] == BS) { + ch = Nxtch(inp_stream); + } + t->TokPos = GetCurInpPos(); + + switch (chtype[ch]) { + + case CC: + while ((ch = Nxtch(inp_stream)) != 10 && chtype[ch] != EF); + if (chtype[ch] != EF) { + /* blank space */ + goto restart; } else { - *charp++ = ch; - my_get_quoted_ch(); + t->Tok = Ord(kind = eot_tok); } - ++len; - if (charp > (char *)AuxSp - 1024) { - /* Not enough space to read in the string. */ - Yap_ErrorMessage = "not enough heap space to read in string or quoted atom"; - /* serious error now */ - Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage); - return(eot_tok); - } - } - *charp = '\0'; - if (quote == '"') { - mp = AllocScannerMemory(len + 1); - if (mp == NULL) { - Yap_ErrorMessage = "not enough stack space to read in string or quoted atom"; - Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage); - return(eot_tok); - } - strcpy(mp, TokImage); - TokenInfo = Unsigned(mp); - Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage); - return (String_tok); - } - else { - TokenInfo = Unsigned(Yap_LookupAtom(TokImage)); - Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage); - return (Name_tok); - } + break; - case SY: - och = ch; - my_getch(); - if (och == '/' && ch == '*') { - while ((och != '*' || ch != '/') && chtype[ch] != EF) { - och = ch; - my_getch(); - } - if (chtype[ch] == EF) { - Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage); - return (eot_tok); - } - my_getch(); - Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage); - return (token()); - } - if (och == '.' && (chtype[ch] == BS || chtype[ch] == EF - || chtype[ch] == CC)) { - Yap_eot_before_eof = TRUE; - if (chtype[ch] == CC) - while (my_getch() != 10 && chtype[ch] != EF); - Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage); - return (eot_tok); - } - else { + case UC: + case UL: + case LC: + och = ch; + ch = Nxtch(inp_stream); + scan_name: + TokImage = ((AtomEntry *) ( Yap_PreAllocCodeSpace()))->StrOfAE; + charp = TokImage; + isvar = (chtype[och] != LC); *charp++ = och; - for (; chtype[ch] == SY; my_getch()) + for (; chtype[ch] <= NU; ch = Nxtch(inp_stream)) *charp++ = ch; - *charp = '\0'; - TokenInfo = Unsigned(Yap_LookupAtom(TokImage)); - Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage); - return (Name_tok); - } - - case SL: - *charp++ = ch; - *charp++ = '\0'; - my_getch(); - TokenInfo = Unsigned(Yap_LookupAtom(TokImage)); - Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage); - return (Name_tok); - - case BK: - och = ch; - do { - my_getch(); - } while (chtype[ch] == BS); - if (och == '[' && ch == ']') { - TokenInfo = Unsigned(AtomNil); - my_getch(); - Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage); - return (Name_tok); - } - else { - TokenInfo = och; - Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage); - return (Ponctuation_tok); - } - - case EF: - Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage); - return (eot_tok); -#ifdef DEBUG - default: - fprintf(Yap_stderr, "\n++++ token: wrong char type %c %d\n", ch, chtype[ch]); - Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage); - return (eot_tok); -#else - default: - Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage); - return (eot_tok); /* Just to make lint happy */ -#endif - } -} - -TokEntry * -Yap_tokenizer(int (*Nxtch) (int), int (*QuotedNxtch) (int)) -{ - TokEntry *t, *l, *p; - enum TokenKinds kind; - int solo_flag = TRUE; - - Yap_ErrorMessage = NULL; - Yap_VarTable = NULL; - Yap_AnonVarTable = NULL; - Nextch = Nxtch; - QuotedNextch = QuotedNxtch; - Yap_eot_before_eof = FALSE; - l = NIL; - p = NIL; /* Just to make lint happy */ - ch = ' '; - my_getch(); - while (chtype[ch] == BS) { - my_getch(); - } - do { - t = (TokEntry *) AllocScannerMemory(sizeof(TokEntry)); - if (t == NULL) { - Yap_ErrorMessage = "not enough stack space to read in term"; - if (p != NIL) - p->TokInfo = eot_tok; - /* serious error now */ - return(l); - } - - if (l == NIL) - l = t; - else - p->TokNext = t; - p = t; - if ((kind = token()) == Name_tok && ch == '(') - solo_flag = FALSE; - else if (kind == Ponctuation_tok && TokenInfo == '(' && !solo_flag) { - TokenInfo = 'l'; - solo_flag = TRUE; - } - t->Tok = Ord(kind); -#ifdef DEBUG - if(Yap_Option[2]) fprintf(Yap_stderr,"[Token %d %ld]",Ord(kind),(unsigned long int)TokenInfo); -#endif - t->TokInfo = (Term) TokenInfo; - t->TokPos = TokenPos; - t->TokNext = NIL; - if (Yap_ErrorMessage) { - /* insert an error token to inform the system on what happened */ - TokEntry *e = (TokEntry *) AllocScannerMemory(sizeof(TokEntry)); - if (e == NULL) { - Yap_ErrorMessage = "not enough stack space to read in term"; - p->TokInfo = eot_tok; - /* serious error now */ - return(l); - } - p->TokNext = e; - e->Tok = Error_tok; - e->TokInfo = MkAtomTerm(Yap_LookupAtom(Yap_ErrorMessage)); - e->TokPos = TokenPos; - e->TokNext = NIL; - Yap_ErrorMessage = NULL; - p = e; - } - } while (kind != eot_tok); - return (l); -} - -#if DEBUG -static inline int -debug_fgetch(void) -{ - int ch = Yap_PlFGetchar(); - if (Yap_Option[1]) - fprintf(Yap_stderr, "[getch %c,%d]", ch,ch); - return (ch); -} -#define my_fgetch() (ch = debug_fgetch()) -#else -#define my_fgetch() (ch = Yap_PlFGetchar()) -#endif - -TokEntry * -Yap_fast_tokenizer(void) -{ - /* I hope, a compressed version of the last - * three files */ - - TokEntry *t, *l, *p; - enum TokenKinds kind; - register int ch, och; - int solo_flag = TRUE; - - Yap_ErrorMessage = NULL; - Yap_VarTable = NULL; - Yap_AnonVarTable = NULL; - Yap_eot_before_eof = FALSE; - l = NIL; - p = NIL; /* Just to make lint happy */ - my_fgetch(); - while (chtype[ch] == BS) - my_fgetch(); - if (chtype[ch] == EF) - return(NIL); - do { - t = (TokEntry *) AllocScannerMemory(sizeof(TokEntry)); - if (t == NULL) { - Yap_ErrorMessage = "not enough stack space to read in term"; - if (p != NIL) - p->TokInfo = eot_tok; - /* serious error now */ - return(l); - } - - if (l == NIL) - l = t; - else - p->TokNext = t; - p = t; - /* old code for token() */ - { - int quote, isvar; - char *charp, *mp; - unsigned int len; - - get_tok: - - charp = TokImage = ((AtomEntry *) ( Yap_PreAllocCodeSpace()))->StrOfAE; - while (chtype[ch] == BS) - my_fgetch(); - TokenPos = GetCurInpPos(); - switch (chtype[ch]) { - case CC: - while (my_fgetch() != 10 && chtype[ch] != EF); - if (chtype[ch] != EF) { - my_fgetch(); - Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage); - goto get_tok; - } - else - kind = eot_tok; - break; - case UC: - case UL: - case LC: - isvar = (chtype[ch] != LC); - *charp++ = ch; - - inside_letters: - - for (my_fgetch(); chtype[ch] <= NU; my_fgetch()) - *charp++ = ch; - *charp++ = '\0'; - if (!isvar) { - TokenInfo = Unsigned(Yap_LookupAtom(TokImage)); - if (ch == '(') - solo_flag = FALSE; - kind = Name_tok; - } - else { - TokenInfo = Unsigned(Yap_LookupVar(TokImage)); - kind = Var_tok; - } - break; - - case NU: - - { - char *sp = TokImage; - Int val = 0, base = ch - '0'; - int might_be_float = TRUE, has_overflow = FALSE; - - *sp++ = ch; - my_fgetch(); - /* - * because of things like 00'2, 03'2 - * and even better 12'2, I need to do - * this (have mercy) - */ - if (chtype[ch] == NU) { - *sp++ = ch; - base = 10 * base + ch - '0'; - my_fgetch(); - } - if (ch == '\'') { - might_be_float = FALSE; - *sp++ = ch; - restart: - my_fgetch(); - if (base == 0) { - Int ascii = ch; - - /* - * a quick way to - * represent ASCII - */ - if (ch == '\\' && - yap_flags[CHARACTER_ESCAPE_FLAG] != CPROLOG_CHARACTER_ESCAPES) { - /* escape sequence */ - my_fgetch(); - switch (ch) { - case 10: - goto restart; - case 'a': - ascii = '\a'; - break; - case 'b': - ascii = '\b'; - break; - case 'r': - ascii = '\r'; - break; - case 'f': - ascii = '\f'; - break; - case 't': - ascii = '\t'; - break; - case 'n': - ascii = '\n'; - break; - case 'v': - ascii = '\v'; - break; - case '\\': - ascii = '\\'; - break; - case '\'': - ascii = '\''; - break; - case '"': - ascii = '"'; - break; - case '`': - ascii = '`'; - break; - 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 \ */ - { - unsigned char so_far = ch-'0'; - my_fgetch(); - if (ch >= '0' && ch < '8') {/* octal */ - so_far = so_far*8+(ch-'0'); - my_fgetch(); - if (ch >= '0' && ch < '8') { /* octal */ - ascii = so_far*8+(ch-'0'); - my_fgetch(); - if (ch != '\\') { - Yap_ErrorMessage = "invalid octal escape sequence"; - } - } else if (ch == '\\') { - ascii = so_far; - } else { - Yap_ErrorMessage = "invalid octal escape sequence"; - } - } else if (ch == '\\') { - ascii = so_far; - } else { - Yap_ErrorMessage = "invalid octal escape sequence"; - } - } - break; - case 'x': - /* hexadecimal character (YAP allows empty hexadecimal */ - { - unsigned char so_far = 0; - my_fgetch(); - if (my_isxdigit(ch,'f','F')) {/* hexa */ - so_far = so_far * 16 + (chtype[ch] == NU ? ch - '0' : - (my_isupper(ch) ? ch - 'A' : ch - 'a') + 10); - my_fgetch(); - if (my_isxdigit(ch,'f','F')) { /* hexa */ - ascii = so_far * 16 + (chtype[ch] == NU ? ch - '0' : - (my_isupper(ch) ? ch - 'A' : ch - 'a') + 10); - my_fgetch(); - if (ch != '\\') { - Yap_ErrorMessage = "invalid hexadecimal escape sequence"; - } - } else if (ch == '\\') { - ascii = so_far; - } else { - Yap_ErrorMessage = "invalid hexadecimal escape sequence"; - } - } else if (ch == '\\') { - ascii = so_far; - my_fgetch(); - } else { - Yap_ErrorMessage = "invalid hexadecimal escape sequence"; - } - } - break; - default: - /* accept sequence. Note that the ISO standard does not - consider this sequence legal, whereas SICStus would - eat up the escape sequence. */ - Yap_ErrorMessage = "invalid escape sequence"; - } - } - my_fgetch(); - TokenInfo = (CELL) MkIntTerm(ascii); - goto end_of_read_number; - } - else if (base >= 10 && base <= 36) { - int upper_case = 'A' - 11 + base; - int lower_case = 'a' - 11 + base; - - while (my_isxdigit(ch, upper_case, lower_case)) { - Int oval = val; - - *sp++ = ch; - val = val * base + (chtype[ch] == NU ? ch - '0' : - (my_isupper(ch) ? ch - 'A' : ch - 'a') + 10); - if (oval >= val && oval != 0) /* overflow */ - has_overflow = (has_overflow || TRUE); - my_fgetch(); - } - } - } - else if ((ch == 'x' || ch == 'X') && base == 0) { - might_be_float = FALSE; - *sp++ = ch; - my_fgetch(); - while (my_isxdigit(ch, 'F', 'f')) { - Int oval = val; - - *sp++ = ch; - val = val * 16 + (chtype[ch] == NU ? ch - '0' : - (my_isupper(ch) ? ch - 'A' : ch - 'a') + 10); - if (oval >= val && oval != 0) /* overflow */ - has_overflow = (has_overflow || TRUE); - my_fgetch(); - } - } - else { - val = base; - base = 10; - } - while (chtype[ch] == NU) { - Int oval = val; - *sp++ = ch; - if (ch - '0' >= base) { - TokenInfo = (CELL) MkIntegerTerm(val); - goto end_of_read_number; - } - val = val * base + ch - '0'; - if (oval >= val && oval != 0) /* overflow */ - has_overflow = (has_overflow || TRUE); - my_fgetch(); - } - if (might_be_float && (ch == '.' || ch == 'e' || ch == 'E')) { - if (ch == '.') { - *sp++ = '.'; - if (chtype[my_fgetch()] != NU) { - /* - * first - * process - * the new - * token - */ - t->Tok = Ord(Number_tok); -#ifdef DEBUG - /* - * if(Yap_Option[2 - * ]) - * fprintf(Yap_stderr,"[To - * ken %d - * %d]",Ord(ki - * nd),TokenIn - * fo); - */ -#endif - if (has_overflow) - t->TokInfo = read_int_overflow(TokImage,base,val); - else - t->TokInfo = MkIntegerTerm(val); - t->TokPos = TokenPos; - t = (TokEntry *) AllocScannerMemory(sizeof(TokEntry)); - if (t == NULL) { - Yap_ErrorMessage = "not enough stack space to read in term"; - if (p != NIL) - p->TokInfo = eot_tok; - /* serious error now */ - Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage); - return(l); - } - - if (l == NIL) - l = t; - else - p->TokNext = t; - p = t; - - /* - * continue - * analysis - */ - och = '.'; - goto inside_symbol; - } - do - *sp++ = ch; - while (chtype[my_fgetch()] == NU); - } - if (ch == 'e' || ch == 'E') { - *sp++ = 'e'; - my_fgetch(); - if (ch == '-') { - *sp++ = ch; - my_fgetch(); - } - else if (ch == '+') - my_fgetch(); - if (chtype[ch] != NU) { - /* - * first - * finish - * processing - */ - --sp; - och = *sp; - *sp = '\0'; - /* - * first - * process - * the new - * token - */ - t->Tok = Ord(Number_tok); - t->TokPos = TokenPos; - t->TokInfo = float_send(TokImage); - t = - (TokEntry *) AllocScannerMemory(sizeof(TokEntry)); - if (t == NULL) { - Yap_ErrorMessage = "not enough stack space to read in term"; - if (p != NIL) - p->TokInfo = eot_tok; - /* serious error now */ - Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage); - return(l); - } - - if (l == NIL) - l = t; - else - p->TokNext = t; - p = t; - - /* - * now try to - * backtrack - * statically - */ - - if (chtype[och] == SY) - goto inside_symbol; - else { - charp = TokImage; - isvar = (chtype[och] != LC); - *charp++ = och; - goto inside_letters; - } - } - do - *sp++ = ch; - while (chtype[my_fgetch()] == NU); - } - *sp = '\0'; - TokenInfo = (CELL) float_send(TokImage); - goto end_of_read_number; - } - if (has_overflow) { - *sp = '\0'; - /* skip base */ - if (TokImage[0] == '0' && (TokImage[1] == 'x' || TokImage[1] == 'X')) - TokenInfo = read_int_overflow(TokImage+2,16,val); - else if (TokImage[1] == '\'') - TokenInfo = read_int_overflow(TokImage+2,base,val); - else if (TokImage[2] == '\'') - TokenInfo = read_int_overflow(TokImage+3,base,val); - else - TokenInfo = read_int_overflow(TokImage,base,val); - } else - TokenInfo = (CELL) MkIntegerTerm(val); - } - - end_of_read_number: - - kind = Number_tok; - break; - - case QT: - case DC: - quote = ch; - len = 0; - my_fgetch(); - while (1) { - if (charp + 1024 > (char *)AuxSp) { - Yap_ErrorMessage = "Heap Overflow While Scanning: please increase code space (-h)"; - break; - } - 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; - } - if (ch == quote) { - my_fgetch(); - if (ch != quote) - break; - *charp++ = ch; - my_fgetch(); - } else if (ch == '\\' && yap_flags[CHARACTER_ESCAPE_FLAG] != CPROLOG_CHARACTER_ESCAPES) { - /* escape sequence */ - my_fgetch(); - switch (ch) { - case 10: - /* just skip */ - my_fgetch(); - break; - case 'a': - *charp++ = '\a'; - my_fgetch(); - break; - case 'b': - *charp++ = '\b'; - my_fgetch(); - break; - case 'r': - *charp++ = '\r'; - my_fgetch(); - break; - case 'f': - *charp++ = '\f'; - my_fgetch(); - break; - case 't': - *charp++ = '\t'; - my_fgetch(); - break; - case 'n': - *charp++ = '\n'; - my_fgetch(); - break; - case 'v': - *charp++ = '\v'; - my_fgetch(); - break; - case '\\': - *charp++ = '\\'; - my_fgetch(); - break; - case '\'': - *charp++ = '\''; - my_fgetch(); - break; - case '"': - *charp++ = '"'; - my_fgetch(); - break; - case '`': - *charp++ = '`'; - my_fgetch(); - break; - 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 \ */ - { - unsigned char so_far = ch-'0'; - my_fgetch(); - if (ch >= '0' && ch < '8') {/* octal */ - so_far = so_far*8+(ch-'0'); - my_fgetch(); - if (ch >= '0' && ch < '8') { /* octal */ - *charp++ = so_far*8+(ch-'0'); - my_fgetch(); - if (ch != '\\') { - Yap_ErrorMessage = "invalid octal escape sequence"; - } else { - my_fgetch(); - } - } else if (ch == '\\') { - *charp++ = so_far; - my_fgetch(); - } else { - Yap_ErrorMessage = "invalid octal escape sequence"; - } - } else if (ch == '\\') { - *charp++ = so_far; - my_fgetch(); - } else { - Yap_ErrorMessage = "invalid octal escape sequence"; - } - } - break; - case 'x': - /* hexadecimal character (YAP allows empty hexadecimal */ - { - unsigned char so_far = 0; - my_fgetch(); - if (my_isxdigit(ch,'f','F')) {/* hexa */ - so_far = so_far * 16 + (chtype[ch] == NU ? ch - '0' : - (my_isupper(ch) ? ch - 'A' : ch - 'a') + 10); - my_fgetch(); - if (my_isxdigit(ch,'f','F')) { /* hexa */ - *charp++ = so_far * 16 + (chtype[ch] == NU ? ch - '0' : - (my_isupper(ch) ? ch - 'A' : ch - 'a') + 10); - my_fgetch(); - if (ch != '\\') { - Yap_ErrorMessage = "invalid hexadecimal escape sequence"; - } else { - my_fgetch(); - } - } else if (ch == '\\') { - *charp++ = so_far; - my_fgetch(); - } else { - Yap_ErrorMessage = "invalid hexadecimal escape sequence"; - } - } else if (ch == '\\') { - *charp++ = so_far; - my_fgetch(); - } else { - Yap_ErrorMessage = "invalid hexadecimal escape sequence"; - } - } - break; - default: - /* accept sequence. Note that the ISO standard does not - consider this sequence legal, whereas SICStus would - eat up the escape sequence. */ - Yap_ErrorMessage = "invalid escape sequence"; - } - } else { - *charp++ = ch; - my_fgetch(); - } - if (chtype[ch] == EF) { - kind = eot_tok; - break; - } - ++len; - if (charp > (char *)AuxSp - 1024) { - /* Not enough space to read in the string. */ - Yap_ErrorMessage = "not enough heap space to read in string or quoted atom"; - /* serious error now */ - kind = eot_tok; - } - } - *charp = '\0'; - if (quote == '"') { - mp = AllocScannerMemory(len + 1); - if (mp == NULL) { - Yap_ErrorMessage = "not enough stack space to read in string or quoted atom"; - /* serious error now */ - kind = eot_tok; - } - strcpy(mp, TokImage); - TokenInfo = Unsigned(mp); - kind = String_tok; - } - else { - TokenInfo = Unsigned(Yap_LookupAtom(TokImage)); - if (ch == '(') - solo_flag = FALSE; - kind = Name_tok; - } - break; - - case SY: - och = ch; - my_fgetch(); - inside_symbol: - if (och == '/' && ch == '*') { - while ((ch != '/' || och != '*') && chtype[ch] != EF) { - och = ch; - my_fgetch(); - } - if (chtype[ch] == EF) { - kind = eot_tok; - break; - } - my_fgetch(); - Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage); - goto get_tok; - } - if (och == '.' && (chtype[ch] == BS || chtype[ch] == EF - || chtype[ch] == CC)) { - Yap_eot_before_eof = TRUE; - if (chtype[ch] == CC) - while (my_fgetch() != 10 && chtype[ch] != EF); - kind = eot_tok; - } - else { - *charp++ = och; - for (; chtype[ch] == SY; my_fgetch()) - *charp++ = ch; - *charp = '\0'; - TokenInfo = Unsigned(Yap_LookupAtom(TokImage)); - if (ch == '(') - solo_flag = FALSE; - kind = Name_tok; - } - break; - - case SL: - *charp++ = ch; - *charp++ = '\0'; - my_fgetch(); - TokenInfo = Unsigned(Yap_LookupAtom(TokImage)); + *charp++ = '\0'; + if (!isvar) { + /* don't do this in iso */ + t->TokInfo = Unsigned(Yap_LookupAtom(TokImage)); + Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage); if (ch == '(') solo_flag = FALSE; - kind = Name_tok; - break; - - case BK: - och = ch; - do { - /* skip spaces to look for stuff such as [ ] */ - my_fgetch(); - } while (chtype[ch] == BS); - if (och == '[' && ch == ']') { - TokenInfo = Unsigned(AtomNil); - my_fgetch(); - if (ch == '(') - solo_flag = FALSE; - kind = Name_tok; - } - else { - if (!solo_flag && och == '(') { - TokenInfo = 'l'; - solo_flag = TRUE; - } - else - TokenInfo = och; - kind = Ponctuation_tok; - } - break; - - case EF: - kind = eot_tok; - break; -#ifdef DEBUG - default: - fprintf(Yap_stderr, "\n++++ token: wrong char type %c %d\n", ch, chtype[ch]); - kind = eot_tok; -#else - default: - kind = eot_tok; /* Just to make lint happy */ -#endif + t->Tok = Ord(kind = Name_tok); + } else { + t->TokInfo = Unsigned(Yap_LookupVar(TokImage)); + Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage); + t->Tok = Ord(kind = Var_tok); } - } + break; - t->Tok = Ord(kind); + case NU: + { + int cherr, cha = ch; + cherr = 0; + t->TokInfo = get_num(&cha,&cherr,inp_stream,Nxtch,QuotedNxtch); + ch = cha; + if (cherr) { + TokEntry *e; + t->Tok = Number_tok; + t->TokPos = GetCurInpPos(); + e = (TokEntry *) AllocScannerMemory(sizeof(TokEntry)); + if (e == NULL) { + Yap_ErrorMessage = "not enough stack space to read in term"; + p->TokInfo = eot_tok; + /* serious error now */ + return(l); + } + t->TokNext = e; + t = e; + p = e; + switch (cherr) { + case 'e': + case 'E': + och = cherr; + goto scan_name; + break; + case '=': + case '_': + /* handle error while parsing a float */ + { + TokEntry *e2; + + t->Tok = Ord(Var_tok); + t->TokInfo = Unsigned(Yap_LookupVar("E")); + t->TokPos = GetCurInpPos(); + e2 = (TokEntry *) AllocScannerMemory(sizeof(TokEntry)); + if (e2 == NULL) { + Yap_ErrorMessage = "not enough stack space to read in term"; + p->TokInfo = eot_tok; + /* serious error now */ + return(l); + } + 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; + t->TokInfo = Unsigned(Yap_LookupAtom("e")); + t->TokPos = GetCurInpPos(); + e2 = (TokEntry *) AllocScannerMemory(sizeof(TokEntry)); + if (e2 == NULL) { + Yap_ErrorMessage = "not enough stack space to read in term"; + p->TokInfo = eot_tok; + /* serious error now */ + return(l); + } + t->TokNext = e2; + t = e2; + p = e2; + } + default: + och = cherr; + goto enter_symbol; + } + } else { + t->Tok = Ord(kind = Number_tok); + } + } + break; + + case QT: + case DC: + TokImage = ((AtomEntry *) ( Yap_PreAllocCodeSpace()))->StrOfAE; + charp = TokImage; + quote = ch; + len = 0; + ch = QuotedNxtch(inp_stream); + while (1) { + if (charp + 1024 > (char *)AuxSp) { + Yap_ErrorMessage = "Heap Overflow While Scanning: please increase code space (-h)"; + break; + } + 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; + } + if (ch == quote) { + ch = QuotedNxtch(inp_stream); + if (ch != quote) + break; + *charp++ = ch; + ch = QuotedNxtch(inp_stream); + } else if (ch == '\\' && yap_flags[CHARACTER_ESCAPE_FLAG] != CPROLOG_CHARACTER_ESCAPES) { + int scan_next = TRUE; + *charp++ = read_quoted_char(&scan_next, inp_stream, QuotedNxtch); + if (scan_next) { + ch = QuotedNxtch(inp_stream); + } + } else if (chtype[ch] == EF) { + Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage); + t->Tok = Ord(kind = eot_tok); + } else { + *charp++ = ch; + ch = QuotedNxtch(inp_stream); + } + ++len; + if (charp > (char *)AuxSp - 1024) { + /* Not enough space to read in the string. */ + Yap_ErrorMessage = "not enough heap space to read in string or quoted atom"; + /* serious error now */ + Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage); + t->Tok = Ord(kind = eot_tok); + } + } + *charp = '\0'; + if (quote == '"') { + mp = AllocScannerMemory(len + 1); + if (mp == NULL) { + Yap_ErrorMessage = "not enough stack space to read in string or quoted atom"; + Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage); + t->Tok = Ord(kind = eot_tok); + } + strcpy(mp, TokImage); + t->TokInfo = Unsigned(mp); + Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage); + t->Tok = Ord(kind = String_tok); + } else { + t->TokInfo = Unsigned(Yap_LookupAtom(TokImage)); + Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage); + t->Tok = Ord(kind = Name_tok); + if (ch == '(') + solo_flag = FALSE; + } + break; + + case SY: + och = ch; + ch = Nxtch(inp_stream); + if (och == '/' && ch == '*') { + while ((och != '*' || ch != '/') && chtype[ch] != EF) { + och = ch; + ch = Nxtch(inp_stream); + } + if (chtype[ch] == EF) { + t->Tok = Ord(kind = eot_tok); + } + ch = Nxtch(inp_stream); + goto restart; + } + enter_symbol: + if (och == '.' && (chtype[ch] == BS || chtype[ch] == EF + || chtype[ch] == CC)) { + Yap_eot_before_eof = TRUE; + if (chtype[ch] == CC) + while ((ch = Nxtch(inp_stream)) != 10 && chtype[ch] != EF); + t->Tok = Ord(kind = eot_tok); + } + else { + TokImage = ((AtomEntry *) ( Yap_PreAllocCodeSpace()))->StrOfAE; + charp = TokImage; + *charp++ = och; + for (; chtype[ch] == SY; ch = Nxtch(inp_stream)) + *charp++ = ch; + *charp = '\0'; + t->TokInfo = Unsigned(Yap_LookupAtom(TokImage)); + Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage); + t->Tok = Ord(kind = Name_tok); + if (ch == '(') + solo_flag = FALSE; + } + break; + + case SL: + { + char chs[2]; + chs[0] = ch; + chs[1] = '\0'; + ch = Nxtch(inp_stream); + t->TokInfo = Unsigned(Yap_LookupAtom(chs)); + t->Tok = Ord(kind = Name_tok); + if (ch == '(') + solo_flag = FALSE; + } + break; + + case BK: + och = ch; + do { + ch = Nxtch(inp_stream); + } while (chtype[ch] == BS); + if (och == '[' && ch == ']') { + t->TokInfo = Unsigned(AtomNil); + ch = Nxtch(inp_stream); + t->Tok = Ord(kind = Name_tok); + if (ch == '(') + solo_flag = FALSE; + } else { + t->TokInfo = och; + if (t->TokInfo == '(' && !solo_flag) { + t->TokInfo = 'l'; + solo_flag = TRUE; + } + t->Tok = Ord(kind = Ponctuation_tok); + } + break; + + case EF: + t->Tok = Ord(kind = eot_tok); + break; + + default: #ifdef DEBUG - if(Yap_Option[2]) fprintf(Yap_stderr,"[Token %d %ld]\n",Ord(kind),(unsigned long int)TokenInfo); + fprintf(Yap_stderr, "\n++++ token: wrong char type %c %d\n", ch, chtype[ch]); +#endif + t->Tok = Ord(kind = eot_tok); + } +#ifdef DEBUG + if(Yap_Option[2]) fprintf(Yap_stderr,"[Token %d %ld]",Ord(kind),(unsigned long int)t->TokInfo); #endif - t->TokInfo = (Term) TokenInfo; - t->TokPos = TokenPos; - t->TokNext = NIL; - Yap_ReleasePreAllocCodeSpace((CODEADDR)TokImage); if (Yap_ErrorMessage) { /* insert an error token to inform the system on what happened */ TokEntry *e = (TokEntry *) AllocScannerMemory(sizeof(TokEntry)); @@ -1607,7 +897,7 @@ Yap_fast_tokenizer(void) p->TokNext = e; e->Tok = Error_tok; e->TokInfo = MkAtomTerm(Yap_LookupAtom(Yap_ErrorMessage)); - e->TokPos = TokenPos; + e->TokPos = GetCurInpPos(); e->TokNext = NIL; Yap_ErrorMessage = NULL; p = e; diff --git a/C/stdpreds.c b/C/stdpreds.c index 5e62fcc04..397f0da12 100644 --- a/C/stdpreds.c +++ b/C/stdpreds.c @@ -312,7 +312,7 @@ strtod(s, pe) static char *cur_char_ptr; static int -get_char_from_string(int sno) +get_char_from_string(void) { if (cur_char_ptr[0] == '\0') return(-1); diff --git a/H/yapio.h b/H/yapio.h index de33a8d11..7dbb9ead3 100644 --- a/H/yapio.h +++ b/H/yapio.h @@ -267,8 +267,7 @@ VarEntry STD_PROTO(*Yap_LookupVar,(char *)); Term STD_PROTO(Yap_VarNames,(VarEntry *,Term)); /* routines ins scanner.c */ -TokEntry STD_PROTO(*Yap_tokenizer,(int (*)(int), int (*)(int))); -TokEntry STD_PROTO(*Yap_fast_tokenizer,(void)); +TokEntry STD_PROTO(*Yap_tokenizer,(int)); Term STD_PROTO(Yap_scan_num,(int (*)(int))); char STD_PROTO(*Yap_AllocScannerMemory,(unsigned int)); diff --git a/library/Tries/tries.h b/library/Tries/tries.h index c55652a0e..efc18b703 100644 --- a/library/Tries/tries.h +++ b/library/Tries/tries.h @@ -4,9 +4,19 @@ * Comments: Tries module for yap * ******************************************/ -/* ----------------------------- */ -/* Structs and Defines */ -/* ----------------------------- */ +/* --------------------------- */ +/* Defines */ +/* --------------------------- */ + +#define TERM_STACK_SIZE 1000 +#define MODE_STANDARD 0 +#define MODE_REVERSE 1 + + + +/* --------------------------- */ +/* Structs */ +/* --------------------------- */ struct trie_stats { long memory_in_use; @@ -19,6 +29,15 @@ struct trie_stats { long buckets_max_used; } STATS; +#define MEMORY_IN_USE (STATS.memory_in_use) +#define MEMORY_MAX_USED (STATS.memory_max_used) +#define NODES_IN_USE (STATS.nodes_in_use) +#define NODES_MAX_USED (STATS.nodes_max_used) +#define HASHES_IN_USE (STATS.hashes_in_use) +#define HASHES_MAX_USED (STATS.hashes_max_used) +#define BUCKETS_IN_USE (STATS.buckets_in_use) +#define BUCKETS_MAX_USED (STATS.buckets_max_used) + typedef struct trie_node { YAP_Term entry; int hits; @@ -28,6 +47,13 @@ typedef struct trie_node { struct trie_node *previous; } *TrNode; +#define TrNode_entry(X) ((X)->entry) +#define TrNode_hits(X) ((X)->hits) +#define TrNode_parent(X) ((X)->parent) +#define TrNode_child(X) ((X)->child) +#define TrNode_next(X) ((X)->next) +#define TrNode_previous(X) ((X)->previous) + typedef struct trie_hash { YAP_Term entry; /* for compatibility with the trie_node data structure */ int number_of_buckets; @@ -37,22 +63,6 @@ typedef struct trie_hash { struct trie_hash *previous; } *TrHash; -#define MEMORY_IN_USE (STATS.memory_in_use) -#define MEMORY_MAX_USED (STATS.memory_max_used) -#define NODES_IN_USE (STATS.nodes_in_use) -#define NODES_MAX_USED (STATS.nodes_max_used) -#define HASHES_IN_USE (STATS.hashes_in_use) -#define HASHES_MAX_USED (STATS.hashes_max_used) -#define BUCKETS_IN_USE (STATS.buckets_in_use) -#define BUCKETS_MAX_USED (STATS.buckets_max_used) - -#define TrNode_entry(X) ((X)->entry) -#define TrNode_hits(X) ((X)->hits) -#define TrNode_parent(X) ((X)->parent) -#define TrNode_child(X) ((X)->child) -#define TrNode_next(X) ((X)->next) -#define TrNode_previous(X) ((X)->previous) - #define TrHash_mark(X) ((X)->entry) #define TrHash_num_buckets(X) ((X)->number_of_buckets) #define TrHash_seed(X) ((X)->number_of_buckets - 1) @@ -62,16 +72,20 @@ typedef struct trie_hash { #define TrHash_next(X) ((X)->next) #define TrHash_previous(X) ((X)->previous) -#define TYPE_TR_NODE struct trie_node -#define TYPE_TR_HASH struct trie_hash -#define SIZEOF_TR_NODE sizeof(TYPE_TR_NODE) -#define SIZEOF_TR_HASH sizeof(TYPE_TR_HASH) -#define SIZEOF_TR_BUCKET sizeof(TYPE_TR_NODE *) +#define TYPE_TR_NODE struct trie_node +#define TYPE_TR_HASH struct trie_hash +#define SIZEOF_TR_NODE sizeof(TYPE_TR_NODE) +#define SIZEOF_TR_HASH sizeof(TYPE_TR_HASH) +#define SIZEOF_TR_BUCKET sizeof(TYPE_TR_NODE *) #define AS_TR_NODE_NEXT(ADDRESS) (TrNode)((int)(ADDRESS) - sizeof(YAP_Term) - sizeof(int) - 2 * sizeof(struct trie_node *)) #define AS_TR_HASH_NEXT(ADDRESS) (TrHash)((int)(ADDRESS) - sizeof(YAP_Term) - 2 * sizeof(int) - sizeof(struct trie_node **)) -#define TERM_STACK_SIZE 1000 + + +/* --------------------------- */ +/* Macros */ +/* --------------------------- */ #define MkTrieVar(INDEX) ((INDEX) << 4) #define TrieVarIndex(TERM) ((TERM) >> 4) @@ -90,12 +104,12 @@ typedef struct trie_hash { #define PUSH_DOWN(STACK, ITEM, STACK_TOP) \ { if (STACK > STACK_TOP) \ fprintf(stderr, "\nTries module: TERM_STACK full"); \ - *STACK++ = (YAP_Term)(ITEM); \ + *STACK++ = (YAP_Term)(ITEM); \ } #define PUSH_UP(STACK, ITEM, STACK_TOP) \ { if (STACK < STACK_TOP) \ fprintf(stderr, "\nTries module: TERM_STACK full"); \ - *STACK-- = (YAP_Term)(ITEM); \ + *STACK-- = (YAP_Term)(ITEM); \ } @@ -103,7 +117,7 @@ typedef struct trie_hash { #define new_struct(STR, STR_TYPE, STR_SIZE) \ STR = (STR_TYPE *) YAP_AllocSpaceFromYap(STR_SIZE) #define free_struct(STR) \ - YAP_FreeSpaceFromYap((void *) (STR)) + YAP_FreeSpaceFromYap((char *) (STR)) #define free_trie_node(STR) \ free_struct(STR); \ STATS_node_dec() @@ -177,18 +191,20 @@ typedef struct trie_hash { -/* ------------- */ -/* API */ -/* ------------- */ +/* --------------------------- */ +/* API */ +/* --------------------------- */ +extern int MODE; extern TrNode TRIES; extern TrHash HASHES; +extern YAP_Functor FunctorComma; -TrNode open_trie(void); -void close_trie(TrNode node); -void close_all_tries(void); -TrNode put_trie_entry(TrNode node, YAP_Term entry); -YAP_Term get_trie_entry(TrNode node); -void remove_trie_entry(TrNode node); -void trie_stats(void); -void print_trie(TrNode node); +TrNode open_trie(void); +void close_trie(TrNode node); +void close_all_tries(void); +TrNode put_trie_entry(TrNode node, YAP_Term entry); +YAP_Term get_trie_entry(TrNode node); +void remove_trie_entry(TrNode node); +void trie_stats(void); +void print_trie(TrNode node); diff --git a/library/Tries/yap_tries.c b/library/Tries/yap_tries.c index b9b967fdc..488997584 100644 --- a/library/Tries/yap_tries.c +++ b/library/Tries/yap_tries.c @@ -6,13 +6,12 @@ #include "config.h" #include "YapInterface.h" - #include #if HAVE_STRING_H #include #endif -#include "tries.h" +#include "tries.h" #include "tries.c" void init_tries(void); @@ -38,89 +37,109 @@ void init_tries(void) { BUCKETS_IN_USE = 0; BUCKETS_MAX_USED = 0; - YAP_UserCPredicate("open_trie", p_open_trie, 1); /* -> Ref */ - YAP_UserCPredicate("close_trie", p_close_trie, 1); /* Ref -> */ - YAP_UserCPredicate("close_all_tries", p_close_all_tries, 0); /* -> */ - YAP_UserCPredicate("put_trie_entry", p_put_trie_entry, 3); /* Ref x Entry -> Ref */ - YAP_UserCPredicate("get_trie_entry", p_get_trie_entry, 2); /* Ref -> Entry */ - YAP_UserCPredicate("remove_trie_entry", p_remove_trie_entry, 1); /* Ref -> */ - YAP_UserCPredicate("trie_statistics", p_trie_stats, 0); /* -> */ - YAP_UserCPredicate("print_trie", p_print_trie, 1); /* Ref -> */ + FunctorComma = YAP_MkFunctor(YAP_LookupAtom(","), 2); + + YAP_UserCPredicate("open_trie", p_open_trie, 1); /* -> Trie */ + YAP_UserCPredicate("close_trie", p_close_trie, 1); /* Trie -> */ + YAP_UserCPredicate("close_all_tries", p_close_all_tries, 0); /* -> */ + YAP_UserCPredicate("put_trie_entry", p_put_trie_entry, 4); /* Mode x Trie x Entry -> Ref */ + YAP_UserCPredicate("get_trie_entry", p_get_trie_entry, 3); /* Mode x Ref -> Entry */ + YAP_UserCPredicate("remove_trie_entry", p_remove_trie_entry, 1); /* Ref -> */ + YAP_UserCPredicate("trie_statistics", p_trie_stats, 0); /* -> */ + YAP_UserCPredicate("print_trie", p_print_trie, 1); /* Trie -> */ return; } -/* open_trie(+Ref) */ +/* open_trie(+Trie) */ static int p_open_trie(void) { - YAP_Term arg1 = YAP_ARG1; + YAP_Term arg_trie = YAP_ARG1; TrNode node; /* check arg */ - if (!YAP_IsVarTerm(arg1)) + if (!YAP_IsVarTerm(arg_trie)) return FALSE; + /* open trie */ node = open_trie(); - /* return node reference */ - if (!YAP_Unify(arg1, YAP_MkIntTerm((int) node))) + if (!YAP_Unify(arg_trie, YAP_MkIntTerm((int) node))) return FALSE; return TRUE; } -/* close_trie(-Ref) */ +/* close_trie(-Trie) */ static int p_close_trie(void) { - YAP_Term arg1 = YAP_ARG1; + YAP_Term arg_trie = YAP_ARG1; /* check args */ - if (!YAP_IsIntTerm(arg1)) + if (!YAP_IsIntTerm(arg_trie)) return FALSE; - /* free trie */ - close_trie((TrNode) YAP_IntOfTerm(arg1)); + + /* close trie */ + close_trie((TrNode) YAP_IntOfTerm(arg_trie)); return TRUE; } /* close_all_tries() */ static int p_close_all_tries(void) { - /* close all tries */ close_all_tries(); return TRUE; } -/* put_trie_entry(-Ref,-Entry,+Ref) */ +/* put_trie_entry(-Mode,-Trie,-Entry,+Ref) */ static int p_put_trie_entry(void) { - YAP_Term arg1 = YAP_ARG1; - YAP_Term arg2 = YAP_ARG2; - YAP_Term arg3 = YAP_ARG3; + YAP_Term arg_mode = YAP_ARG1; + YAP_Term arg_trie = YAP_ARG2; + YAP_Term arg_entry = YAP_ARG3; + YAP_Term arg_ref = YAP_ARG4; TrNode node; + char *mode_str; /* check args */ - if (!YAP_IsIntTerm(arg1)) + mode_str = YAP_AtomName(YAP_AtomOfTerm(arg_mode)); + if (!strcmp(mode_str, "std")) { + MODE = MODE_STANDARD; + } else if (!strcmp(mode_str, "rev")) { + MODE = MODE_REVERSE; + } else return FALSE; - /* put entry */ - node = put_trie_entry((TrNode) YAP_IntOfTerm(arg1), arg2); - /* return node reference */ - if (!YAP_Unify(arg3, YAP_MkIntTerm((int) node))) + if (!YAP_IsIntTerm(arg_trie)) + return FALSE; + + /* put trie entry */ + node = put_trie_entry((TrNode) YAP_IntOfTerm(arg_trie), arg_entry); + if (!YAP_Unify(arg_ref, YAP_MkIntTerm((int) node))) return FALSE; return TRUE; } -/* get_trie_entry(-Ref,+Entry) */ +/* get_trie_entry(-Mode,-Ref,+Entry) */ static int p_get_trie_entry(void) { - YAP_Term arg1 = YAP_ARG1; - YAP_Term arg2 = YAP_ARG2; + YAP_Term arg_mode = YAP_ARG1; + YAP_Term arg_ref = YAP_ARG2; + YAP_Term arg_entry = YAP_ARG3; YAP_Term entry; + char *mode_str; /* check args */ - if (!YAP_IsIntTerm(arg1)) + mode_str = YAP_AtomName(YAP_AtomOfTerm(arg_mode)); + if (!strcmp(mode_str, "std")) { + MODE = MODE_STANDARD; + } else if (!strcmp(mode_str, "rev")) { + MODE = MODE_REVERSE; + } else return FALSE; - /* get entry */ - entry = get_trie_entry((TrNode) YAP_IntOfTerm(arg1)); - /* return entry reference */ - if (!YAP_Unify(arg2, entry)) + if (!YAP_IsIntTerm(arg_ref)) + return FALSE; + + /* get trie entry */ + entry = get_trie_entry((TrNode) YAP_IntOfTerm(arg_ref)); + if (!YAP_Unify(arg_entry, entry)) return FALSE; return TRUE; } @@ -128,33 +147,34 @@ static int p_get_trie_entry(void) { /* remove_trie_entry(-Ref) */ static int p_remove_trie_entry(void) { - YAP_Term arg1 = YAP_ARG1; + YAP_Term arg_ref = YAP_ARG1; /* check arg */ - if (!YAP_IsIntTerm(arg1)) + if (!YAP_IsIntTerm(arg_ref)) return FALSE; + /* remove trie entry */ - remove_trie_entry((TrNode) YAP_IntOfTerm(arg1)); + remove_trie_entry((TrNode) YAP_IntOfTerm(arg_ref)); return TRUE; } /* trie_statistics() */ static int p_trie_stats(void) { - /* print trie statistics */ trie_stats(); return TRUE; } -/* print_trie(-Ref) */ +/* print_trie(-Trie) */ static int p_print_trie(void) { - YAP_Term arg1 = YAP_ARG1; + YAP_Term arg_trie = YAP_ARG1; /* check arg */ - if (!YAP_IsIntTerm(arg1)) + if (!YAP_IsIntTerm(arg_trie)) return FALSE; + /* print trie */ - print_trie((TrNode) YAP_IntOfTerm(arg1)); + print_trie((TrNode) YAP_IntOfTerm(arg_trie)); return TRUE; } diff --git a/pl/boot.yap b/pl/boot.yap index 37bbed1e5..ed1053eaf 100644 --- a/pl/boot.yap +++ b/pl/boot.yap @@ -15,6 +15,7 @@ * * *************************************************************************/ + % This one should come first so that disjunctions and long distance % cuts are compiled right with co-routining. % diff --git a/pl/directives.yap b/pl/directives.yap index a75a7788d..865dfaea1 100644 --- a/pl/directives.yap +++ b/pl/directives.yap @@ -574,8 +574,7 @@ yap_flag(host_type,X) :- '$syntax_check_single_var'(_,off), '$syntax_check_discontiguous'(_,off), '$syntax_check_multiple'(_,off), - '$transl_to_on_off'(Y,off), % disable character escapes. - '$set_yap_flags'(12,Y), + '$set_yap_flags'(12,0), % disable character escapes. '$set_yap_flags'(14,1), '$set_fpu_exceptions', unknown(_,error). @@ -590,6 +589,8 @@ yap_flag(host_type,X) :- '$set_yap_flags'(5,X1), '$force_char_conversion', '$set_yap_flags'(14,0), + % CHARACTER_ESCAPE + '$set_yap_flags'(12,1), '$set_fpu_exceptions', fileerrors, unknown(_,error). @@ -599,12 +600,17 @@ yap_flag(host_type,X) :- '$syntax_check_single_var'(_,on), '$syntax_check_discontiguous'(_,on), '$syntax_check_multiple'(_,on), + % YAP_TO_CHARS '$set_yap_flags'(7,1), fileerrors, '$transl_to_on_off'(X1,on), + % CHAR_CONVERSION '$set_yap_flags'(5,X1), '$force_char_conversion', + % ALLOW_ASSERTING_STATIC '$set_yap_flags'(14,0), + % CHARACTER_ESCAPE + '$set_yap_flags'(12,1), '$set_fpu_exceptions', unknown(_,error). diff --git a/pl/modules.yap b/pl/modules.yap index 892ecc771..bc2523f86 100644 --- a/pl/modules.yap +++ b/pl/modules.yap @@ -441,7 +441,7 @@ module(N) :- functor(P,F,N), ( M1 = prolog -> M = _ ; M1 = M), ( retractall('$meta_predicate'(F,M,N,_)), fail ; true), - asserta('$meta_predicate'(F,M,N,P)), + asserta(prolog:'$meta_predicate'(F,M,N,P)), '$flags'(P, M1, Fl, Fl), NFlags is Fl \/ 0x200000, '$flags'(P, M1, Fl, NFlags).