Google
 

Trailing-Edge - PDP-10 Archives - decuslib20-04 - decus/20-0109/select.sim
There are 4 other files named select.sim in the archive. Click here to see a list.
OPTIONS(/l);
COMMENT  SELECT --- Boolean search conditions on text files;
OPTIONS(/-A/-D/-Q/-I);
OPTIONS(/L/P/E);
EXTERNAL TEXT PROCEDURE rest, upcase;
EXTERNAL TEXT PROCEDURE scanto, from, conc;
EXTERNAL CHARACTER PROCEDURE findtrigger;
EXTERNAL BOOLEAN PROCEDURE frontcompare, puttext;
EXTERNAL INTEGER PROCEDURE scanint, search;
CLASS select;
NOT HIDDEN PROTECTED line, linecopy_buffer, operator,
set_operator_characters,
build_condition, tree_print, line_scan, array_scan,
select_errmess;
BEGIN
  CHARACTER char0, and_char, or_char, not_char;
  CHARACTER left_parenthesis, right_parenthesis;
  TEXT op_chars, select_errmess, linecopy_buffer, line;
  TEXT ARRAY line_array[1:10]; INTEGER la_index, la_max;
  BOOLEAN array_search;
  PROCEDURE set_operator_characters(t);
  VALUE t; TEXT t;
  BEGIN
    op_chars:- t;
    and_char:= t.getchar;
    or_char:= t.getchar;
    not_char:= t.getchar;
    left_parenthesis:= t.getchar;
    right_parenthesis:= t.getchar;
  END;

  CLASS operator(word);
  VALUE word; TEXT word;
  BEGIN
    BOOLEAN found, caseshift;
    loop:
    detach; INNER;
    GOTO loop;
  END;

  operator CLASS search_operator;
  BEGIN
    IF array_search THEN
    BEGIN
      found:= FALSE;
      FOR la_index:= 1 STEP 1 UNTIL la_max DO
      BEGIN
        line:- line_array[la_index]; line.setpos(1);
        IF search(line,word) <
        line.length THEN GOTO good;
      END;
      IF FALSE THEN good: found:= TRUE;
    END ELSE
    BEGIN
      line.setpos(1);
      found:= search(line,word) < line.length;
    END;
  END;

  operator CLASS and_operator(left, right);
  REF (operator) left, right;
  BEGIN
    call(left);
    IF left.found THEN
    BEGIN call(right);
      found:= right.found;
    END ELSE found:= FALSE;
  END;

  operator CLASS or_operator(left, right);
  REF (operator) left, right;
  BEGIN
    call(left);
    IF left.found THEN found:= TRUE ELSE
    BEGIN call(right);
      found:= right.found;
    END;
  END;

  operator CLASS not_operator(below);
  REF (operator) below;
  BEGIN
    call(below); found:= NOT below.found;
  END;

  BOOLEAN PROCEDURE build_condition(selection_tree,selector,
  caseshift);
  NAME selection_tree; VALUE selector;
  REF (operator) selection_tree; TEXT selector;
  BOOLEAN caseshift;
  BEGIN
    REF (operator) largest_tree;
    REF (operator) PROCEDURE interpret(selector,restrictor);
    TEXT selector; INTEGER restrictor;
    BEGIN
      REF (operator) result, below, left, right;
      CHARACTER firstchar;
      IF selector = NOTEXT THEN GOTO out;
      selector.setpos(1);
      firstchar:= selector.getchar;
      IF restrictor < 1 THEN
      BEGIN
        selector.setpos(1);
        scanto(selector,or_char); WHILE selector.more DO
        BEGIN
          left:- interpret(selector.sub(1,selector.pos-2),1);
          IF left =/= NONE THEN
          BEGIN
            right:- interpret(selector.sub(selector.pos,
            selector.length-selector.pos+1),0);
            IF right =/= NONE THEN
            BEGIN result:- NEW or_operator(selector,left,
            right); GOTO out;
            END;
          END;
          scanto(selector,or_char);
        END;
      END of or operator interpretation;
      IF restrictor < 2 THEN
      BEGIN
        selector.setpos(1);
        scanto(selector,and_char); WHILE selector.more DO
        BEGIN
          left:- interpret(selector.sub(1,selector.pos-2),2);
          IF left =/= NONE THEN
          BEGIN
            right:- interpret(selector.sub(selector.pos,
            selector.length-selector.pos+1),0);
            IF right =/= NONE THEN
            BEGIN result:- NEW and_operator(selector,left,
            right); GOTO out;
            END;
          END;
          scanto(selector,and_char);
        END;
      END of and operator interpretation;
      IF firstchar = left_parenthesis THEN
      BEGIN
        selector.setpos(selector.length);
        IF selector.getchar = right_parenthesis THEN
        BEGIN result:- interpret(selector.sub(2,
        selector.length-2),0);
          GOTO out;
        END;
      END;
      IF firstchar = not_char THEN
      BEGIN
        below:- interpret(selector.sub(2,selector.length-1),
        0);
        IF below =/= NONE THEN result:- NEW
        not_operator(selector,below);
        GOTO out;
      END;
      selector.setpos(1);
      IF findtrigger(selector,op_chars) = char0 THEN
      result:- NEW search_operator(selector);
      out: interpret:- result;
      IF (IF result == NONE THEN FALSE
      ELSE IF largest_tree == NONE THEN TRUE
      ELSE result.word.length >= largest_tree.word.length)
      THEN largest_tree:- result;
    END;
    IF caseshift THEN upcase(selector);
    selection_tree:- interpret(selector,0);
    IF selection_tree == NONE AND selector =/= NOTEXT
    THEN select_errmess:- conc(
    "?SELECT - Syntax error",
    IF largest_tree =/= NONE THEN conc(" after: ",
    largest_tree.word) ELSE NOTEXT)
    ELSE build_condition:= TRUE;
    IF selection_tree == NONE THEN selection_tree:-
    largest_tree;
    IF selection_tree =/= NONE AND caseshift THEN
    selection_tree.caseshift:= TRUE;
  END of procedure build_condition;

  PROCEDURE tree_print(top);
  REF (operator) top;
  INSPECT top WHEN search_operator DO outtext(word)
  WHEN not_operator DO
  BEGIN outchar(left_parenthesis); outchar(not_char);
    tree_print(below); outchar(right_parenthesis);
  END WHEN and_operator DO
  BEGIN outchar(left_parenthesis); tree_print(left);
  outchar(and_char);
    tree_print(right);
    outchar(right_parenthesis);
  END WHEN or_operator DO
  BEGIN outchar(left_parenthesis); tree_print(left);
  outchar(or_char);
    tree_print(right);
    outchar(right_parenthesis);
  END;
  BOOLEAN PROCEDURE line_scan(selection_tree,inline);
  REF (operator) selection_tree; TEXT inline;
  BEGIN
    IF selection_tree == NONE THEN GOTO yes;
    IF inline =/= NOTEXT THEN
    BEGIN
      IF selection_tree.caseshift THEN
      BEGIN
        IF inline.length > linecopy_buffer.length THEN
        linecopy_buffer:- blanks(inline.length+15);
        line:- linecopy_buffer.sub(1,inline.length);
        line:= inline;
        upcase(line);
      END ELSE line:- inline;
      array_search:= FALSE;
      call(selection_tree);
      IF selection_tree.found THEN GOTO yes;
    END;
    IF FALSE THEN yes: line_scan:= TRUE;
  END;
  BOOLEAN PROCEDURE array_scan(selection_tree,lines,i1,i2);
  REF (operator) selection_tree; TEXT ARRAY lines;
  INTEGER i1, i2;
  BEGIN
    INTEGER i, totallength;
    IF selection_tree == NONE THEN GOTO yes;
    FOR i:= i1 STEP 1 UNTIL i2 DO
    totallength:= totallength+lines(i).length;
    IF totallength > 0 THEN
    BEGIN
      array_search:= NOT (selection_tree.caseshift OR i2-i1 >
      9);
      IF array_search THEN
      BEGIN
        la_max:= 0;
        FOR i:= i1 STEP 1 UNTIL i2 DO
        IF lines[i] =/= NOTEXT THEN
        BEGIN
          la_max:= la_max+1; line_array[la_max]:- lines[i];
        END;
      END ELSE
      BEGIN
        totallength:= totallength+i2-i1+1;
        IF totallength > linecopy_buffer.length THEN
        linecopy_buffer:- blanks(totallength+15*(i2-i1+1));
        line:- linecopy_buffer.sub(1,totallength);
        FOR i:= i1 STEP 1 UNTIL i2 DO
        BEGIN puttext(line,lines(i)); line.putchar(char0);
        END;
        IF selection_tree.caseshift THEN upcase(line);
      END;
      call(selection_tree);
      IF selection_tree.found THEN GOTO yes;
    END;
    IF FALSE THEN yes: array_scan:= TRUE;
  END;

  set_operator_characters("&+-()");
END of select class;