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