|
|
1.1 root 1: -IN80
2: -TITLE minpp: minimal conditional assenbly preprocessor
3: *
4: * This program processes MINIMAL conditional assembly directives.
5: * Its existence is required because none of the assemblers for
6: * VAX/UN*X support conditional assembly. The C-preprocessor
7: * could be used instead. However, the MINIMAL conditional assembly
8: * commands would have to be translated first and this hinders
9: * development work at non-UN*X sites.
10: *
11: &anchor = 1
12: &stlimit = 1000000000
13: *
14: * Obtain file information.
15: *
16: infile = input
17: input( .in,0,infile )
18: terminal = 'Input file: ' infile
19: outfile = input
20: output( .out,1,outfile )
21: terminal = 'Output file: ' outfile
22: *
23: * XFERVEC is the transfer vector for routing control to handlers
24: * for conditional assembly directives.
25: *
26: xfervec = table( 11,,.badop )
27: xfervec['.DEF'] = .defop
28: xfervec['.UNDEF'] = .undefop
29: xfervec['.IF'] = .ifop
30: xfervec['.THEN'] = .thenop
31: xfervec['.ELSE'] = .elseop
32: xfervec['.FI'] = .fiop
33: *
34: * SYMTBL tracks defined conditional symbols. (Undefined symbols
35: * are assigned null values in SYMTBL.)
36: *
37: symtbl = table( 11 )
38: *
39: * STATESTK maintains all state information while processing conditional
40: * statements. LEVEL indexes the top entry. Another variable, TOP,
41: * has a copy of SAVESTK[LEVEL].
42: *
43: statestk = array( 30 )
44: level = 0
45: top =
46: *
47: * Each STATE entry in STATESTK contains state information about
48: * the processing for each active .IF. The state is maintained
49: * as 2 fields:
50: *
51: * result the result of the .IF expression evaluation-
52: * TRUE, FALSE, or BYPASS
53: *
54: * mode whether processing THEN or ELSE portion of .IF
55: *
56: data( 'state(result,mode)' )
57: false = 0
58: true = 1
59: bypass = 2
60: else = 0
61: then = 1
62: *
63: * PROCESSREC is indexed by the current RESULT and MODE to determine
64: * whether or not a statement should be processed and written to the
65: * output file.
66: *
67: processrec = array( false ':' bypass ',' else ':' then,0 )
68: processrec[true,then] = 1
69: processrec[false,else] = 1
70: *
71: * RIP breaks up conditional assembly directives.
72: *
73: sep = ' '
74: rip = ( break(sep) | rem ) . condcmd
75: + ( span(sep) | '' )
76: + ( break(sep) | rem ) . condvar
77: *
78: * Main loop: read a record and transfer control to appropriate
79: * conditional assembly directive handler or other statement handler.
80: *
81: loop line = in :f(done)
82: incnt = incnt + 1
83: leq( substr( line,1,1 ),'.' ) :f(other)
84: line ? rip :s( $xfervec[condcmd] )
85: *
86: * Syntax error handler.
87: *
88: synerr terminal = incnt '(syntax error):' line :(loop)
89: *
90: * Process define
91: *
92: defop ident( condvar ) :s(synerr)
93: eq( level ) :s(defok)
94: eq( processrec[result(top),mode(top)] ) :s(loop)
95: defok symtbl[condvar] = 1 :(loop)
96: *
97: * process undefine
98: *
99: undefop
100: ident( condvar ) :s(synerr)
101: eq( level ) :s(undok)
102: eq( processrec[result(top),mode(top)] ) :s(loop)
103: undok symtbl[condvar] = :(loop)
104: *
105: * process if
106: *
107: ifop ident( condvar ) :s(synerr)
108: eq( level ) :s(ifok)
109: *
110: * Here for .IF encountered during bypass state.
111: *
112: ne( processrec[result(top),mode(top)] ) :s(ifok)
113: level = level + 1
114: top = statestk[level] = state(bypass,then) :(loop)
115: *
116: * Here for .IF to be processed normally.
117: *
118: ifok level = level + 1
119: top = statestk[level] = state(
120: + ( differ( symtbl[condvar] ) true,false ),
121: + then ) :(loop)
122: *
123: * process .then
124: *
125: thenop eq(level) :s(synerr)f(loop)
126: *
127: * process .else
128: *
129: elseop mode(top) = ne( level ) else :s(loop)f(synerr)
130: *
131: * process .fi
132: *
133: fiop level = ne( level ) level - 1 :f(synerr)
134: top = ( ne( level ) statestk[level],'' ) :(loop)
135: *
136: * process statements other than consitional directives.
137: *
138: other eq( level ) :s(outit)
139: eq( processrec[result(top),mode(top)] ) :s(loop)
140: outit out = line
141: outcnt = outcnt + 1 :(loop)
142: *
143: * finished - print out statistics.
144: *
145: done terminal = lpad( incnt,6 ) ' input records.'
146: terminal = lpad( outcnt,6 ) ' output records.'
147: end
148: spitv35.min
149: spitv35.ppmin
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.