|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)scan.c 1.1 86/02/03 Copyr 1985 Sun Micro";
3: #endif
4:
5: /*
6: * Copyright (c) 1985 by Sun Microsystems, Inc.
7: */
8:
9: #include "as.h"
10:
11: /* process lines from source file, returns when EOF detected */
12:
13: #define LSIZE 4*BUFSIZ+2 /* max size of input line + fudge */
14:
15: char *sassign(),*sdefer(),*exp(),*term();
16: struct ins_bkt * sopcode();
17: int slabel();
18:
19: char iline[LSIZE]; /* current input line resides */
20: int line_no; /* current input line number */
21: char code[CODE_MAX]; /* where generated code is stored */
22: long dot; /* offset in current csect */
23: int bc; /* size of code for current line */
24: int opshow = 0;
25: long break_line = -1, break_pass = 1;
26:
27: /* for local labels: ``[0-9]:'', and references ``[0-9][bh]'' */
28: extern char *ll_format;
29: extern int ll_val[10];
30:
31: scan()
32: {
33: register int i;
34: register char *p; /* pointer into input line */
35: char *token; /* pointer to beginning of last token */
36: struct ins_bkt * opindex;/* index of opcode on current line */
37: # ifdef C2
38: char *docomment();
39: # endif
40:
41: #ifdef AS
42: /* setup stupid local-lable array */
43: for( i = 0; i < 10; ll_val[i++] = -1 ) ;
44: #endif
45:
46: while (iline[LSIZE-2]='\0', fgets(iline,LSIZE,stdin) == iline) {
47: line_no++;
48: #ifdef AS
49: if (line_no == break_line && pass == break_pass) break_here();
50: #endif
51: #ifdef C2
52: if (line_no == break_line ) break_here();
53: #endif
54: /* a cheap way to find if the line was too long */
55: if (iline[LSIZE-2] != '\0'){ PROG_ERROR(E_LINELONG); continue; }
56: p = iline;
57:
58: /* see what's the first thing on the line. if newline or comment
59: * char just ignore line all together. if start of symbol see
60: * what follows. otherwise error.
61: */
62: restart: skipb(p);
63: i = cinfo[*p]; /* see what we know about next char */
64: /* hack to make # in col 1 a comment -- for cpp leavings */
65: if (i == EOL || i == IMM) {
66: /* further hack to make ; in line act as seperator. */
67: if (*p == ';'){ p++; goto restart;}
68: # ifdef C2
69: p = docomment(p);
70: if (p==NULL)
71: return 1; /* special return */
72: # endif
73: continue;
74: }
75: if (!(i & (S|D))) { PROG_ERROR(E_BADCHAR); continue; }
76: bc = 0;
77: # ifdef AS
78: code_length = 0;
79: # endif
80:
81: /* what follows is either label or opcode, gobble it up */
82: token = p;
83: skips(p);
84: skipb(p);
85: i = cinfo[*p];
86:
87: /* if next char is ":", this is label definition */
88: if (i == COL) { p++; slabel(token); goto restart; }
89:
90: /* if next char is "=", this is label assignment */
91: if (i == EQL) {
92: p = sassign(++p,token);
93: if (cinfo[*p] != EOL) PROG_ERROR(E_BADCHAR);
94: /* hack to make ; in line act as seperator. */
95: if (*p == ';'){ p++; goto restart;}
96: continue;
97: }
98:
99: /* otherwise this must be opcode, find its index */
100: if ((opindex = sopcode(token)) == 0) {
101: PROG_ERROR(E_OPCODE);
102: continue;
103: }
104:
105: if (i == EOL) { numops = 0; goto doins; }
106:
107: /* keep reading operands until we run out of room or hit EOL */
108: for (numops = 1; numops <= OPERANDS_MAX; numops++) {
109: p = soperand(p,&operands[numops-1]);
110: skipb(p);
111: i = cinfo[*p];
112: if (i == COM) { p++; skipb(p); continue; }
113: if (i == EOL) goto doins;
114: PROG_ERROR(E_OPERAND);
115: goto next;
116: }
117: PROG_ERROR(E_NUMOPS);
118: next: continue;
119:
120: doins:
121: instruction(opindex);
122: dot += bc;
123: dot_bkt->value_s = dot;
124:
125: /* hack to make ; in line act as seperator. */
126: if (*p == ';'){ p++; goto restart;}
127: }
128: return 0; /* normal exit */
129: } /* end Scan */
130:
131: /* lookup token in opcode hash table, return 0 if not found */
132: struct ins_bkt *
133: sopcode(token)
134: register char *token;
135: {
136: register struct ins_ptr *ipp;
137: char *mnem = token;
138: char savechar;
139:
140: /* make asciz version of mnemonic */
141: while (cinfo[*token] & T) token++;
142: savechar = *token;
143: *token = '\0';
144:
145: /* look through appropriate hash bucket */
146: ipp = ins_hash_tab[hash(mnem)];
147: while (ipp) {
148: if (strcmp(ipp->name_p,mnem) == 0) break;
149: ipp = ipp->next_p;
150: }
151: *token = savechar;
152:
153: if( ipp == 0) return 0;
154: return(ipp->this_p);
155: } /* end sopcode */
156:
157:
158: /* handle assignment to a label, return updated line pointer */
159: char *
160: sassign(lptr,token)
161: register char *token;
162: register char *lptr;
163: {
164: register char *p;
165: register struct sym_bkt *sbp;
166: struct oper value;
167: char nextc;
168: static struct oper zero_oper = { T_NULL, 0, 0, 0, 0, NULL};
169:
170: /* make asciz version of label */
171: p = token;
172: while (cinfo[*p] & T) p++;
173: nextc = *p;
174: *p = '\0';
175: value = zero_oper;
176:
177: /* find/enter symbol in the symbol table, and get its new value */
178: sbp = lookup(token);
179: lptr = exp(lptr,&value);
180:
181: /* if assignment is to dot, we'll treat it specially */
182: if (sbp == dot_bkt) {
183: #ifdef AS
184: int deltadot;
185: #endif AS
186: if (value.sym_o && value.sym_o->csect_s!=cur_csect_name)
187: PROG_ERROR(E_OPERAND);
188: #ifdef AS
189: deltadot = value.value_o - dot;
190: if (deltadot<0)
191: PROG_ERROR(E_OPERAND);
192: operands[0].value_o = deltadot;
193: skip_op( NULL );
194: #endif
195: } else {
196: if (value.sym_o != NULL) {
197: sbp->value_s = value.sym_o->value_s;
198: } else {
199: sbp->value_s = value.value_o;
200: }
201: sbp->csect_s = (value.sym_o!=NULL) ? value.sym_o->csect_s : C_UNDEF;
202: if (sbp->attr_s & S_LABEL) {
203: PROG_ERROR(E_EQUALS);
204: } else if (value.type_o == T_REG)
205: sbp->attr_s = (sbp->attr_s&S_EXT) | S_REG | S_DEC | S_DEF;
206: else
207: sbp->attr_s = (sbp->attr_s&S_EXT) |
208: ((value.sym_o!=NULL) ?
209: (value.sym_o->attr_s & ~(S_LABEL|S_PERM)): (S_DEC | S_DEF));
210: }
211:
212: if (opshow) fprintf(stderr,"sassign(%s) = %ld, %ld\n",
213: token, value.value_o, sbp->attr_s);
214: #if C2
215: /* echo assignment immediately. RHS involving (.) will break. Fix later */
216: printf(" %s = ", sbp->name_s);
217: printoperand( &value );
218: putchar('\n');
219: #endif
220:
221: *p = nextc;
222:
223: /* return update line pointer */
224: skipb(lptr);
225: return(lptr);
226: } /* end sassign */
227:
228: /* hashing routine for Symbol and Instruction hash tables */
229: hash(s)
230: register char *s;
231: {
232: register int i = 0;
233:
234: while (*s) i = i*10 + *s++ - ' ';
235: i = i % HASH_MAX;
236: return(i<0 ? i+HASH_MAX : i);
237: } /* end hash */
238:
239:
240: break_here(){ }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.