Skip to content

Commit 4e04d14

Browse files
committed
Adjust the source code of the macro "__FB_ARG_EXTRACT__( index, args... )",
Make its first parameter (index) support constant expression at compile time.
1 parent 77d9a04 commit 4e04d14

File tree

1 file changed

+85
-72
lines changed

1 file changed

+85
-72
lines changed

src/compiler/symb-define.bas

Lines changed: 85 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -236,6 +236,84 @@ private function hMacro_getArgW( byval argtb as LEXPP_ARGTB ptr, byval num as in
236236

237237
end 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+
239317
private 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

Comments
 (0)