home *** CD-ROM | disk | FTP | other *** search
/ Atari FTP / ATARI_FTP_0693.zip / ATARI_FTP_0693 / Tex / Tex29 / StTeXsrc.zoo / src / eval.c < prev    next >
C/C++ Source or Header  |  1988-08-13  |  15KB  |  716 lines

  1.  
  2. /*
  3.  * @(#)eval.c 2.5 EPA
  4.  *
  5.  * Copyright 1987,1988 Pat J Monardo
  6.  *
  7.  * Redistribution of this file is permitted through
  8.  * the specifications in the file COPYING.
  9.  *
  10.  * 
  11.  */
  12.  
  13. #include "tex.h"
  14. #include "tfm.h"
  15. #include "eqstack.h"
  16. #include "token.h"
  17. #include "scan.h"
  18. #include "tokenstack.h"
  19. #include "evalstack.h"
  20. #include "box.h"
  21. #include "boxlists.h"
  22. #include "math.h"
  23. #include "mathlists.h"
  24. #include "cond.h"
  25. #include "def.h"
  26. #include "dvi.h"
  27. #include "pack.h"
  28. #include "page.h"
  29. #include "par.h"
  30. #include "eval.h"
  31.  
  32. #define vmode(CMD) \
  33.     case VMODE + CMD
  34.  
  35. #define hmode(CMD) \
  36.     case HMODE + CMD
  37.  
  38. #define non_math(M) \
  39.     case VMODE + M: \
  40.     case HMODE + M
  41.  
  42. #define mmode(CMD) \
  43.     case MMODE + CMD
  44.  
  45. #define any_mode(CMD) \
  46.     case VMODE + CMD: \
  47.     case HMODE + CMD: \
  48.     case MMODE + CMD
  49.  
  50. main_control ()
  51. {
  52.     byte    c;
  53.     int     intofc;
  54.     fnt     f;
  55.     qqqq    i;
  56.     qqqq    j;
  57.     int     k;
  58.     qword   l;
  59.     ptr     p;
  60.     ptr     q;
  61.     hword   r;
  62.     int     s;
  63.     int     t;
  64.     bool    ligature_present;
  65.  
  66.  
  67.     if (every_job != NULL)
  68.         begin_token_list(every_job, EVERY_JOB_TEXT);
  69.  
  70. big_switch:
  71.     get_x_token();
  72.  
  73. reswitch:
  74.     if (interrupt) {
  75.         if (OK_to_interrupt) {
  76.             back_input();
  77.             pause_for_instructions();
  78.             goto big_switch;
  79.         }
  80.     }
  81.  
  82.     if (tracing_commands > 0)
  83.         show_cur_cmd_chr();
  84.  
  85.     switch (abs(mode) + cur_cmd)
  86.     {
  87.     hmode(LETTER):
  88.     hmode(OTHER_CHAR):
  89.     hmode(CHAR_GIVEN):
  90.         goto main_loop;
  91.     
  92.     hmode(CHAR_NUM):
  93.         scan_char_num();
  94.         cur_chr = cur_val;
  95.         goto main_loop;
  96.  
  97.     hmode(SPACER):
  98.         if (space_factor == 1000)
  99.             goto append_normal_space;
  100.         else app_space();
  101.         break;
  102.     
  103.     hmode(EX_SPACE):
  104.     mmode(EX_SPACE):
  105.         goto append_normal_space;
  106.     
  107.     any_mode(RELAX):
  108.     vmode(SPACER):
  109.     mmode(SPACER):
  110.         break;
  111.     
  112.     any_mode(IGNORE_SPACES):
  113.         get_nbx_token();
  114.         goto reswitch;
  115.  
  116.     vmode(STOP):
  117.         if (its_all_over())
  118.             return;
  119.         break;
  120.  
  121.     any_mode(LAST_ITEM):
  122.     any_mode(MAC_PARAM):
  123.     non_math(EQ_NO):
  124.     vmode(VMOVE):
  125.     hmode(HMOVE):
  126.     mmode(HMOVE):
  127.     vmode(VADJUST):
  128.     vmode(ITAL_CORR):
  129.         report_illegal_case();
  130.         break;
  131.  
  132.     non_math(SUP_MARK):
  133.     non_math(SUB_MARK):
  134.     non_math(MATH_CHAR_NUM):
  135.     non_math(MATH_GIVEN):
  136.     non_math(MATH_COMP):
  137.     non_math(DELIM_NUM):
  138.     non_math(LEFT_RIGHT):
  139.     non_math(ABOVE):
  140.     non_math(RADICAL):
  141.     non_math(MATH_STYLE):
  142.     non_math(MATH_CHOICE):
  143.     non_math(VCENTER):
  144.     non_math(NON_SCRIPT):
  145.     non_math(MKERN):
  146.     non_math(LIMIT_SWITCH):
  147.     non_math(MSKIP):
  148.     non_math(MATH_ACCENT):
  149.     mmode(ENDV):
  150.     mmode(PAR_END):
  151.     mmode(STOP):
  152.     mmode(VSKIP):
  153.     mmode(UN_VBOX):
  154.     mmode(VALIGN):
  155.     mmode(HRULE):
  156.         insert_dollar_sign();
  157.         break;
  158.     
  159.     vmode(HRULE):
  160.     hmode(VRULE):
  161.     mmode(VRULE):
  162.         tail_append(scan_rule_spec());
  163.         if (abs(mode) == VMODE)
  164.             prev_depth = IGNORE_DEPTH;
  165.         else if (abs(mode) == HMODE)
  166.             space_factor = 1000;
  167.         break;
  168.     
  169.     vmode(VSKIP):
  170.     hmode(HSKIP):
  171.     mmode(HSKIP):
  172.     mmode(MSKIP):
  173.         append_glue();
  174.         break;
  175.     
  176.     any_mode(KERN):
  177.     mmode(MKERN):
  178.         append_kern();
  179.         break;
  180.     
  181.     non_math(LEFT_BRACE):
  182.         new_save_level(SIMPLE_GROUP);
  183.         break;
  184.  
  185.     any_mode(BEGIN_GROUP):
  186.         new_save_level(SEMI_SIMPLE_GROUP);
  187.         break;
  188.  
  189.     any_mode(END_GROUP):
  190.         if (cur_group == SEMI_SIMPLE_GROUP)
  191.             unsave();
  192.         else off_save();
  193.         break;
  194.     
  195.     any_mode(RIGHT_BRACE):
  196.         handle_right_brace();
  197.         break;
  198.  
  199.     vmode(HMOVE):
  200.     hmode(VMOVE):
  201.     mmode(VMOVE):
  202.         t = cur_chr;
  203.         scan_normal_dimen();
  204.         if (t == 0)
  205.             saved(0) = cur_val;
  206.         else saved(0) = -cur_val;
  207.         scan_box();
  208.         break;
  209.     
  210.     any_mode(LEADER_SHIP):
  211.         saved(0) = LEADER_FLAG - A_LEADERS + cur_chr;
  212.         scan_box();
  213.         break;
  214.     
  215.     any_mode(MAKE_BOX):
  216.         saved(0) = 0;
  217.         begin_box();
  218.         break;
  219.  
  220.     vmode(START_PAR):
  221.         new_graf(cur_chr > 0);
  222.         break;
  223.     
  224.     vmode(LETTER):
  225.     vmode(OTHER_CHAR):
  226.     vmode(CHAR_NUM):
  227.     vmode(CHAR_GIVEN):
  228.     vmode(MATH_SHIFT):
  229.     vmode(UN_HBOX):
  230.     vmode(VRULE):
  231.     vmode(ACCENT):
  232.     vmode(DISCRETIONARY):
  233.     vmode(HSKIP):
  234.     vmode(VALIGN):
  235.     vmode(EX_SPACE):
  236.         back_input();
  237.         new_graf(TRUE);
  238.         break;
  239.     
  240.     hmode(START_PAR):
  241.     mmode(START_PAR):
  242.         indent_in_hmode();
  243.         break;
  244.     
  245.     vmode(PAR_END):
  246.         normal_paragraph();
  247.         if (mode > 0)
  248.             build_page();
  249.         break;
  250.  
  251.     hmode(PAR_END):
  252.         if (align_state < 0)
  253.             off_save();
  254.         end_graf();
  255.         if (mode == VMODE)  
  256.             build_page();
  257.         break;
  258.     
  259.     hmode(STOP):
  260.     hmode(VSKIP):
  261.     hmode(HRULE):
  262.     hmode(UN_VBOX):
  263.     hmode(HALIGN):
  264.         head_for_vmode();
  265.         break;
  266.     
  267.     any_mode(INSERT):
  268.     hmode(VADJUST):
  269.     mmode(VADJUST):
  270.         begin_insert_or_adjust();
  271.         break;
  272.     
  273.     any_mode(MARK):
  274.         make_mark();
  275.         break;
  276.     
  277.     any_mode(BREAK_PENALTY):
  278.         append_penalty();
  279.         break;
  280.     
  281.     any_mode(REMOVE_ITEM):
  282.         delete_last();
  283.         break;
  284.     
  285.     vmode(UN_VBOX):
  286.     hmode(UN_HBOX):
  287.     mmode(UN_HBOX):
  288.         unpackage();
  289.         break;
  290.     
  291.     hmode(ITAL_CORR):
  292.         append_italic_correction();
  293.         break;
  294.     
  295.     mmode(ITAL_CORR):
  296.         tail_append(new_kern(0L));
  297.         break;
  298.  
  299.     hmode(DISCRETIONARY):
  300.     mmode(DISCRETIONARY):
  301.         append_discretionary();
  302.         break;
  303.     
  304.     hmode(ACCENT):
  305.         make_accent();
  306.         break;
  307.     
  308.     any_mode(CAR_RET):
  309.     any_mode(TAB_MARK):
  310.         align_error();
  311.         break;
  312.  
  313.     any_mode(NO_ALIGN):
  314.         no_align_error();
  315.         break;
  316.     
  317.     any_mode(OMIT):
  318.         omit_error();
  319.         break;
  320.  
  321.     vmode(HALIGN):
  322.     hmode(VALIGN):
  323.         init_align();
  324.         break;
  325.     
  326.     mmode(HALIGN):
  327.         if (privileged())
  328.             init_align();
  329.         break;
  330.  
  331.     vmode(ENDV):
  332.     hmode(ENDV):
  333.         do_endv();
  334.         break;
  335.     
  336.     any_mode(END_CS_NAME):
  337.         cs_error();
  338.         break;
  339.  
  340.     hmode(MATH_SHIFT):
  341.         init_math();
  342.         break;
  343.     
  344.     mmode(EQ_NO):
  345.         if (privileged())
  346.             start_eq_no();
  347.         break;
  348.     
  349.     mmode(LEFT_BRACE):
  350.         tail_append(new_noad()); 
  351.         back_input();
  352.         scan_math(nucleus(tail));
  353.         break;
  354.  
  355.     mmode(LETTER):
  356.     mmode(OTHER_CHAR):
  357.     mmode(CHAR_GIVEN):
  358.         if (cur_chr < 256)
  359.             set_math_char(ho(math_code(cur_chr)));
  360.         else set_math_char(cur_chr);
  361.         break;
  362.     
  363.     mmode(CHAR_NUM):
  364.         scan_char_num();
  365.         cur_chr = cur_val;
  366.         if (cur_chr < 256)
  367.             set_math_char(ho(math_code(cur_chr)));
  368.         else set_math_char(cur_chr);
  369.         break;
  370.     
  371.     mmode(MATH_CHAR_NUM):
  372.         scan_fifteen_bit_int();
  373.         set_math_char((hword) cur_val);
  374.         break;
  375.     
  376.     mmode(MATH_GIVEN):
  377.         set_math_char(cur_chr);
  378.         break;
  379.  
  380.     mmode(DELIM_NUM):
  381.         scan_twenty_seven_bit_int();
  382.         set_math_char((hword) (cur_val / 010000));
  383.         break;
  384.     
  385.     mmode(MATH_COMP):
  386.         tail_append(new_noad());
  387.         type(tail) = cur_chr;
  388.         scan_math(nucleus(tail));
  389.         break;
  390.     
  391.     mmode(LIMIT_SWITCH):
  392.         math_limit_switch();
  393.         break;
  394.  
  395.     mmode(RADICAL):
  396.         math_radical();
  397.         break;
  398.  
  399.     mmode(ACCENT):
  400.     mmode(MATH_ACCENT):
  401.         math_ac();
  402.         break;
  403.  
  404.     mmode(VCENTER):
  405.         scan_spec();
  406.         new_save_level(VCENTER_GROUP);
  407.         normal_paragraph();
  408.         push_nest();
  409.         mode = -VMODE;
  410.         prev_depth = IGNORE_DEPTH;
  411.         if (every_vbox != NULL)
  412.             begin_token_list(every_vbox, EVERY_VBOX_TEXT);
  413.         break;
  414.     
  415.     mmode(MATH_STYLE):
  416.         tail_append(new_style(cur_chr));
  417.         break;
  418.     
  419.     mmode(NON_SCRIPT):
  420.         tail_append(new_glue(zero_glue));
  421.         subtype(tail) = COND_MATH_GLUE;
  422.         break;
  423.     
  424.     mmode(MATH_CHOICE):
  425.         append_choices();
  426.         break;
  427.  
  428.     mmode(SUB_MARK):
  429.     mmode(SUP_MARK):
  430.         sub_sup();
  431.         break;
  432.     
  433.     mmode(ABOVE):
  434.         math_fraction();
  435.         break;
  436.     
  437.     mmode(LEFT_RIGHT):
  438.         math_left_right();
  439.         break;
  440.  
  441.     mmode(MATH_SHIFT):
  442.         if (cur_group == MATH_SHIFT_GROUP)
  443.             after_math();
  444.         else off_save();
  445.         break;
  446.     
  447.     any_mode(ASSIGN_TOKS):
  448.     any_mode(ASSIGN_INT):
  449.     any_mode(ASSIGN_DIMEN):
  450.     any_mode(ASSIGN_GLUE):
  451.     any_mode(ASSIGN_MU_GLUE):
  452.     any_mode(ASSIGN_FONT_DIMEN):
  453.     any_mode(ASSIGN_FONT_INT):
  454.     any_mode(SET_AUX):
  455.     any_mode(SET_PREV_GRAF):
  456.     any_mode(SET_PAGE_DIMEN):
  457.     any_mode(SET_PAGE_INT):
  458.     any_mode(SET_BOX_DIMEN):
  459.     any_mode(SET_SHAPE):
  460.     any_mode(DEF_CODE):
  461.     any_mode(DEF_FAMILY):
  462.     any_mode(SET_FONT):
  463.     any_mode(DEF_FONT):
  464.     any_mode(REGISTER):
  465.     any_mode(ADVANCE):
  466.     any_mode(MULTIPLY):
  467.     any_mode(DIVIDE):
  468.     any_mode(PREFIX):
  469.     any_mode(LET):
  470.     any_mode(SHORTHAND_DEF):
  471.     any_mode(READ_TO_CS):
  472.     any_mode(DEF):
  473.     any_mode(SET_BOX):
  474.     any_mode(TOKS_REGISTER):
  475.     any_mode(HYPH_DATA):
  476.     any_mode(SET_INTERACTION):
  477.         prefixed_command();
  478.         break;
  479.  
  480.     any_mode(AFTER_ASSIGNMENT):
  481.         get_token();
  482.         after_token = cur_tok;
  483.         break;
  484.     
  485.     any_mode(AFTER_GROUP):
  486.         get_token();
  487.         save_for_after(cur_tok);
  488.         break;
  489.  
  490.     any_mode(IN_STREAM):
  491.         clopen_stream();
  492.         break;
  493.  
  494.     any_mode(MESSAGE):
  495.         issue_message();
  496.         break;
  497.     
  498.     any_mode(CASE_SHIFT):
  499.         shift_case();
  500.         break;
  501.     
  502.     any_mode(XRAY):
  503.         show_whatever();
  504.         break;
  505.     
  506.     any_mode(EXTENSION):
  507.         do_extension();
  508.         break;
  509.     }
  510.     goto big_switch;
  511.  
  512. #define make_lig_disc() \
  513.     {if (ligature_present) { \
  514.         p = new_ligature(f, l, link(q)); \
  515.         link(q) = p; \
  516.         tail = p;} \
  517.     if (c == hyphen_char[f] && mode == HMODE) \
  518.         tail_append(new_disc());}
  519.  
  520. #define space_glue() \
  521.     {p = font_glue[cur_font]; \
  522.     if (p == NULL) { \
  523.         f = cur_font; \
  524.         p = new_spec(zero_glue); \
  525.         k = param_base[f] + SPACE_CODE; \
  526.         width(p) = font_info[k].sc; \
  527.         stretch(p) = font_info[k + 1].sc; \
  528.         shrink(p) = font_info[k + 2].sc; \
  529.         font_glue[f] = p;}}
  530.  
  531. main_loop:
  532.     f = cur_font;
  533.     c = cur_chr;
  534.  
  535. main_loop_1:
  536.     if (c < font_bc[f] || c > font_ec[f]) {
  537.         char_warning(f, c);
  538.         goto big_switch;
  539.     }
  540.  
  541. main_loop_2:
  542.     q = tail;
  543.     ligature_present = FALSE;
  544.     l = qi(c);
  545.  
  546. main_loop_3:
  547.     intofc = c; if ( intofc < 256) {
  548.         s = sf_code(c);
  549.         if (s == 1000)
  550.             space_factor = 1000;
  551.         else if (s < 1000) {
  552.             if (s > 0)
  553.                 space_factor = s;
  554.         } else if (space_factor < 1000)
  555.             space_factor = 1000;
  556.         else space_factor = s;
  557.     } else space_factor = 1000;
  558.     i = char_info(f, l);
  559.     if (char_exists(i)) {
  560.         fast_get_avail(p);
  561.         font(p) = f;
  562.         character(p) = qi(c);
  563.         link(tail) = p;
  564.         tail = p;
  565.     } else char_warning(f, qo(l));
  566.     get_next();
  567.     if (cur_cmd == LETTER ||
  568.         cur_cmd == OTHER_CHAR ||
  569.         cur_cmd == CHAR_GIVEN)
  570.         r = qi(cur_chr);
  571.     else {
  572.         x_token();
  573.         if (cur_cmd == LETTER ||
  574.             cur_cmd == OTHER_CHAR ||
  575.             cur_cmd == CHAR_GIVEN)
  576.             r = qi(cur_chr);
  577.         else if (cur_cmd == CHAR_NUM) {
  578.             scan_char_num();
  579.             r = qi(cur_val);
  580.         } else
  581.             r = qi(256);
  582.     }
  583.     if (char_tag(i) == LIG_TAG && r != qi(256)) {
  584.         k = lig_kern_start(f, i);
  585.         do {
  586.             j = font_info[k].qqqq;
  587.             if (next_char(j) == r) {
  588.                 if (op_bit(j) < KERN_FLAG) {
  589.                     ligature_present = TRUE;
  590.                     l = rem_byte(j);
  591.                     c = qo(r);
  592.                     goto main_loop_3;
  593.                 } else {
  594.                     make_lig_disc();
  595.                     tail_append(new_kern(char_kern(f, j)));
  596.                     c = qo(r);
  597.                     goto main_loop_2;
  598.                 }
  599.             }
  600.             incr(k);
  601.         } while (stop_bit(j) < STOP_FLAG);
  602.     }
  603.     make_lig_disc();
  604.     if (r == qi(256))
  605.         goto reswitch;
  606.     c = qo(r);
  607.     goto main_loop_1;
  608.  
  609. append_normal_space:
  610.     if (space_skip == zero_glue) {
  611.         space_glue();
  612.         q = new_glue(p);
  613.     } else
  614.         q = new_param_glue(SPACE_SKIP_CODE);
  615.     link(tail) = q;
  616.     tail = q;
  617.     goto big_switch;
  618. }
  619.  
  620. app_space ()
  621. {
  622.     fnt     f;
  623.     int     k;
  624.     ptr     p;
  625.     ptr     q;
  626.  
  627.     if (space_factor >= 2000 && xspace_skip != zero_glue)
  628.         q = new_param_glue(XSPACE_SKIP_CODE);
  629.     else {
  630.         if (space_skip != zero_glue)
  631.             p = space_skip;
  632.         else space_glue();
  633.         p = new_spec(p);
  634.         if (space_factor >= 2000)
  635.             width(p) += extra_space(cur_font);
  636.         stretch(p) = xn_over_d(stretch(p), space_factor, 1000L);
  637.         shrink(p) = xn_over_d(shrink(p), 1000L, space_factor);
  638.         q = new_glue(p);
  639.         glue_ref_count(p) = NULL;
  640.     }
  641.     link(tail) = q;
  642.     tail = q;
  643. }
  644.  
  645. insert_dollar_sign ()
  646. {
  647.     back_input();
  648.     cur_tok = MATH_SHIFT_TOKEN + '$';
  649.     print_err("Missing $ inserted");
  650.     help_dollar();
  651.     ins_error();
  652. }
  653.  
  654. report_illegal_case ()
  655. {
  656.     you_cant();
  657.     help_illegal_case();
  658.     error();
  659. }
  660.  
  661. you_cant ()
  662. {
  663.     print_err("You can't use `");
  664.     print_cmd_chr(cur_cmd, cur_chr);
  665.     print("' in ");
  666.     print_mode(mode);
  667. }
  668.  
  669. bool
  670. privileged ()
  671. {
  672.     if (mode > 0)
  673.         return TRUE;
  674.     else {
  675.         report_illegal_case();
  676.         return FALSE;
  677.     }
  678. }
  679.  
  680. bool
  681. its_all_over ()
  682. {
  683.     if (privileged()) {
  684.         if (page_head == page_tail &&
  685.             head == tail &&
  686.             dead_cycles == 0) {
  687.             return TRUE;
  688.         }
  689.         back_input();
  690.         tail_append(new_null_box());
  691.         width(tail) = hsize;
  692.         tail_append(new_glue(fill_glue));
  693.         tail_append(new_penalty(-010000000000));
  694.         build_page();
  695.     }
  696.     return FALSE;
  697. }
  698.  
  699. /*
  700.  * Help text
  701.  */
  702.  
  703. help_dollar ()
  704. {
  705.     help2("I've inserted a begin-math/end-math symbol since I think",
  706.     "you left one out. Proceed, with fingers crossed.");
  707. }
  708.  
  709. help_illegal_case ()
  710. {
  711.     help4("Sorry, but I'm not programmed to handle this case;",
  712.     "I'll just pretend that you didn't ask for it.",
  713.     "If you're in the wrong mode, you might be able to",
  714.     "return to the right one by typing `I}' or `I$' or `I\\par'.");
  715. }
  716.