Skip to content

Commit 930f6cc

Browse files
committed
fbc: sf.net # 483 fblite: Can't call LEN with nested WITH block string member
- Also shows up in qb dialect between `__with : end __with` block since both the qb and fblite dialects support periods in variable names. - with outer: len(.inner.member): end with, is incorrectly seen as len( outer.'inner.member' ) where 'inner.member' is taken as the full name of the member of outer. - this bug is due to `CTypeOrExpression()` function looking ahead for a right parenthesis without specifying the `LEXCHECK_NOPERIODS` option. The look ahead token is cached and when the logic falls though, the parser no longer has access to the individual identifiers in the expression and treats it as all one identifier Example: #lang "fblite" '' or "qb" or "fb" #ifndef __with #define __with with #endif type inner_t member as string end type type outer_t inner as inner_t end type dim outer as outer_t outer.inner.member = "blarg" ? len( outer.inner.member ) '' 5 __with outer ? len(.inner.member) '' 5 end __with __with outer.inner ? len(.member) '' 5 end __with
1 parent 4dda1ea commit 930f6cc

File tree

7 files changed

+126
-8
lines changed

7 files changed

+126
-8
lines changed

changelog.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,7 @@ Version 1.09.0
4141
- gfxlib2: fix d2d scaling issues for high dpi (adeyblue)
4242
- fbc: improve error message on statement between SELECT and first CASE inside a subroutine and don't allow CONST/ENUM between any SELECT & first CASE.
4343
- sf.net #843: Implicit casting of argument to string works for Instr() and Mid() but not for Left() and Right()
44+
- sf.net #483 fblite: Can't call LEN with nested WITH block string member
4445

4546

4647
Version 1.08.0

src/compiler/parser-decl-symbtype.bas

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -279,9 +279,12 @@ function cTypeOrExpression _
279279
'' If a simple identifier is given to sizeof/len, then collect
280280
'' information about the symbols which it could refer to. If it could
281281
'' refer to both a type and a non-type symbol, we may want to show a
282-
'' warning later.
282+
'' warning later. Allow FB_LANG_OPT_PERIODS to control lexing the first
283+
'' token but not the look ahead. Only in the qb dialect could variables
284+
'' possibly have periods in the name. In all other cases (like for types)
285+
'' we need to return each identifier between periods.
283286
dim ambigioussizeof as AmbigiousSizeofInfo
284-
if( (lexGetToken( ) = FB_TK_ID) and (lexGetLookAhead( 1 ) = CHAR_RPRNT) ) then
287+
if( (lexGetToken( ) = FB_TK_ID) and (lexGetLookAhead( 1, LEXCHECK_NOPERIOD ) = CHAR_RPRNT) ) then
285288
var chain_ = lexGetSymChain( )
286289
'' Known symbol(s)?
287290
if( chain_ ) then

tests/Makefile

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,10 @@ endif
5050
# build sub-targets based on FB_LANG option
5151
#
5252
ifeq ($(FB_LANG),)
53-
REQ_MOSTLYCLEAN := mostlyclean-unit mostlyclean-fb mostlyclean-qb mostlyclean-deprecated
54-
REQ_CLEAN := clean-unit clean-fb clean-qb clean-deprecated
55-
REQ_TESTS := log-tests-fb log-tests-qb log-tests-deprecated
56-
REQ_FAILED := failed-tests-fb failed-tests-qb failed-tests-deprecated
53+
REQ_MOSTLYCLEAN := mostlyclean-unit mostlyclean-fb mostlyclean-fblite mostlyclean-qb mostlyclean-deprecated
54+
REQ_CLEAN := clean-unit clean-fb clean-fblite clean-qb clean-deprecated
55+
REQ_TESTS := log-tests-fb log-tests-fblite log-tests-qb log-tests-deprecated
56+
REQ_FAILED := failed-tests-fb failed-tests-fblite failed-tests-qb failed-tests-deprecated
5757
else
5858
REQ_MOSTLYCLEAN := mostlyclean-unit mostlyclean-$(FB_LANG)
5959
REQ_CLEAN := clean-unit clean-$(FB_LANG)
@@ -175,6 +175,12 @@ log-tests-fb :
175175
cd . && $(MAKE) -f $(LOGTESTS_MAKEFILE) all FB_LANG=fb
176176
cd . && $(MAKE) -f $(LOGTESTS_MAKEFILE) results FB_LANG=fb
177177

178+
.PHONY: log-tests-fblite
179+
log-tests-fblite :
180+
cd . && $(MAKE) -f $(LOGTESTS_MAKEFILE) mostlyclean FB_LANG=fblite
181+
cd . && $(MAKE) -f $(LOGTESTS_MAKEFILE) all FB_LANG=fblite
182+
cd . && $(MAKE) -f $(LOGTESTS_MAKEFILE) results FB_LANG=fblite
183+
178184
.PHONY: log-tests-qb
179185
log-tests-qb :
180186
cd . && $(MAKE) -f $(LOGTESTS_MAKEFILE) mostlyclean FB_LANG=qb
@@ -196,6 +202,12 @@ failed-tests-fb :
196202
cd . && $(MAKE) -f $(LOGTESTS_MAKEFILE) all FAILED_ONLY=1 FB_LANG=fb
197203
cd . && $(MAKE) -f $(LOGTESTS_MAKEFILE) results FB_LANG=fb
198204

