GLBasic forum

Feature request => IDE/Syntax => Topic started by: bigsofty on 2012-Sep-15

Title: Better Expression As A Parameter Handling
Post by: bigsofty on 2012-Sep-15
Not sure the best way to word this but here you go...

When a function returns a type and that function is called as a parameter for another function that expects that type, you get an error. It's not really a big deal with other languages as usually the parameter functions results are popped onto the stack and then the 'parent' function uses them. But we get the error below when we try this with GLBasic?

You can create a temp local var to hold the result of the function call then use that as a parameter for the 'parent' function call but this is leading to messy code, with lots of superfluous variables being created so that functions will accept the results from the 'child' function call.

There must be a better way?


This illustrates the problem.

Code (glbasic) Select
// *** Configuration: WIN32 ***
// precompiling:
// GPC - GLBasic Precompiler V.10.060 SN:2e101695 - 3D, NET
//
//   given: Expression
//   wants: TVec3
// "blank.gbas"(32) error : GPC0007 wrong argument type : vecfunc, arg no: 1



TYPE TVec3

x#
y#
z#
w# = 1

FUNCTION SetUp: x#, y#, z#
self.x#=x#; self.y#=y#; self.z#=z#
ENDFUNCTION

FUNCTION GetVec AS TVec3: x#, y#, z#
LOCAL v AS TVec3
v.x#=x#; v.y#=y#; v.z#=z#
RETURN v
ENDFUNCTION

ENDTYPE

FUNCTION caller:
LOCAL v AS TVec3
vecfunc(v.GetVec(0,0,0))
ENDFUNCTION

FUNCTION vecfunc: v AS TVec3
ENDFUNCTION
Title: Re: Better Expression As A Parameter Handling
Post by: kanonet on 2012-Sep-15
Uhh you nasty boy deleted your old thread when I was posting an answer in it. :D

copy+past the old one:
Yeah looks like the compiler gets confused, since it works when you change this:
Code (glbasic) Select
vecfunc(v.GetVec(0,0,0))
to look like this:
Code (glbasic) Select
v=v.GetVec(0,0,0)
vecfunc(v)

Obviously both does the same, but tell this the GPC...

This i one of the Problems with the new precompiler. An other one is, that you cant name a variable after a function now. I suffer from this change, cause it breaks compatibility with old code, i used many variables like global% which no throw a syntax error.
Btw. you should mention that you talk about V11 not V10. ;)
Title: Re: Better Expression As A Parameter Handling
Post by: bigsofty on 2012-Sep-15
Whoops, I apologise for deleting the bug report while you were typing. ;) After  reading it back, I could not make my mind up if this was a bug or a 'feature'? So I thought I would paste it here instead.

Ah, this is a V11 bug (problem?) only then.

It's becoming a real PITA TBH.

For example.

This...

Code (glbasic) Select
FUNCTION caller:
LOCAL v AS TVec3
vecfunc(v.GetVec(0,0,0),v.GetVec(0,0,0),v.GetVec(0,0,0),v.GetVec(0,0,0))
ENDFUNCTION

FUNCTION vecfunc: v0 AS TVec3,v1 AS TVec3,v2 AS TVec3,v3 AS TVec3
ENDFUNCTION


Now has to be written like this...

Code (glbasic) Select
FUNCTION caller:
LOCAL v0 AS TVec3
LOCAL v1 AS TVec3
LOCAL v2 AS TVec3
LOCAL v3 AS TVec3
v0.SetUp(0,0,0)
v1.SetUp(0,0,0)
v2.SetUp(0,0,0)
v3.SetUp(0,0,0)
vecfunc(v0,v1,v2,v3)
ENDFUNCTION

FUNCTION vecfunc: v0 AS TVec3,v1 AS TVec3,v2 AS TVec3,v3 AS TVec3
ENDFUNCTION


:o
Title: Re: Better Expression As A Parameter Handling
Post by: jestermon on 2012-Sep-15
Now I sit back and take a deep breath in amazement. Not at the problem nor at the solution, but at the functions that are "inside" of the TYPE structure.

I am new to GLbasic, but am a veteran in professional game development for over 12 years, in almost every conceivable language. What rocks my boat and really makes me over-enthused is that - functions inside of TYPEs makes it possible to apply Object Orientated design principles in a GLBasic.

With full C capabilities via INLINE, and this principle of simulating "class methods", has made me re-evaluate my game framework designs in GLB, and really appreciate the powerhouse that this engine provides.

