bmx-ng / bcc

A next-generation bcc parser for BlitzMax
zlib License
33 stars 12 forks source link

Structs: "lvalue required as left operand of assignment" #529

Closed GWRon closed 4 years ago

GWRon commented 4 years ago
Struct STextParseLineInfo
    'used height in block texts (eg fixed line heights)
    Field boxHeight:Short
...
End Struct

Struct STextParseInfo
    'storage of current font styles
    Field stylesB:Int
    Field stylesI:Int
    Field stylesInvisible:Int
    Field StaticArray stylesColors:SColor8[10]
    Field stylesColorsDynamic:SColor8[]
    Field stylesColorsIndex:Int

    Field baseColor:SColor8
    Field hasCurrentColor:Int

    'helper to read from a given text without extracting strings first
    Field command:SSubString
    Field payload:SSubString

    ' word wrap, alignment and dimensions storage
    Private
    Field StaticArray lineInfo:STextParseLineInfo[10]
    Field lineInfoDynamic:STextParseLineInfo[] = Null
    Public      
...

    Method New(estimatedLineCount:Short, estimatedNestedColorStyles:Int)
        Reset(estimatedLineCount, estimatedNestedColorStyles)

        'set first break index to "none" so rendering only breaks if needed
        GetLineInformation(1).lineBreakIndex = -1
    End Method

    Method GetLineInformation:STextParseLineInfo(line:Int)
        Local lineIndex:Int = line - 1
        If lineIndex >= 0 And lineIndex < lineInfoDynamic.length + lineInfo.length And lineIndex < lineCount
            If lineIndex < lineInfo.length
                Return lineInfo[lineIndex]
            Else
                Return lineInfoDynamic[lineIndex - lineInfo.length]
            EndIf
        EndIf
        Return Null 'empty/default value struct
    End Method
...
End Struct

leads to this C error:

/home/ronny/Arbeit/Share/Dig-master/.bmx/base.gfx.bitmapfont.bmx.release.linux.x64.c: In function ‘__m_base_gfx_bitmapfont_STextParseInfo_New_si’:
/home/ronny/Arbeit/Share/Dig-master/.bmx/base.gfx.bitmapfont.bmx.release.linux.x64.c:3791:192: error: lvalue required as left operand of assignment
  __m_base_gfx_bitmapfont_STextParseInfo_GetLineInformation_TSTextParseLineInfo_i((struct _m_base_gfx_bitmapfont_STextParseInfo*)o,1).__m_base_gfx_bitmapfont_stextparselineinfo_linebreakindex =-1;
                                                                                                                                                                                                ^

(and a lot of other ones ... )

Generated C code there is:

void __m_base_gfx_bitmapfont_STextParseInfo_New_si(struct _m_base_gfx_bitmapfont_STextParseInfo* o,BBSHORT bbt_estimatedLineCount,BBINT bbt_estimatedNestedColorStyles) {
    for(int i=0;i<10;i++) o->__m_base_gfx_bitmapfont_stextparseinfo_stylescolors [i]=((struct brl_color_SColor8){0,0,0,0});
    o->__m_base_gfx_bitmapfont_stextparseinfo_stylescolorsdynamic = &bbEmptyArray;
    o->__m_base_gfx_bitmapfont_stextparseinfo_basecolor = brl_color_SColor8_New_ObjectNew();
    o->__m_base_gfx_bitmapfont_stextparseinfo_command = _m_base_gfx_bitmapfont_SSubString_New_ObjectNew();
    o->__m_base_gfx_bitmapfont_stextparseinfo_payload = _m_base_gfx_bitmapfont_SSubString_New_ObjectNew();
    for(int i=0;i<10;i++) o->__m_base_gfx_bitmapfont_stextparseinfo_lineinfo [i]=((struct _m_base_gfx_bitmapfont_STextParseLineInfo){0,0,0,0,0,0,0});
    o->__m_base_gfx_bitmapfont_stextparseinfo_lineinfodynamic = (&bbEmptyArray);
    o->__m_base_gfx_bitmapfont_stextparseinfo_truncatestartindex = -1;
    o->__m_base_gfx_bitmapfont_stextparseinfo_truncatestartline = -1;
    o->__m_base_gfx_bitmapfont_stextparseinfo_truncateendindex = -1;
    o->__m_base_gfx_bitmapfont_stextparseinfo_truncateendline = -1;
    o->__m_base_gfx_bitmapfont_stextparseinfo_possiblelinebreakindex = -1;
    o->__m_base_gfx_bitmapfont_stextparseinfo_possiblelinebreakcharindex = 0;
    o->__m_base_gfx_bitmapfont_stextparseinfo_handledcharindex = -1;
    o->__m_base_gfx_bitmapfont_stextparseinfo_lastautomaticlinebreakindex = -1;
    o->__m_base_gfx_bitmapfont_stextparseinfo_minimumtextfitsintobox = 1;
    o->__m_base_gfx_bitmapfont_stextparseinfo_calculated = 0;
    __m_base_gfx_bitmapfont_STextParseInfo_Reset_v_ii((struct _m_base_gfx_bitmapfont_STextParseInfo*)o,((BBINT)bbt_estimatedLineCount),bbt_estimatedNestedColorStyles);
    __m_base_gfx_bitmapfont_STextParseInfo_GetLineInformation_TSTextParseLineInfo_i((struct _m_base_gfx_bitmapfont_STextParseInfo*)o,1).__m_base_gfx_bitmapfont_stextparselineinfo_linebreakindex =-1;
}
GWRon commented 4 years ago

Replacing that "struct getter" with this:

        'set first break index to "none" so rendering only breaks if needed
        local lineInfo:STextParseLineInfo = GetLineInformation(1)
        lineInfo.lineBreakIndex = -1

this line is not creating an error anymore.

Yet I think it is the wrong way to "retrieve" a specific struct - and to replace values in there. How to better do that?

Seems this is only "doable" with types ... anyways the error might better be catched by BCC already.

GWRon commented 4 years ago

Just as information: I used this kind of Indirection (line information struct instead of various arrays) as I had for each property two array: Field StaticArray property:Short[10] Field propertyDynamic:Short[]

As this allowed me to have a "fixed size" struct which could - in case of "longer than usual" multi-line texts extend beyond the static assumptions. So for most "cases" the struct worked without using the Garbage Collector at all.

The indirection then "chose" the right array for me and returned the entry of interest.

HurryStarfish commented 4 years ago

We talked about this on discord, so just a quick summary of the actual error here:

Struct S
    Field i:Int
End Struct

Function F:S()
End Function

F().i = 1

C:/Programmierung/BlitzMax-NG latest/tmp/.bmx/untitled1.bmx.console.release.win32.x86.c: In function '_bb_main': C:/Programmierung/BlitzMax-NG latest/tmp/.bmx/untitled1.bmx.console.release.win32.x86.c:63:38: error: lvalue required as left operand of assignment _m_untitled1_F().__m_untitled1_s_i =1;

Since F().i = 1 makes no real sense (it's an assignment to a field of a struct instance that is immediately discarded afterwards, so essentially a no-op), maybe it shouldn't be allowed either way. But it should be a proper compile error from bcc, not invalid C code.


Another bug that's not directly related, but might as well mention it here anyways:

Struct S
End Struct

Local x:S
Local p:S Ptr = x

C:/Programmierung/BlitzMax-NG latest/tmp/.bmx/untitled2.bmx.console.release.win32.x86.c:49:40: error: cannot convert to a pointer type struct _m_untitled2_S bbt_p=(struct _m_untitled2_S)bbt_x;

This should also be a proper compile error.