Skip to content

Commit 5dcb9e2

Browse files
authored
Merge pull request #150 from jayrm/udt-wstring
user defined types can extend zstring or wstring
2 parents 7e3c023 + ff66fc1 commit 5dcb9e2

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

66 files changed

+5503
-52
lines changed

changelog.txt

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,28 @@
11
Version 1.07.0
22

33
[changed]
4+
- SADD/STRPTR(wstring) returns WSTRING PTR
45

56
[added]
67
- CVA_LIST type, CVA_START(), CVA_COPY() CVA_END(), CVA_ARG() macros will map to gcc's __builtin_va_list and __builtin_va_* macros in gcc backend
78
- github #133: fbc makefile supports bootstrap-minimal target to build a bootstrap fbc with only the minimal features necessary to build another fbc. (William Breathitt Gray)
89
- github #141: introduced '-strip'/'-nostrip' options to control symbol stripping of output files (William Breathitt Gray)
910
- github #141: fbc will default to stripping symbols if '-d ENABLE_STRIPALL' is passed in FBCFLAGS (William Breathitt Gray)
1011
- github #141: makefile option 'ENABLE_STRIPALL=1' introduced to pass '-d ENABLE_STRIPALL' via FBCFLAGS by default for dos/win32 targets (William Breathitt Gray)
12+
- 'TYPE udt EXTENDS Z|WSTRING' allowed to specify that UDT is a kind of Z|WSTRING
13+
- LTRIM/RTRIM/TRIM will accept UDT as Z|WSTRING
14+
- LCASE/UCASE will accept UDT as Z|WSTRING
15+
- Cxxx() conversion functions will accept UDT as Z|WSTRING
16+
- INSTR/INSTRREV will accept UDT as Z|WSTRING
17+
- MID function will accept UDT as Z|WSTRING
18+
- SADD/STRPTR will accept UDT as Z|WSTRING to return Z|WSTRING ptr
19+
- LSET/RSET statements will accept UDT as Z|WSTRING
20+
- MID statement will accept UDT as Z|WSTRING
21+
- ASC function will accept UDT as Z|WSTRING
22+
- STR/WSTR function will accept UDT as Z|WSTRING to return a Z|WSTRING
23+
- SELECT statement will accept UDT as Z|WSTRING to return a Z|WSTRING
24+
- SWAP statement will accept UDT as Z|WSTRING
25+
- IIF function will accept UDT as Z|WSTRING
1126

1227
[fixed]
1328
- sf.net #881: C backend: support for varadic function parameters in gcc using __builtin_va_list type and related macros

src/compiler/ast-node-conv.bas

Lines changed: 76 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -285,7 +285,7 @@ end function
285285
proc = symbFindCastOvlProc( to_dtype, to_subtype, node, @err_num )
286286
if( proc <> NULL ) then
287287
'' build a proc call
288-
return astBuildCall( proc, l )
288+
return astBuildCall( proc, node )
289289
else
290290
if( err_num <> FB_ERRMSG_OK ) then
291291
return NULL
@@ -294,6 +294,43 @@ end function
294294
end scope
295295
#endmacro
296296