205+
.PHONY: failed-tests-fblite
206+
failed-tests-fblite :
207+
cd . && $(MAKE) -f $(LOGTESTS_MAKEFILE) mostlyclean FAILED_ONLY=1 FB_LANG=fblite
208+
cd . && $(MAKE) -f $(LOGTESTS_MAKEFILE) all FAILED_ONLY=1 FB_LANG=fblite
209+
cd . && $(MAKE) -f $(LOGTESTS_MAKEFILE) results FB_LANG=fblite
210+
199211
.PHONY: failed-tests-qb
200212
failed-tests-qb :
201213
cd . && $(MAKE) -f $(LOGTESTS_MAKEFILE) mostlyclean FAILED_ONLY=1 FB_LANG=qb
@@ -222,6 +234,10 @@ mostlyclean-unit :
222234
mostlyclean-fb :
223235
cd . && $(MAKE) -f $(LOGTESTS_MAKEFILE) mostlyclean FB_LANG=fb
224236

237+
.PHONY: mostlyclean-fblite
238+
mostlyclean-fblite :
239+
cd . && $(MAKE) -f $(LOGTESTS_MAKEFILE) mostlyclean FB_LANG=fblite
240+
225241
.PHONY: mostlyclean-qb
226242
mostlyclean-qb :
227243
cd . && $(MAKE) -f $(LOGTESTS_MAKEFILE) mostlyclean FB_LANG=qb
@@ -242,6 +258,10 @@ clean-unit :
242258
clean-fb :
243259
cd . && $(MAKE) -f $(LOGTESTS_MAKEFILE) clean FB_LANG=fb
244260

261+
.PHONY: clean-fblite
262+
clean-fblite :
263+
cd . && $(MAKE) -f $(LOGTESTS_MAKEFILE) clean FB_LANG=fblite
264+
245265
.PHONY: clean-qb
246266
clean-qb :
247267
cd . && $(MAKE) -f $(LOGTESTS_MAKEFILE) clean FB_LANG=qb

tests/dirlist.mk

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,9 @@ virtual \
4141
visibility \
4242
wstring
4343

44+
DIRLIST_FBLITE := \
45+
fblite
46+
4447
DIRLIST_QB := \
4548
qb
4649

tests/fblite/len.bas

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
' TEST_MODE : COMPILE_AND_RUN_OK
2+
3+
#lang "fblite"
4+
5+
type inner_t
6+
member as string
7+
end type
8+
9+
type outer_t
10+
inner as inner_t
11+
end type
12+
13+
sub test_scoped
14+
dim outer as outer_t
15+
outer.inner.member = "blarg"
16+
17+
ASSERT( len( outer.inner.member ) = 5 )
18+
19+
with outer
20+
ASSERT( len(.inner.member) = 5 )
21+
end with
22+
23+
with outer.inner
24+
ASSERT( len(.member) = 5 )
25+
end with
26+
27+
ASSERT( len(inner_t) = sizeof(string) )
28+
ASSERT( len(outer_t) = sizeof(string) )
29+
30+
31+
dim variable.string as string
32+
variable.string = "klonk"
33+
34+
ASSERT( len(variable.string) = 5 )
35+
ASSERT( len(short) = 2 )
36+
end sub
37+
38+
namespace NS
39+
type inner_t
40+
member as string
41+
end type
42+
43+
type outer_t
44+
inner as inner_t
45+
end type
46+
47+
dim shared outer as outer_t
48+
49+
sub test_NS_implicit
50+
outer.inner.member = "blarg"
51+
52+
ASSERT( len( outer.inner.member ) = 5 )
53+
54+
with outer
55+
ASSERT( len(.inner.member) = 5 )
56+
end with
57+
58+
with outer.inner
59+
ASSERT( len(.member) = 5 )
60+
end with
61+
62+
ASSERT( len(inner_t) = sizeof(string) )
63+
ASSERT( len(outer_t) = sizeof(string) )
64+
end sub
65+
end namespace
66+
67+
sub test_NS_explicit
68+
NS.outer.inner.member = "blarg"
69+
70+
ASSERT( len( NS.outer.inner.member ) = 5 )
71+
72+
with NS.outer
73+
ASSERT( len(.inner.member) = 5 )
74+
end with
75+
76+
with NS.outer.inner
77+
ASSERT( len(.member) = 5 )
78+
end with
79+
80+
ASSERT( len(NS.inner_t) = sizeof(string) )
81+
ASSERT( len(NS.outer_t) = sizeof(string) )
82+
end sub
83+
84+
test_scoped
85+
NS.test_NS_implicit
86+
test_NS_explicit

tests/log-tests.mk

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,10 @@ ifeq ($(FB_LANG),qb)
5454
DIRLIST := $(DIRLIST_QB)
5555
endif
5656

57+
ifeq ($(FB_LANG),fblite)
58+
DIRLIST := $(DIRLIST_FBLITE)
59+
endif
60+
5761
ifeq ($(FB_LANG),deprecated)
5862
DIRLIST := $(DIRLIST_DEPRECATED)
5963
endif

tests/readme.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ $ make unit-tests
3030

3131
$ make log-tests
3232
generates failed-test-fb.log
33+
generates failed-test-fblite.log
3334
generates failed-test-qb.log
3435
generates failed-test-deprecated.log
3536
if all tests passed, the log file reports "None found"
@@ -55,7 +56,7 @@ rescan directories for new or dropped test files.
5556
Use 'make mostlyclean' to clean-up nearly all the files when it is
5657
known that no tests have been added or dropped between test sessions.
5758

58-
Use 'make log-tests FB_LANG=fb | qb | deprecated' to make a specific
59+
Use 'make log-tests FB_LANG=fb | fblite | qb | deprecated' to make a specific
5960
set of -lang tests.
6061

6162

@@ -67,7 +68,7 @@ OS=DOS
6768
FBC=/path/fbc
6869
Specify the location of the fbc compiler
6970

70-
FB_LANG=fb | qb | deprecated
71+
FB_LANG=fb | fblite | qb | deprecated
7172
Specify the compiler dialect
7273

7374
DEBUG=1

0 commit comments

Comments
 (0)