So for the next few weeks I will be shredding and reconstructing every example, and also searching in the deepest, darkest dungeons of the forum to see what else GLB has to offer, that is not obvious to the beginner's eye.

The more I play with GLB, the more I am impressed. So thanks for raising the compiler issue and opening my eyes.
Title: Re: Better Expression As A Parameter Handling
Post by: kanonet on 2012-Sep-15
@Bigsofty: I dont know if its just a V11 bug, since I dont have a V10 installed to test. But since V11 is still in beta the new GPC have other problems too, I guess it might be V11 related. And I think tis is definitely a bug, cause it really should be working.

@Jestermon: Yes GLB is a nice and powerful tool and developing with it is fun. Functions in Types was a strong point for my decision to switch to GLB. Its no full OOP but like you said, if you really need something thats not inside, you still can use C. Bigsoftys code here is a short demonstration of how to use types and functions and if you want you may find more on my small website. Too bad the GLB help file has some gaps and does not explain everything, but you should be able to find everything in the forum, just ask if you need help. MrTaToad wrote some books about GLB i heard they are really good and are cheap if you get them them as ebooks, use the search engine to find them, if you are interested.
Title: Re: Better Expression As A Parameter Handling
Post by: jestermon on 2012-Sep-15
@kanonet

Here's my first attempt at using the class approach, and it's perfect for real OO design. The "self" keyword is similar to that used in Python OO, so I am quite used to it. It really is a pity that the documentation is lacking in this respect, since this is probably one of GLB's most modern features, and would have had me using the engine years ago, instead of wading through other (IMO) "cr*ppy" BASIC game engines.

Code (glbasic) Select

TYPE myclass
   name$
   surname$
   age%

   FUNCTION SetInfo: name$,surname$, age%
      self.name$ = name$
      self.surname$ = surname$
      self.age% = age%
      self.SetUpper()
   ENDFUNCTION

   FUNCTION SetUpper:
      self.name$ = UCASE$(self.name$)
   ENDFUNCTION

ENDTYPE

LOCAL names AS myclass

names.SetInfo ("john", "Smith", 30)

PRINT names.name$ + " " + names.surname$ + " " + names.age%, 10, 10
SHOWSCREEN
MOUSEWAIT


Also here's my first attempt at testing the TYPE as a "true" class, and I must say my mind is racing at the possibilities of this. And the great fun about it is it is all done in Basic. Sure the odd "c" pointer can be useful with INLINE, but only if one needs to.

Code (glbasic) Select
TYPE World
   DONE = FALSE
   camera#
   light#

   FUNCTION SetCamera:
      //blah blah
   ENDFUNCTION

   FUNCTION SetLight:
   ENDFUNCTION

   FUNCTION LoadTexture: file$
   ENDFUNCTION

   FUNCTION LoadModel: name$, file$
   ENDFUNCTION

   FUNCTION Run:
      WHILE NOT self.DONE


         SHOWSCREEN
      WEND
   ENDFUNCTION


ENDTYPE

LOCAL game AS World
game.Run()


What I find really great about this approach, is that it is easy to put together a very powerful game framework, and not have to compromise years of OO knowledge and concepts. It's so straight forward to use, it actually hurts so much - from laughing with delight.

PS: Of course inheritance etc. is off the table - but is viable INLINE if needed, but that's so minor, it's not important.
Title: Re: Better Expression As A Parameter Handling
Post by: Kitty Hello on 2012-Sep-15
oh noes! I try to fix that.
Getting the return type of a function is a bit hard for me. I really should rewrite that part.
Title: Re: Better Expression As A Parameter Handling
Post by: Kitty Hello on 2012-Sep-15
attached a hotfix.

[attachment deleted by admin]
Title: Re: Better Expression As A Parameter Handling
Post by: MrTAToad on 2012-Sep-19
I'll give that a try shortly...
Title: Re: Better Expression As A Parameter Handling
Post by: bigsofty on 2012-Sep-19
Whoops, missed Gernots reply, I too will give this a go! :D
Title: Re: Better Expression As A Parameter Handling
Post by: bigsofty on 2012-Sep-21
No luck for me I am afraid...

Code (glbasic) Select