297+
'':::::
298+
function astTryOvlStringCONV( byref expr as ASTNODE ptr ) as integer
299+
300+
dim as FBSYMBOL ptr proc = any, sym = any
301+
dim as FB_ERRMSG err_num = any
302+
dim as integer dtype = any
303+
304+
assert( expr )
305+
306+
if( astGetDataType( expr ) = FB_DATATYPE_STRUCT ) then
307+
sym = astGetSubType( expr )
308+
309+
if( symbGetUdtIsZstring( sym ) ) then
310+
dtype = FB_DATATYPE_CHAR
311+
elseif( symbGetUdtIsWstring( sym ) ) then
312+
dtype = FB_DATATYPE_WCHAR
313+
else
314+
dtype = FB_DATATYPE_VOID
315+
end if
316+
317+
if( dtype <> FB_DATATYPE_VOID ) then
318+
'' can cast to z|wstring?
319+
proc = symbFindCastOvlProc( dtype, NULL, expr, @err_num )
320+
if( proc ) then
321+
'' same type?
322+
if( symbGetType( proc ) = dtype ) then
323+
expr = astBuildCall( proc, expr )
324+
return TRUE
325+
end if
326+
end if
327+
end if
328+
end if
329+
330+
return FALSE
331+
332+
end function
333+
297334
'':::::
298335
function astNewCONV _
299336
( _
@@ -349,6 +386,44 @@ function astNewCONV _
349386
end if
350387
end if
351388

389+
'' UDT? check if it is z|wstring?
390+
'' !!! TODO !!! make this block in to a function
391+
'' re-use in astNewOvlCONV()
392+
'' rewrite hDoGlobOpOverload() as astTry* function
393+
if( typeGet( ldtype ) = FB_DATATYPE_STRUCT ) then
394+
dim as FBSYMBOL ptr subtype = astGetSubtype( l )
395+
396+
if( symbGetUdtIsZstring( subtype ) or symbGetUdtIsWstring( subtype ) ) then
397+
dim as FBSYMBOL ptr proc = NULL
398+
dim as FB_ERRMSG err_num = any
399+
400+
'' check exact casts
401+
proc = symbFindCastOvlProc( to_dtype, to_subtype, l, @err_num, TRUE )
402+
if( proc <> NULL ) then
403+
'' build a proc call
404+
return astBuildCall( proc, l )
405+
end if
406+
407+
'' check exact string pointer casts
408+
if( symbGetUdtIsZstring( subtype ) ) then
409+
proc = symbFindCastOvlProc( typeAddrof( FB_DATATYPE_CHAR ), NULL, l, @err_num, TRUE )
410+
elseif( symbGetUdtIsWstring( subtype ) ) then
411+
proc = symbFindCastOvlProc( typeAddrof( FB_DATATYPE_WCHAR ), NULL, l, @err_num, TRUE )
412+
end if
413+
if( proc <> NULL ) then
414+
'' build a proc call
415+
return astBuildCall( proc, l )
416+
end if
417+
418+
'' strings? convert.
419+
if( options and AST_CONVOPT_CHECKSTR ) then
420+
if( astTryOvlStringCONV( l ) ) then
421+
ldtype = astGetFullType( l )
422+
end if
423+
end if
424+
end if
425+
end if
426+
352427
'' try casting op overloading
353428
hDoGlobOpOverload( to_dtype, to_subtype, l )
354429

src/compiler/ast-node-iif.bas

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -199,6 +199,35 @@ function astNewIIF _
199199
dtype = FB_DATATYPE_INVALID
200200
subtype = NULL
201201

202+
'' Maybe UDT extends Z|WSTRING? Check for string conversions...
203+
if( truexpr->dtype <> falsexpr->dtype ) then
204+
if( truexpr->dtype = FB_DATATYPE_STRUCT ) then
205+
if( symbGetUdtIsZstring( truexpr->subtype ) ) then
206+
if( falsexpr->dtype = FB_DATATYPE_CHAR ) then
207+
astTryOvlStringCONV( truexpr )
208+
truexpr->dtype = astGetDataType( truexpr )
209+
end if
210+
elseif( symbGetUdtIsWstring( truexpr->subtype ) ) then
211+
if( falsexpr->dtype = FB_DATATYPE_WCHAR ) then
212+
astTryOvlStringCONV( truexpr )
213+
truexpr->dtype = astGetDataType( truexpr )
214+
end if
215+
end if
216+
elseif( falsexpr->dtype = FB_DATATYPE_STRUCT ) then
217+
if( symbGetUdtIsZstring( falsexpr->subtype ) ) then
218+
if( truexpr->dtype = FB_DATATYPE_CHAR ) then
219+
astTryOvlStringCONV( falsexpr )
220+
falsexpr->dtype = astGetDataType( falsexpr )
221+
end if
222+
elseif( symbGetUdtIsWstring( falsexpr->subtype ) ) then
223+
if( truexpr->dtype = FB_DATATYPE_WCHAR ) then
224+
astTryOvlStringCONV( falsexpr )
225+
falsexpr->dtype = astGetDataType( falsexpr )
226+
end if
227+
end if
228+
end if
229+
end if
230+
202231
'' check types & find the iif() result type
203232
if( hCheckTypes( truexpr->dtype, truexpr->subtype, _
204233
falsexpr->dtype, falsexpr->subtype, _

src/compiler/ast.bi

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,8 @@ enum AST_CONVOPT
536536
AST_CONVOPT_DONTWARNFUNCPTR = &h20
537537
end enum
538538

539+
declare function astTryOvlStringCONV( byref expr as ASTNODE ptr ) as integer
540+
539541
declare function astNewCONV _
540542
( _
541543
byval to_dtype as integer, _

src/compiler/parser-compound-select.bas

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -92,6 +92,8 @@ sub cSelectStmtBegin( )
9292
expr = astNewCONSTi( 0 )
9393
end if
9494

95+
astTryOvlStringCONV( expr )
96+
9597
'' can't be an UDT
9698
if( astGetDataType( expr ) = FB_DATATYPE_STRUCT ) then
9799
errReport( FB_ERRMSG_INVALIDDATATYPES )

src/compiler/parser-decl-struct.bas

Lines changed: 73 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -626,7 +626,9 @@ private function hTypeAdd _
626626
byval id_alias as zstring ptr, _
627627
byval isunion as integer, _
628628
byval align as integer, _
629-
byval baseSubtype as FBSYMBOL ptr = NULL _
629+
byval baseDType as integer = 0, _
630+
byval baseSubtype as FBSYMBOL ptr = NULL, _
631+
byval baseStringType as integer = 0 _
630632
) as FBSYMBOL ptr
631633

632634
dim as FBSYMBOL ptr s = any
@@ -638,6 +640,13 @@ private function hTypeAdd _
638640
s = symbStructBegin( NULL, NULL, parent, symbUniqueLabel( ), NULL, isunion, align, (baseSubtype <> NULL), 0, 0 )
639641
end if
640642

643+
select case baseStringType
644+
case FB_DATATYPE_CHAR
645+
symbSetUdtIsZstring( s )
646+
case FB_DATATYPE_WCHAR
647+
symbSetUdtIsWstring( s )
648+
end select
649+
641650
if( baseSubtype ) then
642651
symbStructAddBase( s, baseSubtype )
643652
end if
@@ -998,18 +1007,75 @@ sub cTypeDecl( byval attrib as integer )
9981007

9991008
'' (EXTENDS SymbolType)?
10001009
dim as FBSYMBOL ptr baseSubtype = NULL
1010+
dim as integer baseDType = 0
1011+
dim as integer stringType = 0
1012+
10011013
if( lexGetToken( ) = FB_TK_EXTENDS ) then
10021014
lexSkipToken( )
10031015

10041016
'' SymbolType
1005-
dim as integer baseDtype
1006-
hSymbolType( baseDtype, baseSubtype, 0 )
1017+
hSymbolType( baseDType, baseSubtype, 0, FALSE, TRUE )
10071018

10081019
'' is the base type a struct?
10091020
if( baseDType <> FB_DATATYPE_STRUCT ) then
1010-
errReport( FB_ERRMSG_EXPECTEDCLASSTYPE )
1011-
'' error recovery: skip
1012-
baseSubtype = NULL
1021+
1022+
'' allow extending WSTRING and ZSTRING, the UDT
1023+
'' will use different rules for conversions,
1024+
if (baseDType = FB_DATATYPE_WCHAR) or (baseDType = FB_DATATYPE_CHAR) then
1025+
stringType = baseDType
1026+
baseDType = 0
1027+
assert( baseSubtype = NULL )
1028+
1029+
'' anything else? don't allow
1030+
else
1031+
errReport( FB_ERRMSG_EXPECTEDCLASSTYPE )
1032+
'' error recovery: skip
1033+
baseSubtype = NULL
1034+
end if
1035+
end if
1036+
1037+
'' got a string type? check for another base type
1038+
if( stringType <> 0 ) then
1039+
1040+
'' ','?
1041+
if( lexGetToken( ) = CHAR_COMMA ) then
1042+
lexSkipToken( )
1043+
1044+
'' SymbolType
1045+
hSymbolType( baseDType, baseSubtype, 0, FALSE, TRUE )
1046+
1047+
'' is the base type a struct?
1048+
if( baseDType <> FB_DATATYPE_STRUCT ) then
1049+
errReport( FB_ERRMSG_EXPECTEDCLASSTYPE )
1050+
'' error recovery: skip
1051+
baseSubtype = NULL
1052+
end if
1053+
end if
1054+
end if
1055+
1056+
'' base type? check if z|wstring was already extended
1057+
if( baseSubType ) then
1058+
select case stringType
1059+
case FB_DATATYPE_CHAR
1060+
'' can't extend zstring if inheriting from wstring
1061+
if( symbGetUdtIsWstring( baseSubtype ) ) then
1062+
errReport( FB_ERRMSG_INVALIDDATATYPES )
1063+
stringType = FB_DATATYPE_WCHAR
1064+
end if
1065+
case FB_DATATYPE_WCHAR
1066+
'' can't extend wstring if inheriting from zstring
1067+
if( symbGetUdtIsZstring( baseSubtype ) ) then
1068+
errReport( FB_ERRMSG_INVALIDDATATYPES )
1069+
stringType = FB_DATATYPE_CHAR
1070+
end if
1071+
case else
1072+
'' inherit from base type
1073+
if( symbGetUdtIsZstring( baseSubtype ) ) then
1074+
stringType = FB_DATATYPE_CHAR
1075+
elseif( symbGetUdtIsWstring( baseSubtype ) ) then
1076+
stringType = FB_DATATYPE_WCHAR
1077+
end if
1078+
end select
10131079
end if
10141080
end if
10151081

@@ -1029,7 +1095,7 @@ sub cTypeDecl( byval attrib as integer )
10291095
dim as FBSYMBOL ptr currprocsym = parser.currproc, currblocksym = parser.currblock
10301096
dim as integer scope_depth = parser.scope
10311097

1032-
sym = hTypeAdd( NULL, id, palias, isunion, align, baseSubtype )
1098+
sym = hTypeAdd( NULL, id, palias, isunion, align, baseDType, baseSubtype, stringType )
10331099

10341100
'' restore the context
10351101
ast.proc.curr = currproc

src/compiler/parser-decl-var.bas

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,14 +38,18 @@ sub hSymbolType _
3838
byref dtype as integer, _
3939
byref subtype as FBSYMBOL ptr, _
4040
byref lgt as longint, _
41-
byval is_byref as integer _
41+
byval is_byref as integer, _
42+
byval is_extends as integer _
4243
)
4344

4445
dim as integer options = FB_SYMBTYPEOPT_DEFAULT
4546
if( is_byref ) then
4647
options and= not FB_SYMBTYPEOPT_CHECKSTRPTR
4748
options or= FB_SYMBTYPEOPT_ISBYREF
4849
end if
50+
if( is_extends ) then
51+
options and= not FB_SYMBTYPEOPT_CHECKSTRPTR
52+
end if
4953

5054
'' parse the symbol type (INTEGER, STRING, etc...)
5155
if( cSymbolType( dtype, subtype, lgt, , options ) = FALSE ) then

src/compiler/parser-expr-unary.bas

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -655,6 +655,15 @@ function cAddrOfExpression( ) as ASTNODE ptr
655655

656656
dim as integer dtype = astGetDataType( expr )
657657

658+
'' UDT? it might be a kind of z|wstring
659+
if( typeGet( dtype ) = FB_DATATYPE_STRUCT ) then
660+
var sym = astGetSubType( expr )
661+
if( symbGetUdtIsZstring( sym ) or symbGetUdtIsWstring( sym ) ) then
662+
astTryOvlStringCONV( expr )
663+
dtype = astGetDataType( expr )
664+
end if
665+
end if
666+
658667
if( symbIsString( dtype ) = FALSE ) then
659668
errReport( FB_ERRMSG_INVALIDDATATYPES )
660669
'' error recovery: skip until ')' and fake a node
@@ -678,15 +687,21 @@ function cAddrOfExpression( ) as ASTNODE ptr
678687
end select
679688

680689
'' varlen? do: *cast( [const] zstring const ptr ptr, @expr )
681-
if( dtype = FB_DATATYPE_STRING ) then
690+
select case dtype
691+
case FB_DATATYPE_STRING
682692
expr = astBuildStrPtr( expr )
683693

694+
case FB_DATATYPE_WCHAR
695+
expr = astNewCONV( typeAddrOf( FB_DATATYPE_WCHAR ), _
696+
NULL, _
697+
astNewADDROF( expr ) )
698+
684699
'' anything else: do cast( zstring ptr, @expr )
685-
else
700+
case else
686701
expr = astNewCONV( typeAddrOf( FB_DATATYPE_CHAR ), _
687702
NULL, _
688703
astNewADDROF( expr ) )
689-
end if
704+
end select
690705

691706
'' ')'
692707
if( hMatch( CHAR_RPRNT ) = FALSE ) then

src/compiler/parser-quirk-array.bas

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,37 @@ private function hScopedSwap( ) as integer
8484
dim as integer ldtype = astGetDataType( l )
8585
dim as integer rdtype = astGetDataType( r )
8686

87+
'' Maybe UDT extends Z|WSTRING? Check for string conversions...
88+
if( ldtype <> rdtype ) then
89+
if( ldtype = FB_DATATYPE_STRUCT ) then
90+
var sym = astGetSubType( l )
91+
if( symbGetUdtIsZstring( sym ) ) then
92+
if( rdtype = FB_DATATYPE_CHAR ) then
93+
astTryOvlStringCONV( l )
94+
ldtype = astGetDataType( l )
95+
end if
96+
elseif( symbGetUdtIsWstring( sym ) ) then
97+
if( rdtype = FB_DATATYPE_WCHAR ) then
98+
astTryOvlStringCONV( l )
99+
ldtype = astGetDataType( l )
100+
end if
101+
end if
102+
elseif( rdtype = FB_DATATYPE_STRUCT ) then
103+
var sym = astGetSubType( r )
104+
if( symbGetUdtIsZstring( sym ) ) then
105+
if( ldtype = FB_DATATYPE_CHAR ) then
106+
astTryOvlStringCONV( r )
107+
rdtype = astGetDataType( r )
108+
end if
109+
elseif( symbGetUdtIsWstring( sym ) ) then
110+
if( ldtype = FB_DATATYPE_WCHAR ) then
111+
astTryOvlStringCONV( r )
112+
rdtype = astGetDataType( r )
113+
end if
114+
end if
115+
end if
116+
end if
117+
87118
select case( ldtype )
88119
case FB_DATATYPE_STRING, FB_DATATYPE_FIXSTR, FB_DATATYPE_CHAR
89120
select case rdtype

0 commit comments

Comments
 (0)