Page 1 of 1

Arrays() like C/C++?

Posted: Sat Jun 15, 2019 9:53 am
by Mijikai
In PureBasic i need to do this:

Code: Select all

;x y z
Dim vertices.f(6)
vertices(0) = 1:vertices(1) = 1:vertices(2) = 1
vertices(3) = 1:vertices(4) = 1:vertices(5) = 1
While in C you can do this:

Code: Select all

;x y z
float vertices[6] = {
  1,1,1
  1,1,1
} 
Obviously C in this case is way more easy to write, read and understand.
Is there some kind of clever Macro, assembler code or other trick i could use to get the same or similar behaviour?
Iirc there was a Macro for UUIDS that did something similar (it (ab)used DataSection) but i cant find it anymore.

Any Ideas?
:)

Re: Arrays() like C/C++?

Posted: Sat Jun 15, 2019 10:23 am
by Olliv
Not so quick as C syntax, sadly...

However, a member published a solution in 2015 on this forum.

See the way of ASM syntax. I do not remember exactly the right syntax for this day. It seems like this :

Code: Select all

! ALabel:
! DB 0,1,2,3,4,5,6,7,8
! DB 3,2,1
And after, you use CopyMemory() to store your datas to an array.

DB = Data Byte (8 bits)
DW = Data Word (16 bits)
DD = Data Double word (32 bits)
DQ = Data Quad word (64 bits)

ASM hexadecimal numbers differ from PB syntax : I think this is 0xFh, 0Fh or Fh for $F (15).

Re: Arrays() like C/C++?

Posted: Sat Jun 15, 2019 10:28 am
by mk-soft

Code: Select all


; ;x y z
; float vertices[6] = {
;   1,1,1
;   1,1,1
; } 

;x y z
Dim vertices.f(5) ; Index 0..5 

; Validation

size1 = (ArraySize(vertices()) + 1) * SizeOf(float)
size2 = ?end_vertices - ?begin_vertices

; Copy Datasection to Array
If size1 = size2
  CopyMemory(?begin_vertices, @vertices(), size1)
  For index = 0 To 5
    Debug StrD(vertices(index), 2)
  Next
Else
  Debug "Invalid Data Size"
EndIf

DataSection
  begin_vertices:
  Data.f 1.1, 1.2, 1.3, 1.4, 1.5, 1.6
  end_vertices:
EndDataSection


Re: Arrays() like C/C++?

Posted: Sat Jun 15, 2019 10:40 am
by Mijikai
@Olliv that is a nice idea :)
We can place the assembly in a function after the return or anywhere (using a jmp).

Code: Select all

vertices:
!dd 1.0,1.0,1.0
!dd 1.0,1.0,1.0
;access -> ?vertices / we dont need CopyMemory()
This will be fine for static arrays but not for dynamic arrays.
So this is not really a (full) solution (and the DataSection cant grow).

Re: Arrays() like C/C++?

Posted: Sat Jun 15, 2019 10:54 am
by mk-soft
With Macro for Arrays

Edit

Code: Select all


Macro DimWithData(ArrayName, Type, Elements)
  Dim ArrayName#.Type(Elements - 1)
  DataSection
  __Begin_#ArrayName:
EndMacro
  
