@@ -236,6 +236,84 @@ private function hMacro_getArgW( byval argtb as LEXPP_ARGTB ptr, byval num as in
236236
237237end function
238238
239+ private function hMacro_Eval( byval arg as zstring ptr) as string
240+
241+ '' the expression should have already been handled in hLoadMacro|hLoadMacroW
242+ '' so, if we do get here, just pass the argument back as-is
243+ var res = ""
244+
245+ if ( arg ) then
246+
247+ '' create a lightweight context push for the lexer
248+ '' like an include file, but no include file
249+ '' text to expand is to be loaded in LEX.CTX->DEFTEXT[W]
250+ '' use the parser to build an AST for the literal result
251+
252+ lexPushCtx()
253+ lexInit( FALSE , TRUE )
254+
255+ '' prevent cExpression from writing to .pp.bas file
256+ lex.ctx->reclevel += 1
257+
258+ DZstrAssign( lex.ctx->deftext, *arg )
259+ lex.ctx->defptr = lex.ctx->deftext.data
260+ lex.ctx->deflen += len( *arg )
261+
262+ '' Add an end of expression marker so that the parser
263+ '' doesn't read past the end of the expression text
264+ '' by appending an LFCHAR to the end of the expression
265+ '' It would be better to use the explicit EOF character,
266+ '' but we can't appened an extta NULL character to a zstring
267+
268+ DZstrConcatAssign( lex.ctx->deftext, LFCHAR )
269+ lex.ctx->defptr = lex.ctx->deftext.data
270+ lex.ctx->deflen += len( LFCHAR )
271+
272+ dim expr as ASTNODE ptr = cExpression( )
273+ var errmsg = FB_ERRMSG_OK
274+
275+ if ( expr <> NULL ) then
276+ expr = astOptimizeTree( expr )
277+
278+ if ( astIsCONST( expr ) ) then
279+ res = astConstFlushToStr( expr )
280+
281+ '' any tokens still in the buffer? cExpression() should have used them all
282+ if ( lexGetToken( ) <> FB_TK_EOL ) then
283+ errmsg = FB_ERRMSG_SYNTAXERROR
284+ end if
285+ elseif ( astIsConstant( expr ) ) then
286+ res = """" + hReplace( expr->sym->var_.littext, QUOTE, QUOTE + QUOTE ) + """"
287+
288+ '' any tokens still in the buffer? cExpression() should have used them all
289+ if ( lexGetToken( ) <> FB_TK_EOL ) then
290+ errmsg = FB_ERRMSG_SYNTAXERROR
291+ end if
292+ else
293+ astDelTree( expr )
294+ errmsg = FB_ERRMSG_EXPECTEDCONST
295+ res = str( 0 )
296+ end if
297+ else
298+ errmsg = FB_ERRMSG_SYNTAXERROR
299+ end if
300+
301+ lex.ctx->reclevel -= 1
302+
303+ lexPopCtx()
304+
305+ if ( errmsg <> FB_ERRMSG_OK ) then
306+ errReportEx( errmsg, *arg )
307+ '' error recovery: skip until next line (in the buffer)
308+ hSkipUntil( FB_TK_EOL, TRUE )
309+ end if
310+
311+ end if
312+
313+ function = res
314+
315+ end function
316+
239317private function hDefUniqueIdPush_cb( byval argtb as LEXPP_ARGTB ptr, byval errnum as integer ptr ) as string
240318
241319 '' __FB_UNIQUEID_PUSH__( STACKID )
@@ -357,14 +435,17 @@ private function hDefArgExtract_cb( byval argtb as LEXPP_ARGTB ptr, byval errnum
357435 '' Val returns 0 on failure which we can't detect from a valid 0
358436 '' so check and construct the number manually
359437
360- dim numArgLen as Long = Len(*numStr), i as Long , index as ULong = 0
438+ dim as string varstr = hMacro_Eval(numStr)
439+ var pnumStr = strptr(varstr)
440+
441+ dim numArgLen as Long = Len(*pnumStr), i as Long , index as ULong = 0
361442 dim zeroVal As ULong = Asc( "0" )
362443 For i = 0 To numArgLen - 1
363- if ( Not hIsCharNumeric(numStr [i]) ) then
444+ if ( Not hIsCharNumeric(pnumStr [i]) ) then
364445 Exit For
365446 End If
366447 index *= 10
367- index += (numStr [i] - zeroVal)
448+ index += (pnumStr [i] - zeroVal)
368449 Next
369450 If i = numArgLen Then
370451 dim numVarArgs As ULong = argtb->count - 1
@@ -641,75 +722,7 @@ private function hDefEval_cb( byval argtb as LEXPP_ARGTB ptr, byval errnum as in
641722 '' so, if we do get here, just pass the argument back as-is
642723
643724 var arg = hMacro_getArgZ( argtb, 0 )
644- var res = ""
645-
646- if ( arg ) then
647-
648- '' create a lightweight context push for the lexer
649- '' like an include file, but no include file
650- '' text to expand is to be loaded in LEX.CTX->DEFTEXT[W]
651- '' use the parser to build an AST for the literal result
652-
653- lexPushCtx()
654- lexInit( FALSE , TRUE )
655-
656- '' prevent cExpression from writing to .pp.bas file
657- lex.ctx->reclevel += 1
658-
659- DZstrAssign( lex.ctx->deftext, *arg )
660- lex.ctx->defptr = lex.ctx->deftext.data
661- lex.ctx->deflen += len( *arg )
662-
663- '' Add an end of expression marker so that the parser
664- '' doesn't read past the end of the expression text
665- '' by appending an LFCHAR to the end of the expression
666- '' It would be better to use the explicit EOF character,
667- '' but we can't appened an extta NULL character to a zstring
668-
669- DZstrConcatAssign( lex.ctx->deftext, LFCHAR )
670- lex.ctx->defptr = lex.ctx->deftext.data
671- lex.ctx->deflen += len( LFCHAR )
672-
673- dim expr as ASTNODE ptr = cExpression( )
674- var errmsg = FB_ERRMSG_OK
675-
676- if ( expr <> NULL ) then
677- expr = astOptimizeTree( expr )
678-
679- if ( astIsCONST( expr ) ) then
680- res = astConstFlushToStr( expr )
681-
682- '' any tokens still in the buffer? cExpression() should have used them all
683- if ( lexGetToken( ) <> FB_TK_EOL ) then
684- errmsg = FB_ERRMSG_SYNTAXERROR
685- end if
686- elseif ( astIsConstant( expr ) ) then
687- res = """" + hReplace( expr->sym->var_.littext, QUOTE, QUOTE + QUOTE ) + """"
688-
689- '' any tokens still in the buffer? cExpression() should have used them all
690- if ( lexGetToken( ) <> FB_TK_EOL ) then
691- errmsg = FB_ERRMSG_SYNTAXERROR
692- end if
693- else
694- astDelTree( expr )
695- errmsg = FB_ERRMSG_EXPECTEDCONST
696- res = str( 0 )
697- end if
698- else
699- errmsg = FB_ERRMSG_SYNTAXERROR
700- end if
701-
702- lex.ctx->reclevel -= 1
703-
704- lexPopCtx()
705-
706- if ( errmsg <> FB_ERRMSG_OK ) then
707- errReportEx( errmsg, *arg )
708- '' error recovery: skip until next line (in the buffer)
709- hSkipUntil( FB_TK_EOL, TRUE )
710- end if
711-
712- end if
725+ var res = hMacro_Eval(arg)
713726
714727 ZstrFree(arg)
715728
0 commit comments