@@ -240,6 +240,7 @@ private function hMacro_EvalZ( byval arg as zstring ptr ) as string
240240
241241 '' the expression should have already been handled in hLoadMacro|hLoadMacroW
242242 '' so, if we do get here, just pass the argument back as-is
243+ '' !!!TODO!!! - DZSTRING can be replaced by STRING
243244 dim as DZSTRING res
244245 DZStrAssign( res, NULL )
245246
@@ -284,41 +285,12 @@ private function hMacro_EvalZ( byval arg as zstring ptr ) as string
284285 errmsg = FB_ERRMSG_SYNTAXERROR
285286 end if
286287 elseif ( astIsConstant( expr ) ) then
287- '' !!!TODO!!! refactor in to procedures
288- if ( symbGetType( expr->sym ) <> FB_DATATYPE_WCHAR ) then
289- dim textlen as integer
290- dim text as zstring ptr = hUnescape( symbGetVarLitText( expr->sym ), textlen )
291- if ( len(*text) <> textlen ) then
292- dim tmp as string
293- for i as integer = 1 to textlen
294- tmp &= $"\x" & hex( asc( *text, i ), 2 )
295- next
296- DZStrConcatAssign( res, "!" + QUOTE )
297- DZStrConcatAssign( res, strptr(tmp) )
298- DZStrConcatAssign( res, QUOTE )
299- else
300- DZStrConcatAssign( res, "$" + QUOTE )
301- DZStrConcatAssign( res, text )
302- DZStrConcatAssign( res, QUOTE )
303- end if
304- else
305- '' WSTRING to ASCII? always escape.
306- dim textlen as integer
307- dim text as wstring ptr = hUnescapeW( symbGetVarLitTextW( expr->sym ), textlen )
308- dim tmp as string
309- for i as integer = 0 to textlen - 1
310- tmp &= $"\u" & hex( cast( ulong, text[i] ), 4 )
311- next
312- '' Careful - wstring literal pasted into an ascii lexer stream
313- DZStrConcatAssign( res, "!" + QUOTE )
314- DZStrConcatAssign( res, strptr(tmp) )
315- DZStrConcatAssign( res, QUOTE )
316- end if
317-
288+ DZStrAssign( res, symbGetConstStrAsStr( expr->sym ) )
318289 '' any tokens still in the buffer? cExpression() should have used them all
319290 if ( lexGetToken( ) <> FB_TK_EOL ) then
320291 errmsg = FB_ERRMSG_SYNTAXERROR
321292 end if
293+ astDelTree( expr )
322294 else
323295 astDelTree( expr )
324296 errmsg = FB_ERRMSG_EXPECTEDCONST
@@ -344,6 +316,88 @@ private function hMacro_EvalZ( byval arg as zstring ptr ) as string
344316
345317end function
346318
319+ private function hMacro_EvalW( byval arg as wstring ptr ) as wstring ptr
320+
321+ '' the expression should have already been handled in hLoadMacro|hLoadMacroW
322+ '' so, if we do get here, just pass the argument back as-is
323+ '' !!!TODO!!! - We must use DWSTRING since we don't have a built-in var-len wstring
324+ '' but, if we did have a var-len wstring, we should use it instead
325+
326+ static as DWSTRING res
327+ DWStrAssign( res, NULL )
328+
329+ if ( arg ) then
330+
331+ '' create a lightweight context push for the lexer
332+ '' like an include file, but no named include file
333+ '' - text to expand is to be loaded in LEX.CTX->DEFTEXT[W]
334+ '' - use the parser to build an AST for the literal result
335+
336+ lexPushCtx()
337+ lexInit( FALSE , TRUE )
338+
339+ '' prevent cExpression from writing to .pp.bas file
340+ lex.ctx->reclevel += 1
341+
342+ DWstrAssign( lex.ctx->deftextw, *arg )
343+ lex.ctx->defptrw = lex.ctx->deftextw.data
344+ lex.ctx->deflen += len( *arg )
345+
346+ '' Add an end of expression marker so that the parser
347+ '' doesn't read past the end of the expression text
348+ '' by appending an LFCHAR to the end of the expression
349+ '' It would be better to use the explicit EOF character,
350+ '' but we can't appened an extra NUL character to a zstring
351+
352+ DWstrConcatAssign( lex.ctx->deftextw, LFCHAR )
353+ lex.ctx->defptrw = lex.ctx->deftextw.data
354+ lex.ctx->deflen += len( LFCHAR )
355+
356+ dim expr as ASTNODE ptr = cExpression( )
357+ var errmsg = FB_ERRMSG_OK
358+
359+ if ( expr <> NULL ) then
360+ expr = astOptimizeTree( expr )
361+
362+ if ( astIsCONST( expr ) ) then
363+ DWStrAssign( res, astConstFlushToWstr( expr ) )
364+
365+ '' any tokens still in the buffer? cExpression() should have used them all
366+ if ( lexGetToken( ) <> FB_TK_EOL ) then
367+ errmsg = FB_ERRMSG_SYNTAXERROR
368+ end if
369+ elseif ( astIsConstant( expr ) ) then
370+ DWStrAssign( res, symbGetConstStrAsWstr( expr->sym ) )
371+ '' any tokens still in the buffer? cExpression() should have used them all
372+ if ( lexGetToken( ) <> FB_TK_EOL ) then
373+ errmsg = FB_ERRMSG_SYNTAXERROR
374+ end if
375+ astDelTree( expr )
376+ else
377+ astDelTree( expr )
378+ errmsg = FB_ERRMSG_EXPECTEDCONST
379+ DWStrAssign( res, ! "\u0000" )
380+ end if
381+ else
382+ errmsg = FB_ERRMSG_SYNTAXERROR
383+ end if
384+
385+ lex.ctx->reclevel -= 1
386+
387+ lexPopCtx()
388+
389+ if ( errmsg <> FB_ERRMSG_OK ) then
390+ errReportEx( errmsg, *arg )
391+ '' error recovery: skip until next line (in the buffer)
392+ hSkipUntil( FB_TK_EOL, TRUE )
393+ end if
394+
395+ end if
396+
397+ function = res.data
398+
399+ end function
400+
347401private function hDefUniqueIdPush_cb( byval argtb as LEXPP_ARGTB ptr, byval errnum as integer ptr ) as string
348402
349403 '' __FB_UNIQUEID_PUSH__( STACKID )
@@ -768,6 +822,21 @@ private function hDefEvalZ_cb( byval argtb as LEXPP_ARGTB ptr, byval errnum as i
768822
769823end function
770824
825+ private function hDefEvalW_cb( byval argtb as LEXPP_ARGTB ptr, byval errnum as integer ptr ) as wstring ptr
826+
827+ '' __FB_EVAL__( arg )
828+
829+ '' the expression should have already been handled in hLoadMacro|hLoadMacroW
830+ '' so, if we do get here, just pass the argument back as-is
831+
832+ var arg = hMacro_getArgW( argtb, 0 )
833+ static as DWSTRING res
834+ DWstrAssign( res, hMacro_EvalW( arg ) )
835+
836+ function = res.data
837+
838+ end function
839+
771840
772841'' Intrinsic #defines which are always defined
773842dim shared defTb( 0 to ...) as SYMBDEF => _
@@ -833,7 +902,7 @@ dim shared macroTb(0 to ...) as SYMBMACRO => _
833902 ( @"__FB_JOIN__" , 0 , @hDefJoinZ_cb , @hDefJoinW_cb , 2 , { ( @"L" ), ( @"R" ) } ), _
834903 ( @"__FB_QUOTE__" , 0 , @hDefQuoteZ_cb , @hDefQuoteW_cb , 1 , { ( @"ARG" ) } ), _
835904 ( @"__FB_UNQUOTE__" , 0 , @hDefUnquoteZ_cb , @hDefUnquoteW_cb , 1 , { ( @"ARG" ) } ), _
836- ( @"__FB_EVAL__" , 0 , @hDefEvalZ_cb , NULL , 1 , { ( @"ARG" ) } ) _
905+ ( @"__FB_EVAL__" , 0 , @hDefEvalZ_cb , @ hDefEvalW_cb , 1 , { ( @"ARG" ) } ) _
837906}
838907
839908sub symbDefineInit _
0 commit comments