home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Atari FTP
/
ATARI_FTP_0693.zip
/
ATARI_FTP_0693
/
Tex
/
Tex29
/
StTeXsrc.zoo
/
src
/
token.c
< prev
next >
Wrap
C/C++ Source or Header
|
1988-03-13
|
15KB
|
522 lines
/*
* @(#)token.c 2.6 EPA
*
* Copyright 1987,1988 Pat J Monardo
*
* Redistribution of this file is permitted through
* the specifications in the file COPYING.
*
*
*/
#include "tex.h"
#include "scan.h"
#include "box.h"
#include "cond.h"
#include "expand.h"
#include "align.h"
#include "tokenstack.h"
#include "token.h"
tok cur_tok;
hword cur_cmd;
hword cur_chr;
ptr cur_cs;
/*
* This is the TeX segment
*/
tok tok_mem[TOK_MAX-TOK_MIN+1];
ptr tok_link[TOK_MAX-TOK_MIN+1];
ptr tok_head;
ptr tok_low;
ptr tok_end;
int tok_used;
ptr par_loc;
tok par_token;
bool force_eof;
get_token ()
{
no_new_control_sequence = FALSE;
get_next();
no_new_control_sequence = TRUE;
if (cur_cs == 0)
cur_tok = cur_cmd * 0400 + cur_chr;
else cur_tok = CS_TOKEN_FLAG + cur_cs;
}
#define reduce_expanded_cc() \
{if (buffer[k] == cur_chr && \
cat == SUP_MARK && k < limit) { \
cur_chr = buffer[k + 1]; \
if (cur_chr < 0100) \
buffer[k - 1] = cur_chr + 0100; \
else buffer[k - 1] = cur_chr - 0100; \
limit -= 2; \
first -= 2; \
while (k <= limit) { \
buffer[k] = buffer[k + 2]; \
incr(k);} \
goto start_cs;}}
#define any_state(CAT) \
case MID_LINE + CAT: \
case SKIP_BLANKS + CAT: \
case NEW_LINE + CAT
#define delims(CAT) \
case MATH_SHIFT + CAT: \
case TAB_MARK + CAT: \
case MAC_PARAM + CAT: \
case SUB_MARK + CAT: \
case LETTER + CAT: \
case OTHER_CHAR + CAT
#define mid_line(CAT) \
case MID_LINE + CAT
#define new_line(CAT) \
case NEW_LINE + CAT
#define skip_blanks(CAT) \
case SKIP_BLANKS + CAT
get_next ()
{
int k;
tok t;
int cat;
restart:
cur_cs = 0;
if (state != TOKEN_LIST) {
reread:
if (loc <= limit) {
cur_chr = buffer[loc];
incr(loc);
reswitch:
cur_cmd = cat_code(cur_chr);
switch (state + cur_cmd)
{
any_state(IGNORE):
skip_blanks(SPACER):
new_line(SPACER):
goto reread;
any_state(ESCAPE):
if (loc > limit) {
cur_cs = NULL_CS;
} else {
start_cs:
k = loc;
cur_chr = buffer[k];
cat = cat_code(cur_chr);
incr(k);
if (cat == LETTER)
state = SKIP_BLANKS;
else if (cat == SPACER)
state = SKIP_BLANKS;
else state = MID_LINE;
if (cat == LETTER && k <= limit) {
do {
cur_chr = buffer[k];
incr(k);
cat = cat_code(cur_chr);
} while (cat == LETTER && k <= limit);
reduce_expanded_cc();
if (cat != LETTER)
decr(k);
if (k > loc + 1) {
cur_cs = id_lookup(loc, k - loc);
loc = k;
goto found;
}
} else {
reduce_expanded_cc();
}
cur_cs = SINGLE_BASE + buffer[loc];
incr(loc);
}
found:
cur_cmd = eq_type(cur_cs);
cur_chr = equiv(cur_cs);
if (cur_cmd >= OUTER_CALL)
check_outer_validity();
break;
any_state(ACTIVE_CHAR):
cur_cs = cur_chr + ACTIVE_BASE;
cur_cmd = eq_type(cur_cs);
cur_chr = equiv(cur_cs);
state = MID_LINE;
if (cur_cmd >= OUTER_CALL)
check_outer_validity();
break;
any_state(SUP_MARK):
if (cur_chr == buffer[loc] && loc < limit) {
if (buffer[loc + 1] < 0100)
cur_chr = buffer[loc + 1] + 0100;
else cur_chr = buffer[loc + 1] - 0100;
loc += 2;
goto reswitch;
}
state = MID_LINE;
break;
any_state(INVALID_CHAR):
print_err("Text line contains an invalid character");
help_funny();
deletions_allowed = FALSE;
error();
deletions_allowed = TRUE;
goto restart;
mid_line(SPACER):
state = SKIP_BLANKS;
cur_chr = ' ';
break;
mid_line(CAR_RET):
loc = limit + 1;
cur_cmd = SPACER;
cur_chr = ' ';
break;
skip_blanks(CAR_RET):
any_state(COMMENT):
loc = limit + 1;
goto reread;
new_line(CAR_RET):
loc = limit + 1;
cur_cs = par_loc;
cur_cmd = eq_type(cur_cs);
cur_chr = equiv(cur_cs);
if (cur_cmd >= OUTER_CALL)
check_outer_validity();
break;
mid_line(LEFT_BRACE):
incr(align_state);
break;
skip_blanks(LEFT_BRACE):
new_line(LEFT_BRACE):
state = MID_LINE;
incr(align_state);
break;
mid_line(RIGHT_BRACE):
decr(align_state);
break;
skip_blanks(RIGHT_BRACE):
new_line(RIGHT_BRACE):
state = MID_LINE;
decr(align_state);
break;
delims(SKIP_BLANKS):
delims(NEW_LINE):
state = MID_LINE;
break;
default:
break;
}
} else {
state = NEW_LINE;
if (name > 17) {
incr(line);
first = start;
if (!force_eof) {
if (input_ln(cur_file, TRUE))
firm_up_the_line();
else force_eof = TRUE;
}
if (force_eof) {
print_char(')');
force_eof = FALSE;
update_terminal();
end_file_reading();
check_outer_validity();
goto restart;
}
if (end_line_char < 0 || end_line_char > 127)
decr(limit);
else buffer[limit] = end_line_char;
first = limit + 1;
loc = start;
} else {
if (!terminal_input) {
cur_cmd = 0;
cur_chr = 0;
return;
}
if (input_ptr > 0) {
end_file_reading();
goto restart;
}
if (selector < LOG_ONLY)
open_log_file();
if (interaction > NONSTOP_MODE) {
if (end_line_char < 0 || end_line_char > 255)
incr(limit);
if (limit == start)
print_nl("(Please type a command or say `\\end')");
print_ln();
first = start;
prompt_input("*");
limit = last;
if (end_line_char < 0 || end_line_char > 127)
decr(limit);
else buffer[limit] = end_line_char;
first = limit + 1;
loc = start;
} else
fatal_error(
"*** (job aborted, no legal \\end found)");
}
check_interrupt();
goto reread;
}
} else {
if (loc != NULL) {
t = token(loc);
loc = token_link(loc);
if (t >= CS_TOKEN_FLAG) {
cur_cs = t - CS_TOKEN_FLAG;
cur_cmd = eq_type(cur_cs);
cur_chr = equiv(cur_cs);
if (cur_cmd >= OUTER_CALL) {
if (cur_cmd == DONT_EXPAND) {
cur_cs = token(loc) - CS_TOKEN_FLAG;
loc = NULL;
cur_cmd = eq_type(cur_cs);
cur_chr = equiv(cur_cs);
if (cur_cmd > MAX_COMMAND) {
cur_cmd = RELAX;
cur_chr = NO_EXPAND_FLAG;
}
} else {
check_outer_validity();
}
}
} else {
cur_cmd = t / 0400;
cur_chr = t % 0400;
switch (cur_cmd)
{
case LEFT_BRACE:
incr(align_state);
break;
case RIGHT_BRACE:
decr(align_state);
break;
case OUT_PARAM:
begin_token_list(
param_stack[param_start + cur_chr - 1],
PARAMETER
);
goto restart;
default:
break;
}
}
} else {
end_token_list();
goto restart;
}
}
if (cur_cmd <= CAR_RET &&
cur_cmd >= TAB_MARK &&
align_state == 0) {
if (scanner_status == ALIGNING)
fatal_error("(interwoven alignment preambles are not allowed)");
cur_cmd = extra_info(cur_align);
extra_info(cur_align) = cur_chr;
if (cur_cmd == OMIT)
begin_token_list(omit_template, (qword) V_TEMPLATE);
else begin_token_list((ptr) v_part(cur_align), (qword) V_TEMPLATE);
align_state = 1000000;
goto restart;
}
}
check_outer_validity ()
{
ptr p;
ptr q;
if (scanner_status != NORMAL) {
deletions_allowed = FALSE;
if (cur_cs != 0) {
if (state == TOKEN_LIST || name < 1 || name > 17) {
p = new_token();
token(p) = CS_TOKEN_FLAG + cur_cs;
back_list(p);
}
cur_cmd = SPACER;
cur_chr = ' ';
}
if (scanner_status > SKIPPING) {
runaway();
if (cur_cs == 0) {
print_err("File ended");
} else {
cur_cs = 0;
print_err("Forbidden control sequence found");
}
print(" while scanning ");
p = new_token();
switch (scanner_status)
{
case DEFINING:
print("definition");
token(p) = RIGHT_BRACE_TOKEN + '}';
break;
case MATCHING:
print("use");
token(p) = par_token;
long_state = OUTER_CALL;
break;
case ALIGNING:
print("preamble");
token(p) = RIGHT_BRACE_TOKEN + '}';
q = p;
p = new_token();
token_link(p) = q;
token(p) = CS_TOKEN_FLAG + FROZEN_CR;
align_state = -1000000;
break;
case ABSORBING:
print("text");
token(p) = RIGHT_BRACE_TOKEN + '}';
break;
}
ins_list(p);
print(" of ");
sprint_cs(warning_index);
help_scanner();
error();
} else {
print_err("Incomplete ");
print_cmd_chr(IF_TEST, cur_if);
print("; all text was ignored after line ");
print_val(skip_line);
help_skif();
if (cur_cs != 0)
cur_cs = 0;
else
help_line[0] =
"The file ended while I was skipping conditional text.";
cur_tok = CS_TOKEN_FLAG + FROZEN_FI;
ins_error();
}
deletions_allowed = TRUE;
}
}
firm_up_the_line ()
{
int k;
limit = last;
if (pausing > 0 && interaction > NONSTOP_MODE) {
wake_up_terminal();
print_ln();
if (start < limit) {
for (k = start; k < limit; incr(k))
print_char(buffer[k]);
}
first = limit;
prompt_input("=>");
if (last > first) {
for (k = first; k < last; incr(k))
buffer[k + start - first] = buffer[k];
limit = start + last - first;
}
}
}
ptr
new_token ()
{
ptr p;
p = tok_head;
if (p != NULL) {
tok_head = token_link(tok_head);
} else if (tok_end < TOK_MAX) {
incr(tok_end);
p = tok_end;
} else {
decr(tok_low);
p = tok_low;
if (tok_low <= TOK_MIN) {
runaway();
overflow("token memory size", TOK_MAX - TOK_MIN + 1);
}
}
token_link(p) = NULL;
#ifdef STAT
incr(tok_used);
#endif
return p;
}
init_tok_mem()
{
int i;
#ifdef INIT
tok_head = NULL;
tok_end = TOK_TOP;
tok_low = tok_high;
for (i = TOK_TOP; i > tok_low; decr(i)) {
token(i) = 0;
token_link(i) = NULL;
}
token(omit_template) = END_TEMPLATE_TOKEN;
tok_used = tok_usage;
#endif
}
/*
* Help text
*/
help_scanner ()
{
help4("I suspect you have forgotten a `}', causing me",
"to read past where you wanted me to stop.",
"I'll try to recover; but if the error is serious,",
"you'd better type `E' or `X' now and fix your file.");
}
help_funny ()
{
help2("A funny symbol that I can't read has just been input.",
"Continue, and I'll forget that it ever happened.");
}
help_skif ()
{
help3("A forbidden control sequence occurred in skipped text.",
"This kind of error happens when you say `\\if...' and forget",
"the matching `\\fi'. I've inserted a `\\fi'; this might work.");
}