Skip to content

Commit 8970ad2

Browse files
committed
Implement recording of tokens read by lex()
1 parent 46149d1 commit 8970ad2

File tree

4 files changed

+119
-0
lines changed

4 files changed

+119
-0
lines changed

source/compiler/sc.h

+4
Original file line numberDiff line numberDiff line change
@@ -724,6 +724,8 @@ SC_FUNC void lexinit(void);
724724
SC_FUNC int lex(cell *lexvalue,char **lexsym);
725725
SC_FUNC void lexpush(void);
726726
SC_FUNC void lexclr(int clreol);
727+
SC_FUNC void recstart(void);
728+
SC_FUNC void recstop(void);
727729
SC_FUNC int matchtoken(int token);
728730
SC_FUNC int tokeninfo(cell *val,char **str);
729731
SC_FUNC int needtoken(int token);
@@ -1013,6 +1015,8 @@ SC_VDECL int pc_retheap; /* heap space (in bytes) to be manually freed when
10131015
SC_VDECL int pc_nestlevel; /* number of active (open) compound statements */
10141016
SC_VDECL unsigned int pc_attributes;/* currently set attribute flags (for the "__pragma" operator) */
10151017
SC_VDECL int pc_ispackedstr; /* true if the last tokenized string is packed */
1018+
SC_VDECL int pc_isrecording; /* true if recording input */
1019+
SC_VDECL char *pc_recstr; /* recorded input */
10161020

10171021
SC_VDECL char *sc_tokens[];
10181022

source/compiler/sc1.c

+2
Original file line numberDiff line numberDiff line change
@@ -791,6 +791,8 @@ int pc_compile(int argc, char *argv[])
791791
line_sym=NULL;
792792
free(pc_deprecate);
793793
pc_deprecate=NULL;
794+
free(pc_recstr);
795+
pc_recstr=NULL;
794796
hashtable_term(&symbol_cache_ht);
795797
delete_consttable(&tagname_tab);
796798
delete_consttable(&libname_tab);

source/compiler/sc2.c

+111
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,8 @@ static void substallpatterns(unsigned char *line,int buffersize);
5656
static int match(char *st,int end);
5757
static int alpha(char c);
5858

59+
static void rectok(char *tokptr,int whitespace);
60+
5961
#define SKIPMODE 1 /* bit field in "#if" stack */
6062
#define PARSEMODE 2 /* bit field in "#if" stack */
6163
#define HANDLED_ELSE 4 /* bit field in "#if" stack */
@@ -68,6 +70,7 @@ static short iflevel; /* nesting level if #if/#else/#endif */
6870
static short skiplevel; /* level at which we started skipping (including nested #if .. #endif) */
6971
static unsigned char term_expr[] = "";
7072
static int listline=-1; /* "current line" for the list file */
73+
static short iskipwspace=FALSE; /* skipped whitespace(s) before the last read token? */
7174

7275

7376
/* pushstk & popstk
@@ -2310,11 +2313,13 @@ SC_FUNC int lex(cell *lexvalue,char **lexsym)
23102313
*lexvalue=_lexval;
23112314
*lexsym=_lexstr;
23122315
_lexnewline=FALSE;
2316+
iskipwspace=FALSE;
23132317
if (!freading)
23142318
return 0;
23152319

23162320
newline= (lptr==pline); /* does lptr point to start of line buffer */
23172321
while (*lptr<=' ') { /* delete leading white space */
2322+
iskipwspace=TRUE;
23182323
if (*lptr=='\0') {
23192324
preprocess(); /* preprocess resets "lptr" */
23202325
if (!freading)
@@ -2344,6 +2349,8 @@ SC_FUNC int lex(cell *lexvalue,char **lexsym)
23442349
_lextok=i;
23452350
if (pc_docexpr) /* optionally concatenate to documentation string */
23462351
insert_autolist(*tokptr);
2352+
if (pc_isrecording)
2353+
rectok(*tokptr,iskipwspace);
23472354
return _lextok;
23482355
} /* if */
23492356
i+=1;
@@ -2355,6 +2362,8 @@ SC_FUNC int lex(cell *lexvalue,char **lexsym)
23552362
errorset(sRESET,0); /* reset error flag (clear the "panic mode")*/
23562363
if (pc_docexpr) /* optionally concatenate to documentation string */
23572364
insert_autolist(*tokptr);
2365+
if (pc_isrecording)
2366+
rectok(*tokptr,iskipwspace);
23582367
return _lextok;
23592368
} /* if */
23602369
i+=1;
@@ -2472,6 +2481,28 @@ SC_FUNC int lex(cell *lexvalue,char **lexsym)
24722481
free(docstr);
24732482
} /* if */
24742483
} /* if */
2484+
if (pc_isrecording) {
2485+
switch (_lextok) {
2486+
case tNUMBER:
2487+
case tRATIONAL:
2488+
_lexstr[0]='\0',strncat(_lexstr,(char *)starttoken,lptr-starttoken);
2489+
/* fallthrough */
2490+
case tSYMBOL:
2491+
case tLABEL:
2492+
rectok(_lexstr,iskipwspace);
2493+
if (_lextok==tLABEL)
2494+
rectok(":",FALSE);
2495+
break;
2496+
default:
2497+
if (_lextok<tFIRST) {
2498+
char tmp[2];
2499+
sprintf(tmp,"%c",_lextok);
2500+
rectok(tmp,iskipwspace);
2501+
} else {
2502+
rectok(sc_tokens[tSTRING-tFIRST],iskipwspace);
2503+
} /* if */
2504+
} /* if */
2505+
} /* if */
24752506
return _lextok;
24762507
}
24772508

