complicated this,
macro also did not accept to apply the pointer in its interior
I will do a cleanup on the amount of arrays and try to add a single control macro, and also add a redim preserve
'indexbase 0
skip {
arrayN( -2 to 5 , 3 to 10 )
' 3 4 5 6 7 8 9 10
{ 0 ,1 ,2 ,3 ,4 ,5 ,6 ,7, ' -2
8 ,9 ,10 ,11 ,12 ,13 ,14 ,15,' -1
16 ,17 ,18 ,19 ,20 ,21 ,22 ,23,' 0
24 ,25 ,26 ,27 ,28 ,29 ,30 ,31,' 1
32 ,33 ,34 ,35 ,36 ,37 ,38 ,39,' 2
40 ,41 ,42 ,43 ,44 ,45 ,46 ,47,' 3
48 ,49 ,50 ,51 ,52 ,53 ,54 ,55,' 4
56 ,57 ,58 ,59 ,60 ,61 ,62 ,63}' 5
}
int n0,n1
dim L, C,an
L=3
redim long ArrayNx_M(L)
redim int LBoundNx_M(L*3)
redim int UBoundNx_M(L*3)
redim int TBoundNx_M(L*3)
redim LONG IBoundNx_M(L*3)
int *Arr1
function CriaArray(int ArrayNx,
int Linha_Lbound,int Linha_Ubound,
int Coluna_Lbound,int Coluna_Ubound)
int n= ArrayNx
LBoundNx_M(N)=Linha_Lbound
UBoundNx_M(N)=Linha_Ubound
IBoundNx_M(N)=-Linha_Lbound
TBoundNx_M(N)=abs(Linha_Lbound - Linha_Ubound)+1
LBoundNx_M(N+1)=Coluna_Lbound
UBoundNx_M(N+1)=Coluna_Ubound
IBoundNx_M(N+1)=-Coluna_Lbound
TBoundNx_M(N+1)=abs(Coluna_Lbound - Coluna_Ubound)+1
ArrayNx_M(n)=getmemory TBoundNx_M(N)*TBoundNx_M(N+1)*sizeof int
end function
MACRO ARRAYnx_C(AN , L,C)
'@Arr1= ArrayNx_M(an) '<<<<<<<<
int B=(L+IBoundNx_M(AN))*TBoundNx_M(AN+1)+(c+IBoundNx_M(AN+1))
Arr1(B)
END MACRO
an=1
CriaArray(an, -2,5,3,10)
@Arr1= ArrayNx_M(an) '<<<<<
int n=0
for L=LBoundNx_M(aN) to uBoundNx_M(aN)
for c=LBoundNx_M(aN+1) to uBoundNx_M(aN+1)
ARRAYnx_C(AN, L , C)=N
n=n+1
next
next
L=-1
C=8
PRINT ARRAYnx_C(AN, L , C)
PRINT ARRAYnx_C(AN, 3 , 6)
I have to set up a matrix cleanup function "after learning how to do it"
Eduardo,
Got it!
There are too many state-variables here for macros. They would not provide a clean solution. You need to use an object to contain all the variables and functions associated with the array.
I suggest something like this: (you can adapt it)
'2018-06-13T15:03:24
class IntArrayYX
================
'
%= si sizeof(int)
'
int lboundX 'lower limit X
int uboundX 'upper limit X
int lboundY 'lower limit Y
int uboundY 'upper limit Y
int width
sys buf 'data buffer
int bytes 'sizeof buffer
'
method constructor(int ly=0, uy=0, lx=0, ux=0)
===============================================
'ly lbound y lines
'uy ubound y lines
'lx lbound x rows
'ux ubound x rows
lboundY=ly
uboundY=uy
lboundX=lx
uboundX=ux
width=(uboundx-lboundx+1)
bytes=si*(uboundy-lboundy+1)*width
buf=getmemory bytes
end method
'
method destructor()
===================
freememory buf
end method
'
method vi(int i, j, int v)
==========================
'SET
'i index
'v value
int a at buf+si*( (i-lboundy)*width+(j-lboundx) )
a=v
end method
'
method vi(int i, j) as int
==========================
'GET
'i index
int a at buf+si*( (i-lboundy)*width+(j-lboundx) )
return a
end method
'
method ptr(int i, j) as sys
===========================
'GET POINTER
'i index
return buf+si*( (i-lboundy)*width+(j-lboundx) )
end method
'
end class
'
'TESTS
======
new IntArrayYX ia(-10,20,30,40) 'lbound,ubound pairs
print ia.lboundY ", " ia.bytes
ia.vi(-5,31)=42
print ia.vi(-5,31)
del ia
Charles,
I'm doing this is more to learn and assimilate the workings of the O2 macros, scope and pointers,
and also the operation of the code structure.
but what about the index of the array?
the fact of having to put the value already calculated inside a variable to apply to the array?
this can cause problems because it accepts simple calculations and the person will be left without realizing errors by complex calculations like index
This is an example of a macro function to access an array of pixels. It does not involve Lbound and Ubound terms, so it is a simpler situation.
Macro functions work by creating a temporary variable, which is substituted into the expression, replacing the macro invocation.
indexbase 0
int pix[800*600]
'
macro pix2d int* (v,x,y, vv)
=============================
'v return pixel pointer supporting read/write
'x horizontal coordinate
'y vertical coodinate
'vv sink pixel
if x>=0 and x<800 and y>=0 and y<600
@v=@pix(y*800+x)
else
int vv=0xffffffff 'value when out of bounds
@v=@vv
end if
end macro
'
'TEST
pix2d(1,20)=0xaabbccdd
print hex pix2d(1,20)
print hex pix2d(800,10)
To accommodate index expressions, instead of variables or constants:
@v=@pix(y*800+x)
-->
@v=@pix((y)*800+x)
indexbase 0
int pix[800*600]
'
macro pix2d int* (v,x,y, vv)
=============================
'v return pixel pointer supporting read/write
'x horizontal coordinate
'y vertical coodinate
'vv sink pixel
if x>=0 and x<800 and y>=0 and y<600
@v=@pix((y)*800+x)
else
int vv=0xffffffff 'value when out of bounds
@v=@vv
end if
end macro
'
'TEST
pix2d(1,20)=0xaabbccdd
print hex pix2d(1,20)
print hex pix2d(800,10)
Thanks, Charles.
I think I understood how MACROS work
they are a kind of pointers that can define expressions
in this case the macro would be a pointer to another pnteiro
it was stupid of me not to notice this when I returned the address instead of the value
about index of arrays I think this has to be a first line item in the help file
can generate a lot of confusion, because as it accepts small calculations, the person can think that the internal expreções are totally solved
I took some time having error problems without understanding what was happening
on macros, what I understand is that as pointers do not work in different scopes.
in NAMESPACE for example even putting "::" the variable for which it points will not have the same treatment, the variable of work in this case would have to be public
I went to do a performance test and I liked it a lot
array( -2 to 5 , 3 to 10 )
int n =0
int ln
int l1 =LBoundnx(aN,1)
int l2 =UBoundnx(aN,1)
int c1 =LBoundnx(aN,2)
int c2 = UBoundnx(aN,2)
for ln= 1 to 1000000000
for L=l1 to l2
for c=c1 to c2
ARRAYnx_l(AN, L , C)=N
n=n+1
next
next
next
less than 30 seconds
while my vba even failed to complete, and to complete has to 2 zeros less and still takes almost 2 minutes
maybe this will encourage me to complete the things I did not do because of the processing time
Charles
his proposal using objects took 3 minutes to run with 1 zero less, 6,400,000,000,
an acquaintance from another forum tested in delphi and took 50 seconds the 64 billion of interaction upon matrix
using macros takes 30 seconds the 64 billion interaction
only this macro is breaking my head, it's difficult to define its limits and what exactly it will return
in the attempt posted here I defined an int B and put B as the matrix index,
and it worked,
and now I try INT A = (AN) * 10 and the macro returns me the value of A
even though it is a dirty solution as you said, I still prefer to try a solution using macros
Eduardo,
There is no problem, if you are comfortable using macros, and customising them. The important thing is to ensure that your code is readable, and that you will still be able to understand it six months from now :)
charles
would probably be just a dumb question, but could not create an internal macro in the compiler to recognize matrices indexes?
the macros are called by name,
then it would have to have one for each array, but if called by a set 1 only "[] []" "(,)" could serve for all arrays
well, I do not know if it would be viable or possible
I do not like to have something controlled as an object since they are very slow
EDIT========================
I really said bullshit
I forgot the dimensional control of the array
each created matrix would have to have control variables or use elements of the matrix itself for that purpose
after all how are they done in C and Delphi for example?
Quote from: Charles Pegge on June 13, 2018, 06:12:42 PM
indexbase 0
int pix[800*600]
'
macro pix2d int* (v,x,y, vv)
=============================
'v return pixel pointer supporting read/write
'x horizontal coordinate
'y vertical coodinate
'vv sink pixel
if x>=0 and x<800 and y>=0 and y<600
@v=@pix(y*800+x)
else
int vv=0xffffffff 'value when out of bounds
@v=@vv
end if
end macro
'
'TEST
pix2d(1,20)=0xaabbccdd
print hex pix2d(1,20)
print hex pix2d(800,10)
Hi Charles,
Please note well that the solution you've suggested implements O2 multidimesional dynamic arrays as
row-major entities while since the times of Dartmouth, BASIC arrays and matrices have been stored in memory in a
column-major order. Row-major is rather how the C language and its derivatives would store their arrays and matrices, which makes them element-by-element (pointer) incompatible with their genuine BASIC equivalents without prior
transposition.
It is of course irrelevant for the O2 user as long as all access to the array contents is done via the array indices. But it makes the O2 arrays and matrices binary incompatible with the modules generated by other BASIC compilers, e.g. an O2 project main code and a PB/FB DLL or vice versa.
Hi Mike,
Yes, that example is for accessing pixels in x,y order, conforming to the original hardware layout of pixels in a video controller, and scan-lines in a TV set.
FreeBasic is Row-Major, like C. PowerBasic is Column-Major. But these terms are very confusing, so I have dodged the whole issue and left it to the programmer to decide how they like to arrange their arrays. :)
For general tabular layouts, Row then Column, with each row holding contiguous data, makes more intuitive sense. Each row is a record, and each column is a field.
This is the example I was about to provide for Eduardo:
'2D ARRAY USING A TYPE
uses console
type RowType
int c[16] 'columns
end type
dim RowType r[100]
int i,j
for i=1 to 100
for j=1 to 16
r[i].c[j]=i*10+j
next
next
'
for i=1 to 10
for j=1 to 8
print r[i].c[j] tab
next
print cr
next
wait
I think that this concern with the current type of array of O2 is unnecessary, since it is a visible implementation for the programmer
I myself was ignorant on the subject, and with this knowledge I have been able to improve some routines that I have in Vba
the same solution can be changed with simple change in the calculation of the index.
when this is something internal of the compiler, and transparent to the programmer, then Chales has to decide the course that will take.
Charles, thanks for the example,
this gives a greater margin of examples
I still prefer to implement the macros because they are faster, even though
more work
When traversing an array, you can use a pointer as an alternative to a macro. The pointer is moved instead of recalculating the array index every time an element is accessed. It should be significantly faster!
'TRAVERSING 2D ARRAY USING A POINTER
'INSTEAD OF A MACRO
uses console
dim int ar(100*16)
'macro arr(r,c)
' ar((r)*16+c)
'end macro
int i,j
int *a
for i=1 to 100
@a=@ar(i*16) 'set pointer address
for j=1 to 16
'arr(i,j)=i*10+j
a=i*10+j
@a+=sizeof int 'ptr next element
next
next
'
for i=1 to 10
@a=@ar(i*16) 'set pointer address
for j=1 to 8
'print arr(i,j) tab
print a tab
@a+=sizeof int 'ptr next element
next
print cr
next
wait
MIKE, I do not know exactly what you understood from what I wrote, since even if you restrict, there are terms that have multiple meanings.
and as Charles spoke
"FreeBasic is Row-Major, like C. PowerBasic is Column-Major."
what is the internal O2 standard?
"Perhaps we do not need language specifications and standards at all?"
of course we need to, but O2 does not yet have an internal standard, so the solutions presented are according to the present need as Charles himself pointed out.
this makes explicit that there is a difference to implement and use, I even had difficulty using some examples posted to read the imported vba array, if it was calculated internally I would simply have to transpose the array,
Apart from representations of pixels in an image, and fields in records, we have OpenGl matrixes, which use column-major storage.
The column-major and row-major terminology is confusing because there are two aspects to consider:
First, how the data is stored. For pixels the data is row-contiguous, and for matrixes the data is normally column-contiguous.
Second, the order of indexes in the array expression. For pixels, it is normally x then y, in other words, column then row. But this could easily be reversed.
about language patterns
O2 does not yet have a defined array index and this is clear, O2 is in alpha, and this can be implemented by Chales in the future without affecting what has already been written
then the calculated indexed examples may follow the stated need.
in speaking of Basic patterns, what is the current pattern?
Thin basic for example does not have Goto, something usually standard,
what I found out there in the various Basic
declaration of variables, int x, dim x to integer ...
endif, end if, end
among many other things
porting a small code, "even without an array", may require rewriting everything, even if it is Basic
Eduardo,
I wasn't speaking about the "O2 standard", which I don't even know how to interpret to see what it might relate to. And please, spare me your fantasies about what a BASIC should and shouldn't be. If you have questions to Eros Olmi why he wouldn't implement a goto in his thinBasic dialect, then go ask him why, rather than tell me that someone else should or shouldn't do the same. A programming language is not a subject of the case law but is instead subject to strict standardization and meticulous observance.
I was speaking about standard BASIC (http://www.oxygenbasic.org/forum/index.php?topic=1722.msg18548#msg18548) that we should stick to until we (hopefully) have a newer base document (standard) that would define the aspects of modern BASIC particularities as thoroughly as the older one did.
And it is not the user's prerogative to decide how the BASIC arrays should behave. On the contrary, it is the BASIC dialect developer's responsibility to implement their language in such a way that it is compliant and thus may be called a BASIC at all. And then, it would be the user's responsibility to apply matrix transpose whenever an array element order different from BASIC's conventional column-major is needed for whatever purpose.
It came as a surprise to me that FreeBASIC uses C-style arrays. Such an overt deviationism can indeed be an inexhaustible source of bugs and confusion for the BASIC'ers that know what a BASIC array or matrix should be.
Mike, probably the language barrier is not totally broken by a translator.
but the fact is that, I agree with you on a standardization,
the basic is being massacred by other languages precisely because of lack of a standard of the several existing implementations.
O2 was the only one that I was able to adapt in comparison to so many other basic ones that I tested. even the array being primitive
to my view the intention with the O2 Standard was to be a point of support for the various existing basic's, and to show that to program does not have to be with a lot of || ! = {..}, despite accepting the symbology, the programmer who chooses
If I had the honor of being Charles Pegge, I would implement column-major arrays as the language standard facility in the first place. And then, being as creative and generous as he is, I would throw in a couple of his brilliant macros (in a small font somewhere in the help file footnotes) for the sake of those who might need a different array storage order when dealing exclusively with some 3rd party modules and/or applications.
That's what I'd call "justified polymorphism". :)
I'm not understanding, in case in a given example have to enforce an internal standard that is not followed by all,
I believe that this would only apply to a native embodiment of language
provide (x * lt + y), and have the person use another program to adjust something that a change in the calculation solves, is not consistent
Quoteenforce an internal standard that is not followed by all
It must be followed by all. Otherwise, the BASICs that don't follow it have no right to be called compliant BASICs. They are just indie deviations.
Dartmouth BASIC has column-major arrays. Visual Basic has column-major arrays. PowerBASIC has column-major arrays. What other "flagships" do you need?
Quotehave the person use another program to adjust something that a change in the calculation solves, is not consistent
Matrix transposition is not another program. It is an ordinary matrix mathematics operation standardized by the Dartmouth BASIC specification.
There are many practical cases when BASIC has to communicate with modules (DLLs) written in other languages, and sometimes vice versa. The other languages (like C and its derivatives) have a different array storage order (row-major). Before dealing with two-dimensional arrays that are "calculated" and/or filled in by libraries written in C/C++/C# etc., BASIC is supposed to transpose them to be able to use the same indices that the original C/C++/C# etc. library code was using when filling in those arrays.
This is just one of the base differences between different languages, just like {} and Begin/End. You have to remember it, live with it, cope with it, and follow it if you want to be a successful programmer.
in my limited knowledge of programming.
I think there are other important points about standardization that need to be solved before you care about a Row-Major, Column-Major pattern that does not even exist in O2,
what basic implementations are compatible with each other, that just copy from one to another and will work "even if arrays do not work"?
when doing communication with other programs the programmer has to be aware of the order of the matrix of both the other and the program he uses, and until that point he will have to deal with and learn much simpler things such as syntax,
when you pass arrays if you have to do the required processing, I already had to do this between vba and postgresql, it is easier to handle this than the syntax differences found in BASICs
if speaking of standardization, I remember that the sql of the various databases are not so standardized
Quoteit is easier to handle this than the syntax differences found in BASICs
Then you're probably looking into the wrong BASICs. I said, Dartmouth/VB/PB -- where else should you be looking into?
And finally, if you still have problems/difficulties with the syntax of major BASICs that are still showing some signs of life, then it is probably a little too early for you have your own point of view on what's more and what's less important to an average BASIC programmer, to say nothing of a BASIC dialect developer.
Quotewhat basic implementations are compatible with each other, that just copy from one to another and will work "even if arrays do not work"?
All compliant BASICs should, as a minimum, be able to run Dartmouth code as-is. All more advanced features of the language are just dialect-specific extensions, regretfully, non-standardized up till now.
A good example of compliant BASIC is your hateful Script BASIC that
runs the code snippets (http://www.oxygenbasic.org/forum/index.php?topic=1722.msg18551#msg18551) from the book I quoted earlier without a single change (except for the DATA/READ commands that wouldn't be hard to fix if need be). There are some other dialects that are able to do the same with equal ease.
And if O2 isn't able to read and execute Dartmouth code (directly or with a dedicated, special-purpose include file) as flawlessly, then I am afraid O2 cannot be called a compliant BASIC, regardless of its versatility and polymorphism.
are they really portable codes with each other?
I think in PB I had problems with the Base of the arrays, and something else, and how it was paid, I did not even go ahead.
Do you speak of Dartmouth, but what about developments coming with the advancement of technology?
would not these be standardized among the various basic's?
or at least be easily included?
I think the main thing is not to maintain an absolute compatibility with the past,
is to exchange possibilities and facilities focusing on the context.
"All more advanced features of the language are just dialect-specific extensions, regretfully, non-standardized up till now."
and of course if you can keep the backward compatibility even better, even though there are few instructions.
but well, that would be solved if it had a centralized decision-making,
so it will continue like this, each one deciding what is most important in the compiler or interpreter that creates
Eduardo, you are right.
There is little need to have a full compatibility with previous or dinosaurean basic. As long as
it can do the job like OxygenBasic, it should be worth its salt. Going backwards to those
Jurassic era Basic is pure stupidity just like SB does.
Charles, I apologize
by my mistake, the initial tests with arrays and macros presented an unrealistic processing time.
but I saw that I was wrong, and that even just with the instructions of the loops takes longer than that.
I tested it in C and it takes more than 2 minutes, "I do not know what led this colleague to say that in Delphi it took 50 seconds", another one with the PB took 5 minutes, but they are different machines.
I'll look at the examples you have in O2 threads, and see if have how to split the processes in my project,
I have many analyzes that are independent,
and I'm also going to try to switch to 64bit
Quote from: Anthon Com on June 19, 2018, 02:31:09 PM
Eduardo, you are right.
There is little need to have a full compatibility with previous or dinosaurean basic. As long as
it can do the job like OxygenBasic, it should be worth its salt. Going backwards to those
Jurassic era Basic is pure stupidity just like SB does.
yes, who will want to use Let, Rem, (Goto "line number")
if they do not even decide the basic syntax
( "end if", "endif", "end" ),
(base 0, base1, escolha base),
("function=x", "return x", "function name=x"),
( $ for string),
("&", "+" to concatenate) ...
existence of basic functions such as Goto, Gosub
the fact is that each one chooses what to do in his compiler or translator and they are not of portable codes
Who's going to be involved if it's Row-Major, Column-Major do you have to re-enter the code?
if it's Row-Major or Column-Major, internal, it's only important if you have to make way for other applications, and I think anyone will prefer to imbibe a transpose than to rewrite all the code
Eduardo,
There is usually a trade-off between flexibility and speed, and you can go down to Assembler for specialised high-volume, high-speed calculations.
really Charles, we could not have it all
assembler would be perfect, but I do not think I can structure my ideas directly in that setting. even the symbology of the C and the semicolons disturb me.
in basic I do not even think much, is to have the idea and write, it takes only to choose the names of variables and procedures