21static char SccsId[] =
"%W% %G%";
57#if HAVE_SYS_SELECT_H && !_MSC_VER && !defined(__MINGW32__)
58#include <sys/select.h>
80#define strncat(X, Y, Z) strcat(X, Y)
83#define strncpy(X, Y, Z) strcpy(X, Y)
85#if _MSC_VER || defined(__MINGW32__)
91#define S_ISDIR(x) (((x)&_S_IFDIR) == _S_IFDIR)
96#if _MSC_VER || defined(__MINGW32__)
97#define SYSTEM_STAT _stat
99#define SYSTEM_STAT stat
103 bool code,
const char *msg);
110 clean_vars(p->VarLeft);
111 clean_vars(p->VarRight);
116#ifdef O_QUASIQUOTATIONS
126static Int qq_open(USES_REGS1)
130 Term t = Deref(ARG1);
132 if (!IsVarTerm(t) && IsApplTerm(t) && FunctorOfTerm(t) =
133 FunctorDQuasiQuotation)
140 if (IsPointerTerm((t0 = ArgOfTerm(1, t))) &&
141 IsPointerTerm((t1 = ArgOfTerm(2, t))) &&
142 IsIntegerTerm((t2 = ArgOfTerm(3, t))))
144 ptr = PointerOfTerm(t0);
145 start = PointerOfTerm(t1);
146 len = IntegerOfTerm(t2);
147 if ((s = Yap_open_buf_read_stream(start, len, ENC_UTF8, MEM_BUF_USER)) <
150 return Yap_unify(ARG2, Yap_MkStream(s));
154 Yap_ThrowError(TYPE_ERROR_READ_CONTEXT, t);
161static int parse_quasi_quotations(
ReadData _PL_rd ARG_LD)
168 if (!PL_unify_nil(_PL_rd->qq_tail))
171 if (!_PL_rd->quasi_quotations)
173 if ((av = PL_new_term_refs(2)) && PL_put_term(av + 0, _PL_rd->qq) &&
175 PL_put_atom(av + 1, YAP_SWIAtomFromAtom(_PL_rd->module->AtomOfME)) &&
177 PL_put_atom(av + 1, _PL_rd->module->name) &&
179 PL_cons_functor_v(av, FUNCTOR_dparse_quasi_quotations2, av))
182 rc = callProlog(MODULE_system, av + 0, PL_Q_CATCH_EXCEPTION, &ex);
185 _PL_rd->exception = ex;
186 _PL_rd->has_exception = TRUE;
193 else if (_PL_rd->quasi_quotations)
195 return PL_unify_nil(_PL_rd->quasi_quotations);
206 PAR("comments", list_filler, READ_COMMENTS), \
207 PAR("module", isatom, READ_MODULE), PAR("priority", nat, READ_PRIORITY), \
208 PAR("output", filler, READ_OUTPUT), \
209 PAR("quasi_quotations", filler, READ_QUASI_QUOTATIONS), \
210 PAR("term_position", filler, READ_TERM_POSITION), \
211 PAR("syntax_errors", isatom, READ_SYNTAX_ERRORS), \
212 PAR("singletons", filler, READ_SINGLETONS), \
213 PAR("variables", filler, READ_VARIABLES), \
214 PAR("variable_names", filler, READ_VARIABLE_NAMES), \
215 PAR("character_escapes", booleanFlag, READ_CHARACTER_ESCAPES), \
216 PAR("input_closing_blank", booleanFlag, READ_INPUT_CLOSING_BLANK), \
217 PAR("backquoted_string", isatom, READ_BACKQUOTED_STRING), \
218 PAR("singlequoted_string", isatom, READ_SINGLEQUOTED_STRING), \
219 PAR("doublequoted_string", isatom, READ_DOUBLEQUOTED_STRING), \
220 PAR("var_prefix", isatom, READ_VAR_PREFIX), \
221 PAR("allow_variable_name_as_functor", isatom, \
222 READ_ALLOW_VARIABLE_NAME_AS_FUNCTOR), \
223 PAR("cycles", booleanFlag, READ_CYCLES), PAR(NULL, ok, READ_END)
225#define PAR(x, y, z) z
227typedef enum open_enum_choices
234#define PAR(x, y, z) \
239static const param_t read_defs[] = {READ_DEFS()};
242static Term add_output(Term t, Term tail)
244 Term topt = Yap_MkApplTerm(Yap_MkFunctor(AtomOutput, 1), 1, &t);
249 Yap_ThrowError(INSTANTIATION_ERROR, tail,
"unbound list of options");
251 else if (IsPairTerm(tail) || tail == TermNil)
253 return MkPairTerm(topt, tail);
257 Yap_ThrowError(TYPE_ERROR_LIST, tail,
"list of options");
262static Term add_names(Term t, Term tail)
264 Term topt = Yap_MkApplTerm(Yap_MkFunctor(AtomVariableNames, 1), 1, &t);
268 Yap_ThrowError(INSTANTIATION_ERROR, tail,
"unbound list of options");
270 else if (IsPairTerm(tail) || tail == TermNil)
272 return MkPairTerm(topt, tail);
276 Yap_ThrowError(TYPE_ERROR_LIST, tail,
"list of options");
281static Term add_priority(Term t, Term tail)
283 Term topt = Yap_MkNewApplTerm(Yap_MkFunctor(AtomPriority, 1), 1);
285 Yap_unify(t, ArgOfTerm(1, topt));
288 Yap_ThrowError(INSTANTIATION_ERROR, tail,
"unbound list of options");
290 else if (IsPairTerm(tail) || tail == TermNil)
292 return MkPairTerm(topt, tail);
296 Yap_ThrowError(TYPE_ERROR_LIST, tail,
"list of options");
323 if (tok == errtok && tok->Tok != Error_tok)
325 *tailp = MkPairTerm(MkAtomTerm(AtomError), TermNil);
326 tailp = RepPair(*tailp) + 1;
329 *tailp = MkPairTerm(rep, TermNil);
330 tailp = RepPair(*tailp) + 1;
331 if (tok->TokNext == NULL)
354static Int scan_to_list(USES_REGS1)
361 inp_stream = Yap_CheckTextStream(ARG1, Input_Stream_f,
"read/3");
362 if (inp_stream == -1)
366 TokEntry *tok = LOCAL_tokptr = LOCAL_toktide =
367 Yap_tokenizer(GLOBAL_Stream + inp_stream, ¶ms);
368 UNLOCK(GLOBAL_Stream[inp_stream].streamlock);
369 tout = scanToList(tok, NULL);
374 return Yap_unify(ARG2, tout);
387 bool code,
const char *msg)
391 Int start_line = tok->TokLine;
392 Int err_line = LOCAL_toktide->TokLine;
393 Int startpos = tok->TokPos;
394 Int errpos = LOCAL_toktide->TokOffset;
395 Int end_line = GetCurInpLine(GLOBAL_Stream + sno);
396 Int endpos = GetCurInpPos(GLOBAL_Stream + sno);
398 if (LOCAL_ActiveError) {
399 e = LOCAL_ActiveError;
410 e->parserFirstLine = start_line;
411 e->parserLine = err_line;
412 e->parserLastLine = end_line;
413 e->parserFirstPos = startpos;
415 e->parserLastPos = endpos;
416 if (AtomOfTerm((GLOBAL_Stream + sno)->user_name))
418 RepAtom((GLOBAL_Stream + sno)->name)->StrOfAE;
421 RepAtom(AtomOfTerm((GLOBAL_Stream + sno)->user_name))->StrOfAE;
425 if (GLOBAL_Stream[sno].status & Seekable_Stream_f &&
429 err_line = e->parserLine;
431 startpos = e->parserFirstPos - 1;
432 endpos = e->parserLastPos - 1;
434 fseeko(GLOBAL_Stream[sno].file, startpos, SEEK_SET);
436 fseek(GLOBAL_Stream[sno].file, startpos, SEEK_SET);
438 Int sza = (endpos - startpos);
441 fread(o, sza, 1, GLOBAL_Stream[sno].file);
444 e->parserTextB = errpos - startpos;
448 int lvl = push_text_stack();
454 if (tok->Tok == Error_tok || tok == LOCAL_toktide)
456 e->parserTextB = strlen(o);
457 err_line = tok->TokLine;
458 errpos = tok->TokPos;
460 const char *ns = Yap_tokText(tok);
461 size_t esz = strlen(ns);
464 if (esz + 1 > sz - 256)
466 o = Realloc(o, strlen(o) + sz + 1024);
467 sz += 1024;
if ( tok->TokNext->TokLine > tok->TokLine) {
474 if (tok->TokNext && tok->TokNext->TokLine > tok->TokLine)
481 e->parserTextA = malloc(strlen(o) + 1);
482 strcpy((
char *)e->parserTextA, o);
490 e->errorMsgLen = strlen(msg);
491 e->errorMsg = malloc(e->errorMsgLen + 1);
492 strcpy(e->errorMsg, msg);
494 clean_vars(LOCAL_VarTable);
495 clean_vars(LOCAL_AnonVarTable);
497 Term msgt = (msg ? MkAtomTerm(Yap_LookupAtom(msg)) : TermNil);
498 sc[0] = Yap_MkApplTerm(FunctorShortSyntaxError, 1, &msgt);
501 return Yap_MkApplTerm(Yap_MkFunctor(AtomError, 2), 2, sc);
502 if (Yap_ExecutionMode == YAP_BOOT_MODE)
504 fprintf(stderr,
"SYNTAX ERROR while booting: ");
508Term Yap_syntax_error(
TokEntry *errtok,
int sno,
const char *msg)
510 return syntax_error(errtok, sno, CurrentModule, -1,
false, msg);
516 Term
qq, tp, sp, np, vprefix;
542static xarg *setClauseReadEnv(Term opts,
FEnv *fe,
struct renv *re,
544static xarg *setReadEnv(Term opts,
FEnv *fe,
struct renv *re,
int inp_stream)
547 LOCAL_VarTable = LOCAL_VarList = LOCAL_VarTail = LOCAL_AnonVarTable = NULL;
548 fe->
enc = GLOBAL_Stream[inp_stream].encoding;
550 memset(args, 0,
sizeof(
xarg)*READ_END);
552 Yap_ArgListToVector(opts, read_defs, READ_END,args, DOMAIN_ERROR_READ_OPTION);
555 if (args && args[READ_OUTPUT].used)
557 fe->t0 = args[READ_OUTPUT].tvalue;
563 if (args && args[READ_MODULE].used)
565 fe->cmod = args[READ_MODULE].tvalue;
569 fe->cmod = CurrentModule;
570 if (fe->cmod == TermProlog)
571 fe->cmod = PROLOG_MODULE;
573 if (args && args[READ_BACKQUOTED_STRING].used)
575 fe->scanner.backquotes = args[READ_BACKQUOTED_STRING].tvalue;
579 fe->scanner.backquotes = getBackQuotesFlag(fe->cmod);
581 if (args && args[READ_DOUBLEQUOTED_STRING].used)
583 fe->scanner.doublequotes = args[READ_DOUBLEQUOTED_STRING].tvalue;
587 fe->scanner.doublequotes = getDoubleQuotesFlag(fe->cmod);
589 if (args && args[READ_SINGLEQUOTED_STRING].used)
591 fe->scanner.singlequotes = args[READ_SINGLEQUOTED_STRING].tvalue;
595 fe->scanner.singlequotes = getSingleQuotesFlag(fe->cmod);
597 if (args && args[READ_CHARACTER_ESCAPES].used)
599 fe->scanner.ce = args[READ_CHARACTER_ESCAPES].tvalue == TermTrue;
603 fe->scanner.ce = Yap_CharacterEscapes(fe->cmod) == TermTrue;
605 if (args && args[READ_VAR_PREFIX].used)
607 fe->scanner.vprefix = args[READ_VAR_PREFIX].tvalue == TermTrue;
611 fe->scanner.vprefix =
false;
613 if (args && args[READ_INPUT_CLOSING_BLANK].used)
615 fe->scanner.get_eot_blank =
616 args[READ_INPUT_CLOSING_BLANK].tvalue == TermTrue;
620 fe->scanner.get_eot_blank =
false;
622 if (args && args[READ_ALLOW_VARIABLE_NAME_AS_FUNCTOR].used)
624 fe->scanner.vn_asfl =
625 args[READ_ALLOW_VARIABLE_NAME_AS_FUNCTOR].tvalue == TermTrue;
629 fe->scanner.vn_asfl =
630 trueLocalPrologFlag(ALLOW_VARIABLE_NAME_AS_FUNCTOR_FLAG) == TermTrue;
632 if (args && args[READ_COMMENTS].used)
640 if (args && args[READ_QUASI_QUOTATIONS].used)
642 fe->
qq = args[READ_QUASI_QUOTATIONS].tvalue;
648 if (args && args[READ_COMMENTS].used)
650 fe->scanner.tcomms = args[READ_COMMENTS].tvalue;
654 fe->scanner.tcomms = 0;
656 if (args && args[READ_TERM_POSITION].used)
658 fe->tp = args[READ_TERM_POSITION].tvalue;
664 if (args && args[READ_SINGLETONS].used)
666 fe->sp = args[READ_SINGLETONS].tvalue;
672 if (args && args[READ_SYNTAX_ERRORS].used)
674 re->sy = args[READ_SYNTAX_ERRORS].tvalue;
678 re->sy = TermException;
680 if (args && args[READ_VARIABLES].used)
682 fe->vprefix = args[READ_VARIABLES].tvalue;
688 if (args && args[READ_VARIABLE_NAMES].used)
690 fe->np = args[READ_VARIABLE_NAMES].tvalue;
696 re->seekable = (GLOBAL_Stream[inp_stream].status & Seekable_Stream_f) != 0;
699 re->cpos = GLOBAL_Stream[inp_stream].charcount;
701 if (args && args[READ_PRIORITY].used)
703 re->prio = IntegerOfTerm(args[READ_PRIORITY].tvalue);
704 if (re->prio > GLOBAL_MaxPriority)
706 Yap_ThrowError(DOMAIN_ERROR_OPERATOR_PRIORITY, opts,
707 "max priority in Prolog is %d, not %ld",
708 GLOBAL_MaxPriority, re->prio);
713 re->prio = LOCAL_default_priority;
729Int Yap_FirstLineInParse(
void)
732 return LOCAL_StartLineCount;
735#define PUSHFET(X) *HR++ = fe->X
736#define POPFET(X) fe->X = *--HR
742 restore_machine_regs();
752 memset(LOCAL_ActiveError,0,
sizeof(*LOCAL_ActiveError));
753 LOCAL_Error_TYPE = YAP_NO_ERROR;
772 if (setjmp(LOCAL_IOBotch) == 0)
774 if ((v = Yap_Variables(LOCAL_VarList, TermNil)))
782 reset_regs(tokstart, fe);
800 if (setjmp(LOCAL_IOBotch) == 0)
802 if ((v = Yap_VarNames(LOCAL_VarList, TermNil)))
810 reset_regs(tokstart, fe);
828 if (setjmp(LOCAL_IOBotch) == 0)
830 if ((v = Yap_Singletons(LOCAL_VarList, TermNil)))
837 reset_regs(tokstart, fe);
844static void warn_singletons(
FEnv *fe,
TokEntry *tokstart)
850 v = get_singletons(fe, tokstart);
851 if (v && v != TermNil)
854 singls[0] = Yap_MkApplTerm(Yap_MkFunctor(AtomSingleton, 1), 1, &v);
855 singls[1] = MkIntegerTerm(LOCAL_SourceFileLineno);
856 singls[2] = MkAtomTerm(LOCAL_SourceFileName);
859 if (IsApplTerm(fe->
t))
862 if (f == FunctorQuery || f == FunctorAssert1)
868 singls[1] = TermTrue;
870 sc[0] = Yap_MkApplTerm(Yap_MkFunctor(AtomStyleCheck, 4), 4, singls);
874 v,
"singletons warning");
877 Yap_PrintWarning(Yap_MkApplTerm(Yap_MkFunctor(AtomError, 2), 2, sc));
881static Term get_stream_position(
FEnv *fe,
TokEntry *tokstart)
892 if (setjmp(LOCAL_IOBotch) == 0)
894 if ((v = CurrentPositionToTerm()))
901 reset_regs(tokstart, fe);
908static bool complete_processing(
FEnv *fe,
TokEntry *tokstart)
913 if (fe->t0 && fe->
t && !(Yap_unify(fe->
t, fe->t0)))
916 if (fe->
t && fe->vprefix)
917 v1 = get_variables(fe, tokstart);
921 v2 = get_varnames(fe, tokstart);
925 v3 = get_singletons(fe, tokstart);
928 if (fe->
t && fe->scanner.tcomms)
932 Term tpos = get_stream_position(fe, tokstart);
935 if (LOCAL_ParserAuxBase) {
937 LOCAL_ParserAuxBase=NULL;
946 return (!v1 || Yap_unify(v1, fe->vprefix)) &&
947 (!v2 || Yap_unify(v2, fe->np)) && (!v3 || Yap_unify(v3, fe->sp)) &&
949 Yap_unify(fe->tp, tpos)) &&
950 (!vc || Yap_unify(vc, fe->scanner.tcomms));
955static bool complete_clause_processing(
FEnv *fe,
TokEntry *tokstart)
958 Term v_vprefix, v_vnames, v_comments, v_pos;
960 if (fe->t0 && fe->
t && !Yap_unify(fe->
t, fe->t0))
962 if (fe->
t && fe->vprefix)
963 v_vprefix = get_variables(fe, tokstart);
967 v_vnames = get_varnames(fe, tokstart);
971 trueGlobalPrologFlag(SINGLE_VAR_WARNINGS_FLAG))
973 warn_singletons(fe, tokstart);
975 if (fe->
t && fe->scanner.tcomms)
976 v_comments = LOCAL_Comments;
980 v_pos = get_stream_position(fe, tokstart);
988 return (!v_vprefix || Yap_unify(v_vprefix, fe->vprefix)) &&
989 (!v_vnames || Yap_unify(v_vnames, fe->np)) &&
990 (!v_pos || Yap_unify(v_pos, fe->tp)) &&
991 (!v_comments || Yap_unify(v_comments, fe->scanner.tcomms));
1014 if (tokstart != NULL && tokstart->Tok != Ord(eot_tok))
1017 if (fe->
msg && fe->
msg[0] && !strcmp(fe->
msg,
"Abort"))
1024 if (GLOBAL_Stream[inp_stream].status & Past_Eof_Stream_f)
1026 strcpy(fe->
msg,
"parsing stopped at a end-of-file");
1030 GLOBAL_Stream[inp_stream].status |= Push_Eof_Stream_f;
1031 strcpy(fe->
msg,
"end of file found before end of term");
1039 fe->
t = MkAtomTerm(AtomEof);
1040 if (fe->np && !Yap_unify(TermNil, fe->np))
1042 if (fe->sp && !Yap_unify(TermNil, fe->sp))
1044 if (fe->vprefix && !Yap_unify(TermNil, fe->vprefix))
1047 !Yap_unify(fe->tp, StreamPosition(inp_stream)))
1050 if (GLOBAL_Option[
'p' -
'a' + 1])
1052 fprintf(stderr,
"[ end_of_file %p ]\n", GLOBAL_Stream[inp_stream].name);
1062 LOCAL_Error_TYPE = YAP_NO_ERROR;
1063 LOCAL_SourceFileName = GLOBAL_Stream[inp_stream].name;
1064 LOCAL_eot_before_eof =
false;
1065 fe->tp = StreamPosition(inp_stream);
1071 fe->
args = setClauseReadEnv(opts, fe, re, inp_stream);
1075 fe->
args = setReadEnv(opts, fe, re, inp_stream);
1077 if (fe->
args == NULL)
1079 if (LOCAL_Error_TYPE == DOMAIN_ERROR_OUT_OF_RANGE)
1080 LOCAL_Error_TYPE = TYPE_ERROR_READ_TERM;
1081 if (LOCAL_Error_TYPE)
1082 Yap_ThrowError(LOCAL_Error_TYPE, opts, NULL);
1087 if (GLOBAL_Stream[inp_stream].status & Push_Eof_Stream_f)
1089 fe->
t = MkAtomTerm(AtomEof);
1090 GLOBAL_Stream[inp_stream].status &= ~Push_Eof_Stream_f;
1107 LOCAL_tokptr = LOCAL_toktide = Yap_tokenizer(GLOBAL_Stream + sno, &fe->scanner);
1110 if (GLOBAL_Option[2])
1116 fprintf(stderr,
"[Token %d %s %d]", Ord(t->Tok), Yap_tokText(t), n++);
1119 fprintf(stderr,
"\n");
1124 if (LOCAL_tokptr->Tok != Ord(eot_tok))
1129 if (LOCAL_tokptr->Tok == eot_tok && LOCAL_tokptr->TokInfo == TermNl)
1131 strcpy(fe->
msg,
". is end-of-term?");
1134 return scanEOF(fe, sno);
1144 if (LOCAL_Error_TYPE == RESOURCE_ERROR_TRAIL)
1146 LOCAL_Error_TYPE = YAP_NO_ERROR;
1147 if (!Yap_growtrail(
sizeof(CELL) * K16, FALSE))
1153 else if (LOCAL_Error_TYPE == RESOURCE_ERROR_AUXILIARY_STACK)
1155 LOCAL_Error_TYPE = YAP_NO_ERROR;
1156 if (!Yap_ExpandPreAllocCodeSpace(0, NULL, TRUE))
1162 else if (LOCAL_Error_TYPE == RESOURCE_ERROR_HEAP)
1164 LOCAL_Error_TYPE = YAP_NO_ERROR;
1165 if (!Yap_growheap(FALSE, 0, NULL))
1171 else if (LOCAL_Error_TYPE == RESOURCE_ERROR_STACK)
1173 LOCAL_Error_TYPE = YAP_NO_ERROR;
1174 if (!Yap_dogc(PASS_REGS1))
1181 if (LOCAL_Error_TYPE == SYNTAX_ERROR)
1187 if (GLOBAL_Stream[inp_stream].status & InMemory_Stream_f)
1189 GLOBAL_Stream[inp_stream].u.mem_string.pos = re->cpos;
1191 else if (GLOBAL_Stream[inp_stream].status)
1194 fseeko(GLOBAL_Stream[inp_stream].file, re->cpos, 0L);
1196 fseek(GLOBAL_Stream[inp_stream].file, re->cpos, 0L);
1208 if (LOCAL_Error_TYPE == RESOURCE_ERROR_STACK) {
1209 LOCAL_Error_TYPE = YAP_NO_ERROR;
1210 while (!Yap_dogc( PASS_REGS1)) {
1211 Yap_ThrowError(RESOURCE_ERROR_STACK, MkStringTerm(
"read_term"),NULL);
1215 return YAP_START_PARSING;
1216 }
else if (LOCAL_Error_TYPE == RESOURCE_ERROR_HEAP) {
1217 LOCAL_Error_TYPE = YAP_NO_ERROR;
1218 if (!Yap_growheap(FALSE, 0, NULL)) {
1219 Yap_ThrowError(RESOURCE_ERROR_HEAP, MkStringTerm(
"read_term"),NULL);
1223 return YAP_START_PARSING;
1224 }
else if (LOCAL_Error_TYPE == RESOURCE_ERROR_TRAIL) {
1225 LOCAL_Error_TYPE = YAP_NO_ERROR;
1226 if (!Yap_growtrail(0, FALSE)) {
1227 Yap_ThrowError(RESOURCE_ERROR_HEAP, MkStringTerm(
"read_term"),NULL);
1231 return YAP_START_PARSING;
1233 if (LOCAL_Error_TYPE != SYNTAX_ERROR && LOCAL_Error_TYPE != YAP_NO_ERROR)
1237 Term ParserErrorStyle = re->sy;
1238 if (ParserErrorStyle == TermQuiet || LOCAL_Error_TYPE == YAP_NO_ERROR)
1241 LOCAL_Error_TYPE = YAP_NO_ERROR;
1246 if (LOCAL_ErrorMessage && LOCAL_ErrorMessage[0]) {
1247 strncpy(fe->
msg, LOCAL_ErrorMessage, 4095);
1249 LOCAL_Error_TYPE = SYNTAX_ERROR;
1252 if (ParserErrorStyle == TermException)
1260 re->cpos = GLOBAL_Stream[inp_stream].charcount;
1262 Yap_PrintWarning(err);
1263 LOCAL_Error_TYPE = YAP_NO_ERROR;
1264 if (ParserErrorStyle == TermDec10)
1266 return YAP_START_PARSING;
1277 fe->
t = Yap_Parse(re->prio, fe->
enc, fe->cmod);
1279 LOCAL_tokptr = tokstart;
1281 first_char = tokstart->TokPos;
1283 if (LOCAL_Error_TYPE != YAP_NO_ERROR || fe->
t == 0)
1294 Yap_PopHandle(yopts);
1296 if (!(GLOBAL_Stream[sno].status & Free_Stream_f) &&
1297 LOCAL_Error_TYPE != YAP_NO_ERROR &&
1298 LOCAL_Error_TYPE != SYNTAX_ERROR &&
1299 GLOBAL_Stream[sno].status & CloseOnException_Stream_f)
1300 Yap_CloseStream(sno);
1301 pop_text_stack(lvl);
1303 LOCAL_ActiveError = old;
1304 LOCAL_PrologMode |= InErrorMode;
1326 int lvl = push_text_stack();
1328 yhandle_t y0 = Yap_StartHandles();
1332 int emacs_cares = FALSE;
1336 yhandle_t yopts = Yap_InitHandle(opts);
1341 case YAP_START_PARSING:
1342 opts = Yap_GetFromHandle(yopts);
1343 state = initparser(opts, fe, re, sno, clause);
1345 return exit_parser(sno, yopts, &
new, lvl, old, 0);
1349 state = scan(re, fe, sno);
1353 state = scanError(re, fe, sno);
1357 state =
parse(re, fe, sno);
1361 state = parseError(re, fe, sno);
1369 done = complete_clause_processing(fe, LOCAL_tokptr);
1371 done = complete_processing(fe, LOCAL_tokptr);
1379 first_char = tokstart->TokPos;
1382 rc = exit_parser(sno, yopts, &
new, lvl, old, rc);
1383 Yap_CloseHandles(y0);
1389 return exit_parser(sno, yopts, &
new, lvl, old, rc);
1393 read_term2(USES_REGS1)
1395 return Yap_read_term(LOCAL_c_input_stream, add_output(ARG1, ARG2),
false) !=
1399static Int read_term(
1407 sno = Yap_CheckTextStream(ARG1, Input_Stream_f,
"read/3");
1413 UNLOCK(GLOBAL_Stream[sno].streamlock);
1417#define READ_CLAUSE_DEFS() \
1418 PAR("comments", list_filler, READ_CLAUSE_COMMENTS) \
1419 , PAR("module", isatom, READ_CLAUSE_MODULE), \
1420 PAR("variable_names", filler, READ_CLAUSE_VARIABLE_NAMES), \
1421 PAR("variables", filler, READ_CLAUSE_VARIABLES), \
1422 PAR("term_position", filler, READ_CLAUSE_TERM_POSITION), \
1423 PAR("syntax_errors", isatom, READ_CLAUSE_SYNTAX_ERRORS), \
1424 PAR("output", isatom, READ_CLAUSE_OUTPUT), \
1425 PAR(NULL, ok, READ_CLAUSE_END)
1427#define PAR(x, y, z) z
1429typedef enum read_clause_enum_choices
1432} read_clause_choices_t;
1436#define PAR(x, y, z) \
1441static const param_t read_clause_defs[] = {READ_CLAUSE_DEFS()};
1444static xarg *setClauseReadEnv(Term opts,
FEnv *fe,
struct renv *re,
int sno)
1448 LOCAL_VarTable = LOCAL_VarList = LOCAL_VarTail = LOCAL_AnonVarTable = NULL;
1450 memset(args, 0,
sizeof(
xarg)*READ_CLAUSE_END);
1451 args = Yap_ArgListToVector(opts, read_clause_defs, READ_CLAUSE_END, args,
1452 TYPE_ERROR_READ_TERM);
1453 memset(fe, 0,
sizeof(*fe));
1455 if (args && args[READ_CLAUSE_OUTPUT].used)
1457 fe->t0 = args[READ_CLAUSE_OUTPUT].tvalue;
1463 if (args && args[READ_CLAUSE_MODULE].used)
1465 fe->cmod = args[READ_CLAUSE_MODULE].tvalue;
1469 fe->cmod = LOCAL_SourceModule;
1470 if (fe->cmod == TermProlog)
1471 fe->cmod = PROLOG_MODULE;
1473 fe->scanner.backquotes = getBackQuotesFlag(fe->cmod);
1474 fe->scanner.singlequotes = getSingleQuotesFlag(fe->cmod);
1475 fe->scanner.doublequotes = getDoubleQuotesFlag(fe->cmod);
1476 fe->
enc = GLOBAL_Stream[sno].encoding;
1479 if (args && args[READ_CLAUSE_TERM_POSITION].used)
1481 fe->tp = args[READ_CLAUSE_TERM_POSITION].tvalue;
1488 if (args && args[READ_CLAUSE_COMMENTS].used)
1490 fe->scanner.tcomms = args[READ_CLAUSE_COMMENTS].tvalue;
1494 fe->scanner.tcomms = 0L;
1496 if (args && args[READ_CLAUSE_SYNTAX_ERRORS].used)
1498 re->sy = args[READ_CLAUSE_SYNTAX_ERRORS].tvalue;
1505 if (args && args[READ_CLAUSE_VARIABLE_NAMES].used)
1507 fe->np = args[READ_CLAUSE_VARIABLE_NAMES].tvalue;
1513 if (args && args[READ_CLAUSE_VARIABLES].used)
1515 fe->vprefix = args[READ_CLAUSE_VARIABLES].tvalue;
1521 fe->scanner.ce = Yap_CharacterEscapes(fe->cmod);
1522 re->seekable = (GLOBAL_Stream[sno].status & Seekable_Stream_f) != 0;
1525 re->cpos = GLOBAL_Stream[sno].charcount;
1527 re->prio = LOCAL_default_priority;
1528 LOCAL_ErrorMessage=NULL;
1538static Int read_clause2(USES_REGS1)
1540 Term ctl = add_output(ARG1, ARG2);
1568static Int read_clause(
1575 sno = Yap_CheckTextStream(ARG1, Input_Stream_f,
"read/3");
1579 UNLOCK(GLOBAL_Stream[sno].streamlock);
1595 static Int start_mega(USES_REGS1)
1599 Term t3 = Deref(ARG3);
1601 sno = Yap_CheckTextStream(ARG1, Input_Stream_f,
"read_exo/3");
1604 yhandle_t y0 = Yap_StartHandles();
1605 yhandle_t h = Yap_InitSlot(ARG2);
1612 LOCAL_tokptr = LOCAL_toktide =
1613 x Yap_tokenizer(GLOBAL_Stream + sno, fe->scanner);
1614 if (tokptr->Tok == Name_tok && (next = tokptr->TokNext) != NULL &&
1615 next->Tok == Ponctuation_tok && next->TokInfo == TermOpenBracket)
1618 while ((tokptr = next->TokNext))
1620 if (IsAtomOrIntTerm(t = fe->tp))
1622 ip->opc = Yap_opcode(get_atom);
1624 ip->y_u.x_c.x = fe->tp++; / ()c * /
1626 else if (IsAtomOrIntTerm(t = *tp))
1628 (IsAtom(tok->Tokt) || IsIntTerm(XREGS + (i + 1)))extra[arity]
1633 Yap_CloseHandles(y0);
1654static Int source_location(USES_REGS1)
1656 return Yap_unify(ARG1, MkAtomTerm(LOCAL_SourceFileName)) &&
1657 Yap_unify(ARG2, MkIntegerTerm(LOCAL_SourceFileLineno));
1677 sno = Yap_CheckTextStream(ARG1, Input_Stream_f,
"read/3");
1683 UNLOCK(GLOBAL_Stream[sno].streamlock);
1700 Term out =
Yap_read_term(LOCAL_c_input_stream, add_output(ARG1, TermNil),
false);
1705static Int style_checker(USES_REGS1)
1707 Term t = Deref(ARG1);
1712 if (getYapFlag(MkAtomTerm(AtomSingleVarWarnings)) == TermTrue)
1714 t = MkPairTerm(MkAtomTerm(AtomSingleVarWarnings), t);
1716 if (getYapFlag(MkAtomTerm(AtomDiscontiguousWarnings)) == TermTrue)
1718 t = MkPairTerm(MkAtomTerm(AtomDiscontiguousWarnings), t);
1720 if (getYapFlag(MkAtomTerm(AtomRedefineWarnings)) == TermTrue)
1722 t = MkPairTerm(MkAtomTerm(AtomRedefineWarnings), t);
1727 while (IsPairTerm(t))
1729 Term h = HeadOfTerm(t);
1734 Yap_ThrowError(INSTANTIATION_ERROR, t,
"style_check/1");
1737 else if (IsAtomTerm(h))
1739 Atom at = AtomOfTerm(h);
1740 if (at == AtomSingleVarWarnings)
1741 Yap_set_flag(MkAtomTerm(AtomSingleVarWarnings), TermTrue);
1742 else if (at == AtomDiscontiguousWarnings)
1743 Yap_set_flag(MkAtomTerm(AtomDiscontiguousWarnings), TermTrue);
1744 else if (at == AtomRedefineWarnings)
1745 Yap_set_flag(MkAtomTerm(AtomRedefineWarnings), TermTrue);
1749 Atom at = AtomOfTerm(ArgOfTerm(1, h));
1750 if (at == AtomSingleVarWarnings)
1751 Yap_set_flag(MkAtomTerm(AtomSingleVarWarnings), TermFalse);
1752 else if (at == AtomDiscontiguousWarnings)
1753 Yap_set_flag(MkAtomTerm(AtomDiscontiguousWarnings), TermFalse);
1754 else if (at == AtomRedefineWarnings)
1755 Yap_set_flag(MkAtomTerm(AtomRedefineWarnings), TermFalse);
1762Term Yap_BufferToTerm(
const char *s, Term opts)
1766 encoding_t l = ENC_ISO_UTF8;
1769 Yap_open_buf_read_stream(NULL,(
char *)s, strlen(s) + 1, &l, MEM_BUF_USER,
1770 Yap_LookupAtom(Yap_StrPrefix(s, 16)), TermNone);
1772 GLOBAL_Stream[sno].status |= CloseOnException_Stream_f;
1774 Yap_CloseStream(sno);
1778Term Yap_UBufferToTerm(
const unsigned char *s, Term opts)
1782 encoding_t l = ENC_ISO_UTF8;
1784 sno = Yap_open_buf_read_stream(NULL,
1785 (
char *)s, strlen((
const char *)s), &l, MEM_BUF_USER,
1786 Yap_LookupAtom(Yap_StrPrefix((
char *)s, 16)), TermNone);
1787 GLOBAL_Stream[sno].status |= CloseOnException_Stream_f;
1789 Yap_CloseStream(sno);
1793X_API Term Yap_BufferToTermWithPrioBindings(
const char *s, Term ctl,
1794 Term bindings,
size_t len,
1800 ctl = add_names(bindings, ctl);
1804 ctl = add_priority(prio, ctl);
1806 Term o = Yap_BufferToTerm(s, ctl);
1826static Int read_term_from_atom(USES_REGS1)
1828 Term t1 = Deref(ARG1);
1830 const unsigned char *s;
1834 Yap_ThrowError(INSTANTIATION_ERROR, t1,
"style_check/1");
1837 else if (!IsAtomTerm(t1))
1839 Yap_ThrowError(TYPE_ERROR_ATOM, t1,
"style_check/1");
1844 at = AtomOfTerm(t1);
1847 Term ctl = add_output(ARG2, ARG3);
1849 Int rc = Yap_UBufferToTerm(s, ctl);
1872static Int read_term_from_atomic(USES_REGS1)
1874 Term t1 = Deref(ARG1);
1875 const unsigned char *s;
1879 Yap_ThrowError(INSTANTIATION_ERROR, t1,
"read_term_from_atomic/3");
1882 else if (!IsAtomicTerm(t1))
1884 Yap_ThrowError(TYPE_ERROR_ATOMIC, t1,
"read_term_from_atomic/3");
1889 Term t = Yap_AtomicToString(t1 PASS_REGS);
1890 s = UStringOfTerm(t);
1892 Term ctl = add_output(ARG2, ARG3);
1894 Int rc = Yap_UBufferToTerm(s, ctl);
1914static Int read_term_from_string(USES_REGS1)
1916 Term t1 = Deref(ARG1), rc;
1917 const unsigned char *s;
1923 Yap_ThrowError(INSTANTIATION_ERROR, t1,
"read_term_from_string/3");
1926 else if (!IsStringTerm(t1))
1928 Yap_ThrowError(TYPE_ERROR_STRING, t1,
"read_term_from_string/3");
1933 s = UStringOfTerm(t1);
1934 len = strlen_utf8(s);
1936 char *ss = (
char *)s;
1937 encoding_t enc = ENC_ISO_UTF8;
1938 int sno = Yap_open_buf_read_stream(NULL, ss, len, &enc, MEM_BUF_USER,
1939 Yap_LookupAtom(Yap_StrPrefix(ss, 16)),
1941 GLOBAL_Stream[sno].status |= CloseOnException_Stream_f;
1943 Yap_CloseStream(sno);
1951 return Yap_unify(rc, ARG2);
1955static Int atom_to_term(USES_REGS1)
1957 Term t1 = Deref(ARG1);
1961 Yap_ThrowError(INSTANTIATION_ERROR, t1,
"read_term_from_atom/3");
1964 else if (!IsAtomTerm(t1))
1966 Yap_ThrowError(TYPE_ERROR_ATOM, t1,
"read_term_from_atomic/3");
1971 Term t = Yap_AtomToString(t1 PASS_REGS);
1972 const unsigned char *us = UStringOfTerm(t);
1973 return Yap_UBufferToTerm(us, add_output(ARG2, add_names(ARG3, TermNil)));
1977static Int atomic_to_term(USES_REGS1)
1979 Term t1 = Deref(ARG1);
1980 int l = push_text_stack();
1981 Term cm = CurrentModule;
1984 Term tmod = LOCAL_SourceModule;
1985 t1 = Yap_YapStripModule(t1, &tmod);
1986 CurrentModule = tmod;
1992 const unsigned char *s = Yap_TextToUTF8Buffer(t1 PASS_REGS);
1993 Int rc = Yap_UBufferToTerm(s, add_output(ARG2, add_names(ARG3, TermNil)));
1999static Int string_to_term(USES_REGS1)
2001 Term t1 = Deref(ARG1);
2005 Yap_ThrowError(INSTANTIATION_ERROR, t1,
"read_term_from_string/3");
2008 else if (!IsStringTerm(t1))
2010 Yap_ThrowError(TYPE_ERROR_STRING, t1,
"read_term_from_string/3");
2015 const unsigned char *us = UStringOfTerm(t1);
2016 return Yap_UBufferToTerm(us, add_output(ARG2, add_names(ARG3, TermNil)));
2020void Yap_InitReadTPreds(
void)
2022 Yap_InitCPred(
"read_term", 2, read_term2, SyncPredFlag);
2023 Yap_InitCPred(
"read_term", 3, read_term, SyncPredFlag);
2025 Yap_InitCPred(
"atom_to_term", 3, atom_to_term, 0);
2026 Yap_InitCPred(
"atomic_to_term", 3, atomic_to_term, 0);
2027 Yap_InitCPred(
"string_to_term", 3, string_to_term, 0);
2029 Yap_InitCPred(
"scan_to_list", 2, scan_to_list, SyncPredFlag);
2030 Yap_InitCPred(
"read", 1, read1, SyncPredFlag);
2031 Yap_InitCPred(
"read", 2, read2, SyncPredFlag);
2032 Yap_InitCPred(
"read_clause", 2, read_clause2, SyncPredFlag);
2033 Yap_InitCPred(
"read_clause", 3, read_clause, 0);
2034 Yap_InitCPred(
"read_term_from_atom", 3, read_term_from_atom, 0);
2035 Yap_InitCPred(
"read_term_from_atomic", 3, read_term_from_atomic, 0);
2036 Yap_InitCPred(
"read_term_from_string", 3, read_term_from_string, 0);
2037 Yap_InitCPred(
"source_location", 2, source_location, SyncPredFlag);
2038 Yap_InitCPred(
"$style_checker", 1, style_checker,
2039 SyncPredFlag | HiddenPredFlag);
syntax_error
Syntax Error Handler.
bool Yap_RaiseException()
let's go
Term Yap_tokRep(void *tokptr)
convert a token to text
void Yap_clean_tokenizer(void)
terminate scanning: just closes the comment store
void * Malloc(size_t sz USES_REGS)
allocate a temporary text block
Term MkSysError(yap_error_descriptor_t *i)
Wrap the error descriptor as exception/2.
bool Yap_MkErrorRecord(yap_error_descriptor_t *r, const char *file, const char *function, int lineno, yap_error_number type, Term where, const char *s)
complete an error descriptor:
Term Yap_read_term(int sno, Term opts, bool clause)
generic routine to read terms from a stream
@ YAP_SCANNING_ERROR
input to list of tokens
@ YAP_PARSING_FINISHED
oom or syntax error
@ YAP_SCANNING
initialization
@ YAP_PARSING
serious error (eg oom); trying error handling, followd
@ YAP_PARSING_ERROR
list of tokens to term
bool reading_clause
input args
int top_stream
Error Messagge.
CELL * old_H
the last token
TokEntry * tokstart
the output term
Term t
initial position of the term to be read
char msg[4096]
encoding of the stream being read
TokEntry * toklast
the token list
xarg * args
initial H, will be reset on stack overflow
encoding_t enc
arity of current procedure
all we need to know about an error/throw
bool parserReadingCode
reading a clause, or called from read?
uintptr_t parserPos
syntax and other parsing errors
yap_error_number errorNo
error identifier
yap_error_class_number errorClass
kind of error: derived from errorNo;
bool prologConsulting
whether we are consulting