@@ -2508,6 +2539,86 @@ SC_FUNC void lexclr(int clreol)
25082539
} /* if */
25092540
}
25102541

2542+
static void rectok(char *tokptr,int whitespace)
2543+
{
2544+
int toklen=strlen(tokptr);
2545+
2546+
if (pc_recstr==NULL) {
2547+
pc_recstr=(char *)malloc((toklen+1)*sizeof(char));
2548+
if (pc_recstr==NULL)
2549+
error(103); /* insufficient memory */
2550+
memcpy(pc_recstr,tokptr,toklen*sizeof(char));
2551+
pc_recstr[toklen]='\0';
2552+
} else {
2553+
int oldlen=strlen(pc_recstr);
2554+
char *newresctr=realloc(pc_recstr,(oldlen+(whitespace ? 1 : 0)+toklen+1)*sizeof(char));
2555+
if (newresctr==NULL)
2556+
error(103); /* insufficient memory */
2557+
pc_recstr=newresctr;
2558+
if (whitespace)
2559+
pc_recstr[oldlen]=' ';
2560+
memcpy(pc_recstr+(whitespace ? 1 : 0)+oldlen,tokptr,(toklen+1)*sizeof(char));
2561+
} /* if */
2562+
}
2563+
2564+
/* recstart
2565+
*
2566+
* (Re-)starts recording all tokens that lex() reads.
2567+
*/
2568+
SC_FUNC void recstart(void)
2569+
{
2570+
pc_isrecording=TRUE;
2571+
if (_pushed) {
2572+
/* record the pushed token */
2573+
char tmp[2];
2574+
char *tokstr;
2575+
if (_lextok<tFIRST) {
2576+
sprintf(tmp,"%c",_lextok);
2577+
tokstr=tmp;
2578+
} else {
2579+
tokstr=sc_tokens[_lextok-tFIRST];
2580+
} /* if */
2581+
rectok(tokstr,iskipwspace);
2582+
} /* if */
2583+
}
2584+
2585+
/* recstop
2586+
*
2587+
* Stops recording tokens.
2588+
*/
2589+
SC_FUNC void recstop(void)
2590+
{
2591+
if (sc_status!=statWRITE)
2592+
return;
2593+
2594+
assert(pc_recstr!=NULL);
2595+
pc_isrecording=FALSE;
2596+
2597+
/* if nothing was recorded, then we have a quick exit */
2598+
if (strempty(pc_recstr))
2599+
return;
2600+
2601+
/* if the last token was pushed, remove it from the recorded string */
2602+
if (_pushed && pc_recstr[0]!='\0') {
2603+
char tmp[2];
2604+
char *tokstr;
2605+
int pos;
2606+
if (_lextok<tFIRST) {
2607+
sprintf(tmp,"%c",_lextok);
2608+
tokstr=tmp;
2609+
} else {
2610+
tokstr=sc_tokens[_lextok-tFIRST];
2611+
} /* if */
2612+
pos=strlen(pc_recstr)-strlen(tokstr);
2613+
if (strcmp(&pc_recstr[pos],tokstr)==0) {
2614+
/* remove trailing whitespaces */
2615+
while (pc_recstr[--pos]<=' ')
2616+
; /* nothing */
2617+
pc_recstr[pos+1]='\0';
2618+
} /* if */
2619+
} /* if */
2620+
}
2621+
25112622
/* matchtoken
25122623
*
25132624
* This routine is useful if only a simple check is needed. If the token

source/compiler/scvars.c

+2
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,8 @@ SC_VDEFINE int pc_retheap=0; /* heap space (in bytes) to be manua
103103
SC_VDEFINE int pc_nestlevel=0; /* number of active (open) compound statements */
104104
SC_VDEFINE unsigned int pc_attributes=0; /* currently set attribute flags (for the "__pragma" operator) */
105105
SC_VDEFINE int pc_ispackedstr=FALSE; /* true if the last tokenized string is packed */
106+
SC_VDEFINE int pc_isrecording=FALSE; /* true if recording input */
107+
SC_VDEFINE char *pc_recstr=NULL; /* recorded input */
106108

107109
SC_VDEFINE char *sc_tokens[] = {
108110
"*=", "/=", "%=", "+=", "-=", "<<=", ">>>=", ">>=", "&=", "^=", "|=",

0 commit comments

Comments
 (0)