1 /* pMARS -- a portable Memory Array Redcode Simulator
2 * Copyright (C) 1993-1996 Albert Ma, Na'ndor Sieben, Stefan Strack and Mintardjo Wangsawidjaja
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 */
18
19 /*
20 * $Id: token.c,v 1.1.1.1 2000/08/20 13:29:46 iltzu Exp $
21 */
22
23 #include <ctype.h>
24 #include <string.h>
25
26 #include "global.h"
27 #include "asm.h"
28
29 /* **************************** Prototype ******************************** */
30
31 #ifdef NEW_STYLE
32 #define toupper_(x) (toupper(x))
33 #else
34 #define toupper_(x) (isalpha(x) && islower(x) ? toupper(x) : (x))
35 #endif
36
37 /* *************************** definitions ******************************* */
38
39 #define is_addr(ch) pstrchr(addr_sym, (int) ch)
40 #define is_expr(ch) pstrchr(expr_sym, (int) ch)
41 #define is_alpha(ch) (isalpha(ch) || (ch) == '_')
42
43 /* ********************************************************************** */
44
45 char *
pstrchr(s,c)46 pstrchr(s, c)
47 char *s;
48 int c;
49 {
50 do {
51 if ((int) *s == c)
52 return s;
53 } while (*s++);
54
55 return NULL;
56 }
57
58 /* ********************************************************************** */
59
60 char *
pstrdup(s)61 pstrdup(s)
62 char *s;
63 {
64 char *p, *q;
65 register int i;
66
67 for (q = s, i = 0; *q; q++)
68 i++;
69
70 if ((p = (char *) MALLOC(sizeof(char) * (i + 1))) != NULL) {
71 q = p;
72 while (*s)
73 *q++ = *s++;
74 *q = '\0';
75 }
76 return p;
77 }
78
79 /* ********************************************************************** */
80
81 char *
pstrcat(s1,s2)82 pstrcat(s1, s2)
83 char *s1, *s2;
84 {
85 register char *p = s1;
86
87 while (*p)
88 p++;
89 while (*s2)
90 *p++ = *s2++;
91 *p = '\0';
92
93 return s1;
94 }
95
96 /* ********************************************************************** */
97
98 /* return src of char in charset. charset is a string */
99 uChar
ch_in_set(c,s)100 ch_in_set(c, s)
101 uShrt c;
102 char *s;
103 {
104 char cc;
105 register char a;
106 register uChar i;
107
108 cc = (char) c;
109 for (i = 0; ((a = s[i]) != '\0') && (a != cc); i++);
110 return (i);
111 }
112
113 /* ********************************************************************** */
114
115 /*
116 * return src of str in charset. charset is a string set. case is significant
117 */
118 uChar
str_in_set(str,s)119 str_in_set(str, s)
120 char *str, *s[];
121 {
122 register uChar i;
123 for (i = 0; *s[i] && strcmp(str, s[i]); i++);
124 return (i);
125 }
126
127 /* ********************************************************************** */
128
129 /* return next char which is non-whitespace char */
130 uChar
skip_space(str,i)131 skip_space(str, i)
132 char *str;
133 uShrt i;
134 {
135 register uChar idx;
136 idx = (uChar) i;
137 while (isspace(str[idx]))
138 idx++;
139 return (idx);
140 }
141
142 /* ********************************************************************** */
143
144 void
to_upper(str)145 to_upper(str)
146 char *str;
147 {
148 while ((*str = toupper_(*str)) != '\0')
149 str++;
150 }
151
152 /* ********************************************************************** */
153
154 /* Get token which depends on the first letter. token need to be allocated. */
155 int
get_token(str,curIndex,token)156 get_token(str, curIndex, token)
157 char *str, *token;
158 uChar *curIndex;
159 {
160 register uChar src, dst = 0;
161 register int ch; /* int for ctype compliance */
162 int tokenType;
163
164 src = skip_space(str, (uShrt) * curIndex);
165
166 if (str[src])
167 if (isdigit(ch = str[src])) { /* Grab the whole digit */
168 while (isdigit(str[src]))
169 token[dst++] = str[src++];
170 tokenType = NUMBTOKEN;
171 }
172 /* Grab the whole identifier. There would be special treatment to modifiers */
173 else if (is_alpha(ch)) {
174 for (; ((ch = str[src]) != '\0') && (is_alpha(ch) || isdigit(ch));)
175 token[dst++] = str[src++];
176 tokenType = CHARTOKEN;
177 }
178 /*
179 * The following would accept only one single char. The order should
180 * reflect the frequency of the symbols being used
181 */
182 else {
183 /* Is operator symbol ? */
184 if (is_expr(ch))
185 tokenType = EXPRTOKEN;
186 /* Is addressing mode symbol ? */
187 else if (is_addr(ch))
188 tokenType = ADDRTOKEN;
189 /* Is concatenation symbol ? */
190 /* currently force so that there is no double '&' */
191 else if (ch == cat_sym)
192 if (str[src + 1] == '&') {
193 token[dst++] = str[src++];
194 tokenType = EXPRTOKEN;
195 } else
196 tokenType = APNDTOKEN;
197 /* comment symbol ? */
198 else if (ch == com_sym)
199 tokenType = COMMTOKEN;
200 /* field separator symbol ? */
201 else if (ch == sep_sym)
202 tokenType = FSEPTOKEN;
203 /* modifier symbol ? */
204 else if (ch == mod_sym)
205 tokenType = MODFTOKEN;
206 else if ((ch == '|') && (str[src + 1] == '|')) {
207 token[dst++] = str[src++];
208 tokenType = EXPRTOKEN;
209 } else
210 tokenType = MISCTOKEN;
211
212 token[dst++] = str[src++];
213 }
214 else
215 tokenType = NONE;
216
217 token[dst] = '\0';
218 *curIndex = src;
219
220 return (tokenType);
221 }
222