_______________________________________
*** Configuration: WIN32 ***
precompiling:
GPC - GLBasic Precompiler V.10.070 SN:2e101695 - 3D, NET
Wordcount:2479 commands
compiling:
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_tempg.cpp: In member function `DGInt __GLBASIC__::TEditor::SetUp()':
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_tempg.cpp:1000: error: expected primary-expression before "__glb_cstr_3"
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_tempg.cpp:1000: error: expected `}' before "__glb_cstr_3"
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_tempg.cpp:1000: error: expected `,' or `;' before "__glb_cstr_3"
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_tempg.cpp:1002: error: expected `;' before '}' token
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_tempg.cpp:1003: error: `__dAta_of_DIMDATA' was not declared in this scope
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_tempg.cpp: At global scope:
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_tempg.cpp:1005: error: expected unqualified-id before '{' token
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_tempg.cpp:1019: error: expected unqualified-id before "this"
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_tempg.cpp:1019: error: expected `)' before "this"
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_tempg.cpp:1020: error: expected unqualified-id before "this"
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_tempg.cpp:1020: error: expected `)' before "this"
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_tempg.cpp:1021: error: expected unqualified-id before "this"
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_tempg.cpp:1021: error: expected `)' before "this"
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_tempg.cpp:1022: error: expected unqualified-id before "this"
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_tempg.cpp:1022: error: expected `)' before "this"
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_tempg.cpp:1023: error: expected unqualified-id before "this"
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_tempg.cpp:1023: error: expected `)' before "this"
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_tempg.cpp:1024: error: expected unqualified-id before "this"
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_tempg.cpp:1024: error: expected `)' before "this"
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_tempg.cpp:1025: error: expected unqualified-id before "this"
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_tempg.cpp:1025: error: expected `)' before "this"
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_tempg.cpp:1026: error: expected unqualified-id before "return"
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_tempg.cpp: In member function `DGInt __GLBASIC__::TLine::SetUp()':
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_tempg.cpp:26423: error: expected primary-expression before "__glb_cstr_78"
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_tempg.cpp:26423: error: expected `}' before "__glb_cstr_78"
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_tempg.cpp:26423: error: expected `,' or `;' before "__glb_cstr_78"
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_tempg.cpp:26425: error: expected `;' before '}' token
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_tempg.cpp:26426: error: `__dAta_of_DIMDATA' was not declared in this scope
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_tempg.cpp: At global scope:
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_tempg.cpp:26431: error: expected unqualified-id before "return"
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_tempg.cpp:26432: error: expected declaration before '}' token
*** FATAL ERROR - Please post this output in the forum
_______________________________________
*** Finished ***
Elapsed: 4.6 sec. Time: 01:12
Build: 0 succeeded.
*** 1 FAILED ***


Didn't seem to like certain "self."s and "DIMDATA"s?
Title: Re: Better Expression As A Parameter Handling
Post by: kanonet on 2012-Sep-21
Did you use V11.171? Cause this version has some strange bugs related to strings, types, etc. Are you sure this is are the same errors than before? I didnt test Gernots quick fix, since i have V11.171 and cant compile most of my code with it.
Title: Re: Better Expression As A Parameter Handling
Post by: bigsofty on 2012-Sep-21
I used 1.163 since I posed the question for that version and also I saw that .171 had problems already. So I assumed .163 would be a better choice?
Title: Re: Better Expression As A Parameter Handling
Post by: MrTAToad on 2012-Sep-22
163 would be the better choice - but I suspect the GPC executable uses 171 stuff :)
Title: Re: Better Expression As A Parameter Handling
Post by: Kitty Hello on 2012-Sep-24
ok, try hotfix attached. Can you post an example about the dimdata problem is it still exists?



[attachment deleted by admin]
Title: Re: Better Expression As A Parameter Handling
Post by: kanonet on 2012-Sep-24
The string problems that i described in an other Thread are  gone with this hotfix. :good:
But bigsofty's problem from this thread still exist.
Title: Re: Better Expression As A Parameter Handling
Post by: bigsofty on 2012-Sep-24
Yes, the DIMDATA bug has neen squashed but the type reference problems that were described at the beginning of this thread still exists.  :(

Code (glbasic) Select
*** Configuration: WIN32 ***
precompiling:
GPC - GLBasic Precompiler V.10.079 SN:2e101695 - 3D, NET
Wordcount:10 commands
compiling:
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_temp0.cpp: In function `DGInt __GLBASIC__::caller()':
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_temp0.cpp:109: error: invalid initialization of non-const reference of type '__GLBASIC__::TVec3&' from a temporary of type '__GLBASIC__::TVec3'
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_temp.h:10: error: in passing argument 1 of `DGInt __GLBASIC__::vecfunc(__GLBASIC__::TVec3&)'
*** FATAL ERROR - Please post this output in the forum
_______________________________________
*** Finished ***
Elapsed: 1.1 sec. Time: 22:49
Build: 0 succeeded.
*** 1 FAILED ***

Title: Re: Better Expression As A Parameter Handling
Post by: MrTAToad on 2012-Sep-25
We will give it a test :)
Title: Re: Better Expression As A Parameter Handling
Post by: Kitty Hello on 2012-Sep-25
Oh dear. I think it's because of my emergency return value when you forget to return anything.
I'll keep digging...

