4 * Revision 1.1 2001/04/04 05:43:39 wang
5 * First commit: compiles on Linux, Amiga, Windows, Windows CE, generic gcc
7 * Revision 1.2 1999/11/26 13:13:47 bnv
8 * Changed: Some spaces to tabs.
10 * Revision 1.1 1998/07/02 17:34:50 bnv
15 #define __NEXTSYMB_C__
23 static PLstr ProgStr
; /* pointer that holds the program string*/
24 static int InitNextch
; /* NextChar initialised? */
25 static bool NextBlank
; /* Next char is blank */
26 static bool commentfound
; /* if comment found in nextchar */
28 bool _in_nextsymbol
; /* Used only to track error inside nextsymb*/
30 /* ------------------- function prototypes ----------------------- */
31 static void literal(void);
32 static void identifier(int isnumber
);
34 /* --------------------------------------------------------------- */
35 /* return the next character and advance the input stream by one */
36 /* also it searches for comments */
37 /* --------------------------------------------------------------- */
39 nextchar(int instring
)
47 if (*symbolptr
=='\n') symboline
++;
52 if (!instring
&& *symbolptr
=='/' && *(symbolptr
+1)=='*') {
53 /* search for comment */
58 while ((*symbolptr
!='*') && (*symbolptr
!='/')) {
59 if (*symbolptr
=='\n') symboline
++;
62 Lerror(ERR_UNMATCHED_QUOTE
,1);
65 if ((*(symbolptr
-1)=='/') && (*symbolptr
=='*')) {
69 if ((*(symbolptr
-1)=='*') && (*symbolptr
=='/')) {
71 if (!level
) goto getnextchar
;
78 /* --------------- InitNextsymbol -------------------- */
80 InitNextsymbol( PLstr str
)
82 Lcat(str
,"\n"); /* We must have a least one new line at the end */
85 LASCIIZ(*ProgStr
); /* Put a zero at the end */
86 symbol
= semicolon_sy
;
87 symbolptr
= LSTR(*ProgStr
);
90 /* Skip first line, '#!/bin/rexx' */
91 if (symbolptr
[0]=='#' && symbolptr
[1]=='!') {
92 while (*symbolptr
!='\n') symbolptr
++;
98 symbolstat
= normal_st
;
99 } /* InitNextsymbol */
101 /* --------------------------------------------------------------- */
102 /* P A R S E next B A S I C S Y M B O L */
103 /* Return the next basic symbol and advance the input stream */
104 /* --------------------------------------------------------------- */
108 #define NEXTCHAR {*(ns++)=*symbolptr; LLEN(symbolstr)++; nextchar(FALSE);}
110 char *Psymbolptr
, *ns
;
114 /* call nextchar to search for comments */
115 nextchar(-1); /* initialise */
116 commentfound
= FALSE
;
119 /* make the type always to be LSTRING */
120 LTYPE(symbolstr
) = LSTRING_TY
;
123 _in_nextsymbol
= TRUE
;
124 symbolPrevBlank
= NextBlank
;
128 while (*symbolptr
==' ' || *symbolptr
=='\t')
131 ns
= LSTR(symbolstr
);
133 symbolprevptr
= symbolptr
;
135 switch (l2u
[(byte
)*symbolptr
]) {
136 case '0': case '1': case '2':
137 case '3': case '4': case '5':
138 case '6': case '7': case '8':
144 case 'A': case 'B': case 'C':
145 case 'D': case 'E': case 'F':
146 case 'G': case 'H': case 'I':
147 case 'J': case 'K': case 'L':
148 case 'M': case 'N': case 'O':
149 case 'P': case 'Q': case 'R':
150 case 'S': case 'T': case 'U':
151 case 'V': case 'W': case 'X':
166 if (*symbolptr
=='/') {
170 if (*symbolptr
=='=') {
172 if (*symbolptr
=='=') {
189 Lerror(ERR_INVALID_EXPRESSION
,0);
190 if (*symbolptr
=='*') {
201 switch (*symbolptr
) {
204 if (*symbolptr
=='=') {
213 if (*symbolptr
=='>') {
222 if (*symbolptr
=='<') {
250 /* Only for UNIX where \r is not recognised as \n */
256 symbol
= semicolon_sy
;
262 Psymbolptr
= symbolptr
;
266 symbolPrevBlank
= TRUE
;
267 if (symbol
==semicolon_sy
&&
268 _lineno
!=symboline
) goto _NEXTSYMBOL
;
269 symbolptr
= Psymbolptr
;
272 symbolPrevBlank
= TRUE
;
276 Psymbolptr
= symbolptr
+1;
277 if ( *Psymbolptr
!=' ' &&
279 *Psymbolptr
!='\n' &&
280 *Psymbolptr
!='\r' &&
281 *Psymbolptr
!='\t' &&
282 *Psymbolptr
!=';' ) {
293 if (*symbolptr
=='|') {
302 if (*symbolptr
=='&') {
316 switch (*symbolptr
) {
324 if (*symbolptr
=='>') {
333 if (*symbolptr
=='<') {
347 switch (*symbolptr
) {
350 if (*symbolptr
=='=') {
374 switch (*symbolptr
) {
377 if (*symbolptr
=='=') {
405 Lerror(ERR_SYMBOL_EXPECTED
,0);
409 _in_nextsymbol
= FALSE
;
410 if ((symbolstat
== in_do_st
) ||
411 (symbolstat
== in_if_st
))
412 Lerror(ERR_INCOMPLETE_STRUCT
,0);
414 if (symbolstat
== in_if_init_st
)
415 Lerror(ERR_THEN_EXPECTED
,0);
417 if (symbolstat
!= normal_st
)
418 Lerror(ERR_SYMBOL_EXPECTED
,0);
423 Lerror(ERR_INVALID_CHAR
,0);
425 if ( *symbolptr
== ' ' ||
429 _in_nextsymbol
= FALSE
;
432 /* --------------------------------------------------------------- */
433 /* find the identifier */
434 /* --------------------------------------------------------------- */
436 identifier(int isnumber
)
439 int l
; /* length */ /* -+- l > maxlen ? */
440 int hasDot
=FALSE
, hasExp
=FALSE
;
448 if (l
>LMAXLEN(symbolstr
))
449 Lerror(ERR_TOO_LONG_STRING
,0);
452 *symbolptr
!='(' && *symbolptr
!=':') {
453 commentfound
= FALSE
;
459 switch (l2u
[(byte
)*symbolptr
]) {
460 case '0': case '1': case '2':
461 case '3': case '4': case '5':
462 case '6': case '7': case '8':
469 case 'A': case 'B': case 'C':
470 case 'D': case 'E': case 'F':
471 case 'G': case 'H': case 'I':
472 case 'J': case 'K': case 'L':
473 case 'M': case 'N': case 'O':
474 case 'P': case 'Q': case 'R':
475 case 'S': case 'T': case 'U':
476 case 'V': case 'W': case 'X':
485 *s
= l2u
[(byte
)*symbolptr
];
502 *s
++ = *symbolptr
; l
++;
517 *s
++ = *symbolptr
; l
++;
518 if (!symbolhasdot
) /* position of first */
519 symbolhasdot
= l
; /* dot */
533 symbol
= function_sy
;
548 while (*symbolptr
==' '||*symbolptr
=='\t')
551 /* literal finished and it is not a label? */
555 /* literal is label */
564 } /* end of switch */
567 if (symbol
!=ident_sy
) return ;
569 if (symbolhasdot
== LLEN(symbolstr
))
570 symbolhasdot
= 0; /* treat is as a variable */
572 if (symbolstat
== in_do_init_st
) {
573 if (!Lcmp(&symbolstr
,"BY" )) symbol
= by_sy
;
574 else if (!Lcmp(&symbolstr
,"FOR" )) symbol
= for_sy
;
575 else if (!Lcmp(&symbolstr
,"TO" )) symbol
= to_sy
;
576 else if (!Lcmp(&symbolstr
,"UNTIL")) symbol
= until_sy
;
577 else if (!Lcmp(&symbolstr
,"WHILE")) symbol
= while_sy
;
579 if (symbolstat
== in_parse_value_st
) {
580 if (!Lcmp(&symbolstr
,"WITH" )) symbol
= with_sy
;
582 if (symbolstat
== in_if_init_st
) {
583 if (!Lcmp(&symbolstr
,"THEN" )) symbol
= then_sy
;
587 /* --------------------------------------------------------------- */
588 /* extract a literal symbol */
589 /* --------------------------------------------------------------- */
595 int l
; /* length of symbolstr */
605 for (;;) { /* -+- l > maxlen ? */
607 if (l
>=LMAXLEN(symbolstr
))
608 Lerror(ERR_TOO_LONG_STRING
,0);
609 if (*symbolptr
==quote
) {
610 nextchar(FALSE
); /* quote ended?? */
611 if (*symbolptr
== '(') {
614 symbol
= function_sy
;
618 if (commentfound
) { /* a comment was inside */
619 commentfound
= FALSE
;
624 if (STRCHR("bBxXhH",*symbolptr
)) {
625 /* check next char */
626 char nc
=l2u
[(byte
)*(symbolptr
+1)];
631 if (IN_RANGE('0',nc
,'9') ||
632 IN_RANGE('A',nc
,'Z') ||
633 nc
=='@' || nc
=='#' || nc
=='$' ||
634 nc
=='_' || nc
=='?' || nc
=='!' ||
640 switch (l2u
[(byte
)*symbolptr
]) {
642 if (!Ldatatype(&symbolstr
,'B'))
643 Lerror(ERR_INVALID_HEX_CONST
,0);
648 if (!Ldatatype(&symbolstr
,'X'))
649 Lerror(ERR_INVALID_HEX_CONST
,0);
650 Lx2d(&A
,&symbolstr
,0);
651 Lstrcpy(&symbolstr
,&A
);
654 if (!Ldatatype(&symbolstr
,'X'))
655 Lerror(ERR_INVALID_HEX_CONST
,0);
657 Lstrcpy(&symbolstr
,&A
);
664 if (*symbolptr
==quote
) {
665 *s
++ = *symbolptr
; l
++;
672 if (*symbolptr
== '\n') {
676 Lerror(ERR_UNMATCHED_QUOTE
,