Macro EndDimWithData(ArrayName)
  __End_#ArrayName:
  EndDataSection
  CopyMemory(?__Begin_#ArrayName, @ArrayName(), ?__End_#ArrayName - ?__Begin_#ArrayName)
EndMacro

Global DimWithData(vertices,f, 6)
  Data.f 1.1, 1.2, 1.3, 1.4, 1.5, 1.6
EndDimWithData(vertices)

For index = 0 To 5
  Debug StrF(vertices(index), 2)
Next


Re: Arrays() like C/C++?

Posted: Sat Jun 15, 2019 11:05 am
by Mijikai
That would be really neat @mk-soft but is that really dynamic?
I always thought that you can not change the size of the DataSection (runtime)?
Can i dynamically "allocate" more memory inside the DataSection?

Re: Arrays() like C/C++?

Posted: Sat Jun 15, 2019 11:31 am
by mk-soft
This is only possible in the first initialization of the array.
The DataSection is Static

Re: Arrays() like C/C++?

Posted: Sat Jun 15, 2019 11:51 am
by mk-soft
Added LoadArrayData from DataSection (Without check ArraySize!)

Link: viewtopic.php?f=12&t=73027

Re: Arrays() like C/C++?

Posted: Sat Jun 15, 2019 4:26 pm
by Olliv
What is finally sad, is C cannot protect our datas so strongly as we can protect them in PureBasic.

Do not hesitate to open a subject about it. I can be wrong...

Re: Arrays() like C/C++?

Posted: Sat Jun 15, 2019 5:24 pm
by Little John
This topic has been discussed before, see e.g.
viewtopic.php?f=13&t=60372

And here is a 10 year old feature request:
viewtopic.php?f=3&t=37635

Re: Arrays() like C/C++?

Posted: Sun Jun 16, 2019 7:56 pm
by Psychophanta
Mijikai wrote:In PureBasic i need to do this:

Code: Select all

;x y z
Dim vertices.f(6)
vertices(0) = 1:vertices(1) = 1:vertices(2) = 1
vertices(3) = 1:vertices(4) = 1:vertices(5) = 1
While in C you can do this:

Code: Select all

;x y z
float vertices[6] = {
  1,1,1
  1,1,1
} 
Obviously C in this case is way more easy to write, read and understand.
Where is the criteria to say such a think :?: :!: :shock:

Re: Arrays() like C/C++?

Posted: Mon Jun 17, 2019 12:32 pm
by Mijikai
For dynamic stuff ill just keep using PureBasic functions.

For static things i came up with some simple macros (still using the inline fasm solution)
to create a section that then can be filled with (any) data.

Why? - Less code and more comfortable compared to a DataSection.
It can be placed anywhere in the program (the accessibility however is subject to the scope of the label).

How does it look:

Code: Select all

Section(Test)
  l() 123,456,789
  f() 2.456
  u() 'Hello!',0
EndSection()

Debug PeekL(?Test + 4)
Debug PeekF(?Test + 12)
Debug PeekS(?Test + 16)
Macros:

Code: Select all

Macro Section(a)
  !jmp @f
  a#:
EndMacro

Macro EndSection()
  !@@:
EndMacro

Macro q()
  !dq 
EndMacro

Macro d()
  !dq 
EndMacro

Macro l()
  !dd 
EndMacro

Macro i()
  If #PB_Compiler_Processor = #PB_Processor_x86
    !dd 
  Else
    !dq 
  EndIf
EndMacro

Macro f()
  !dd 
EndMacro

Macro b()
  !db 
EndMacro

Macro a()
  !db 
EndMacro

Macro u()
  !du 
EndMacro

Macro w()
  !dw 
EndMacro

Re: Arrays() like C/C++?

Posted: Mon Jun 17, 2019 1:37 pm
by Demivec
@Mijikai: Wouldn't you want to use CompilerIf/CompilerEndIf instead of If/EndIf in Macro i()?

Instead of this:

Code: Select all

Macro i()
  If #PB_Compiler_Processor = #PB_Processor_x86
    !dd 
  Else
    !dq 
  EndIf
EndMacro
Use this:

Code: Select all

Macro i()
  CompilerIf #PB_Compiler_Processor = #PB_Processor_x86
    !dd 
  CompilerElse
    !dq 
  CompilerEndIf
EndMacro

Re: Arrays() like C/C++?

Posted: Mon Jun 17, 2019 1:48 pm
by Mijikai
Demivec wrote:@Mijikai: Wouldn't you want to use CompilerIf/CompilerEndIf instead of If/EndIf in Macro i()?
Thanks :shock:
Yes, i added the macro right in the post box as it was missing and made a mistake :oops:

Here are more Macros:

Code: Select all

Macro sa(a);< ascii string + #CRLF$
  !db a#,0x0D,0x0A
EndMacro

Macro su(a);< unicode string + #CRLF$
  !du a#,0x0D,0x0A
EndMacro

;Note: replace the old EndSection() with this (adds a null terminator for strings)
Macro EndSection()
  !dw 0h
  !@@:
EndMacro
Snipped where i use the Macros :)

Code: Select all

;...
          Section(vertices)
            f()  1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0
            f() -1.0,  1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0
            f() -1.0, -1.0, 0.0, 0.0, 0.0, 1.0, 0.0, 1.0
            f()  1.0, -1.0, 0.0, 1.0, 0.0, 0.0, 1.0, 1.0
            f()  1.0,  1.0, 0.0, 0.0, 0.0, 1.0, 1.0, 0.0
            f() -1.0,  1.0, 0.0, 0.0, 1.0, 0.0, 0.0, 0.0
          EndSection()
          
          *vbo = render_CreateVertexBuffer(?vertices,48 * 4,#GL_STATIC_DRAW)
          *vao = render_CreateVertexArray()
          *vao\Layout(3,#GL_FLOAT,#GL_FALSE)
          *vao\Layout(3,#GL_FLOAT,#GL_FALSE)
          *vao\Layout(2,#GL_FLOAT,#GL_FALSE)
          *vao\Buffer(*vbo)

          Section(vertex_shader)
            sa("#version 330 core")
            sa("layout (location = 0) in vec3 aPos;")
            sa("layout(location = 1) in vec3 aColor;")
            sa("layout(location = 2) in vec2 aUV;")
            sa("out vec3 vertexColor;")
            sa("out vec2 vertexUV;")
            sa("void main()")
            sa("{")
            sa("    vertexColor = aColor;")
            sa("    vertexUV = aUV;")
            sa("    gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0);")
            sa("}")
          EndSection()
          
          Section(fragment_shader)
            sa("#version 330 core")
            sa("out vec4 FragColor;")
            sa("in vec3 vertexColor;")
            sa("in vec2 vertexUV;")
            sa("uniform sampler2D myTexture;")
            sa("void main()")
            sa("{")
            sa("    vec2 ndc = vertexUV * 2.0 - 1.0;")
            sa("    //vec3 color = vertexColor * length(ndc);")
            sa("    vec3 color = texture(myTexture, vertexUV).rgb;")
            sa("    FragColor = vec4(color.rgb, 1.0f);")
            sa("}")
          EndSection()
          
          *sdr = render_NewShader()
          *sdr\Add(?vertex_shader,#Null$,#GL_VERTEX_SHADER)
          *sdr\Add(?fragment_shader,#Null$,#GL_FRAGMENT_SHADER)
          *sdr\Link()
;...
Just suit the macros to your need and enjoy :)

Note:
Sadly stacking different data-types horizontally is currently still not possible.