[edit]
oh no!!!
Code (glbasic) Select

Tvec foo()
{
   Tvec; v; return v;
}
void bar(Tvec& v)
{
}
int main()
{
   bar(foo() );
}


In C++ an "rvalue" (the return thing of a function e.g.) cannot be passed as a reference to a function. It might be passed as a const reference, but then it would not allow you to modify the object passed.

So... You would need a temporary object to pass to this function. The only thing I could think of would be an BYVAL keyword for arguments.


Title: Re: Better Expression As A Parameter Handling
Post by: bigsofty on 2012-Sep-26
This would be fine Gernot, Delphi and C# have keywords for variables that are passed as parameters by reference. Which would be fine for me too.  ;)
Title: Re: Better Expression As A Parameter Handling
Post by: bigsofty on 2012-Sep-30
Here's a rather strange thing, it may be related it may be not.

This function...

Code (glbasic) Select
// Convert a 2D x,y to 3D vec
FUNCTION v2D23D AS TVec3: vec2D AS TVec2, z#=0
LOCAL vec3D AS TVec3
INLINE
return vec3D.SetUp(vec2D.x-screenCentre.x,-vec2D.y+screenCentre.y,z);
ENDINLINE
RETURN vec3D.SetUp(vec2D.x-screenCentre.x,-vec2D.y+screenCentre.y,z)
ENDFUNCTION


Actually creates the same return C code ("return vec3D.SetUp(vec2D.x-screenCentre.x,-vec2D.y+screenCentre.y,z);")...

Code (glbasic) Select
// Convert a 2D x,y to 3D vec.
// ------------------------ //
TVec3 v2D23D(TVec2& vec2D, DGInt z)
{
   __PPRegisterFunction
  #undef __FKT
  #define __FKT __l_dbg_cont
  __VAR_CONTAINER __FKT;
ARGS_VAR(TVec2, vec2D);
ARGS_VAR(DGInt, z);

#undef __GLBNO__
#define __GLBNO__ 258

#undef __GLBNO__
#define __GLBNO__ 259
ON_DEBUG(12,259);
REGISTER_VAR(TVec3, vec3D);

#undef __GLBNO__
#define __GLBNO__ 260
ON_DEBUG(12,260);

/* ---- INLINE ---- */

return vec3D.SetUp(vec2D.x-screenCentre.x,-vec2D.y+screenCentre.y,z);


/* ---- ENDINLINE ---- */

#undef __GLBNO__
#define __GLBNO__ 262

#undef __GLBNO__
#define __GLBNO__ 263
ON_DEBUG(12,263);
return vec3D.SetUp(vec2D.x-screenCentre.x,-vec2D.y+screenCentre.y,z);

#undef __GLBNO__
#define __GLBNO__ 264

#undef __GLBNO__
#define __GLBNO__ 265
ON_DEBUG(12,265);
return TVec3();
}


Yet, the pre-compiler throws an error ""misc.gbas"(316) error : GPC0007 wrong argument type :" for the GLBasic RETURN line?

If I remark the GLBasic RETURN line out it works as expected, using the inline C for the return value as expected.


Oh, here is the TYPE that is called.

Code (glbasic) Select
TYPE TVec3

x#
y#
z#
w# = 1

FUNCTION SetUp AS TVec3: x#, y#, z#
self.x#=x#; self.y#=y#; self.z#=z#
RETURN self
ENDFUNCTION

ENDTYPE
Title: Re: Better Expression As A Parameter Handling
Post by: jestermon on 2012-Sep-30
I may be going a bit overboard with my enthusiasm, but heck, it's not everyday that small code snippit posts tell me more than weeks of searching. So again, my thanks for showing a "returnable" self - in full working context in GLB.
I'm still not used to this level of coding in any version of the Basic language.
Title: Re: Better Expression As A Parameter Handling
Post by: bigsofty on 2012-Sep-30
You very welcome Jestermon. I think maybe the description of GLBs advanced types needs more documentation in the manual to help people digest this, extremely usefull, aspect of the GLBasic language?