UnderwareDESIGN

PlayBASIC => Show Case => Topic started by: kevin on October 19, 2009, 09:25:13 AM

Title: PlayBasic V1.64k WIP Gallery
Post by: kevin on October 19, 2009, 09:25:13 AM

(http://underwaredesign.com/PlayBasicSig.png)


PlayBASIC V1.64K (Work In Progress) Gallery (October 19, 2009)


    This thread documents the changes being made for the PlayBASIC 1.64 revision K.  


    For newer upgrade work in progress see,

     See  [plink]PlayBASIC V1.64P (http://www.underwaredesign.com/forums/index.php?topic=4089.0)[/plink]   -     Convert PlayBASIC To Machine Code Dll's (http://www.underwaredesign.com/?l=PlayBASIC-To-DLL-Development-Blog)

     See  [plink]PlayBASIC V1.64O (http://www.underwaredesign.com/forums/index.php?topic=3988.0)[/plink]  (9th,Aug,2013)

    See  PlayBASIC V1.64N2/N3 (http://www.underwaredesign.com/forums/index.php?topic=3833.0)

    See  PlayBASIC V1.64N (http://www.underwaredesign.com/forums/index.php?topic=3651.0)

    See  PlayBASIC V1.64M (http://www.underwaredesign.com/forums/index.php?topic=3440.0)

    See  PlayBASIC V1.64L Learning Edition History (http://www.underwaredesign.com/forums/index.php?topic=3405.0) (Building learning Edition Thread)

    See  PlayBASIC V1.64L (http://www.underwaredesign.com/forums/index.php?topic=3364.0)








PlayBasic V1.64k  WIP  Gallery

     This thread will document the changes being made to the PlayBasic 1.64K upgrade...


Math Short Cuts

     The compiler/parser now supports various C styled math short cuts in assignments.  Including  ++, -- , +=, -=, *=, /=



[pbcode]
      Dim Table(2000)

      Table(110)+=1000
      Table(110)-=2222
      
      print Table(110)

      Dim Table#(1000)
      Table#(10)=1000
      
      Table#(10)/=50
      print Table#(10)

      Dim Table$(200)
      Table$(10)="Yeah"
      
      Table$(10)+="Dude"
      print Table$(10)

      a$="Cool"
      print a$

      c$="DUDEDDD"
      b$="YESAH"
      A$=C$+b$
      print a$

      a$++
      print a$

      Type Test
            Aaa
            X
            Y#
            z$
      EndType

      Dim Dude as test

      Dude.x +=100
      Dude.x +=100
      Dude.x +=100
      Print Dude.x      

      Dude.y +=200
      Dude.y +=200
      Print Dude.y      

      Dude.z +="aaa"
      Dude.z +="bbb"
      Print Dude.z      



      Dim Qrr(10,5) as test
      print "Typed Array"

      Qrr(10,5).x =45

      Qrr(10,5).x +=100
      Qrr(10,5).x +=100
      Qrr(10,5).x +=100
      Print Qrr(10,5).x
      
      Sync
      waitkey         


[/pbcode]
 
         
 


 
Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on October 19, 2009, 11:37:17 PM
 Extended the Math short cuts so they can be applied to Typed Arrays/Variables and Pointer Writes

[pbcode]

      Type Test
            Aaa
            X
            Y#
            z$
      EndType

      Dim Dude as test

      Dude.x +=100
      Dude.x +=100
      Dude.x +=100
      Print Dude.x      

      Dude.y +=200
      Dude.y +=200
      Print Dude.y      

      Dude.z +="aaa"
      Dude.z +="bbb"
      Print Dude.z      

      Dim Qrr(10,5) as test
      print "Typed Array"

      Qrr(10,5).x =45

      Qrr(10,5).x +=100
      Qrr(10,5).x +=100
      Qrr(10,5).x +=100
      Print Qrr(10,5).x
      


      
      Dim You2 as integer pointer

      Dim You as integer pointer
      Bank=NewBank(1000)
      addr=GetBankPtr(Bank)
      You= addr
      
      *You = 45
      *You += 100
      *You *=2
      *You /=10
      print *You


      Dim Me as test pointer
      Me = new test

      me.x =13      
      print me.x

      me.x *=4      
      print me.x

      me.x /=13      
      print me.x

      print "Y test"

      me.y +=22      
      print me.y
      me.y *=4      
      print me.y
      me.y /=13      
      print me.y

   
      me.z +="HellO"
      me.z +="HellO"
      me.z +="HellO"
      print me.z

      Sync
      waitkey         

[/pbcode]


 I should point out that shorts cuts are to help simplify user code, your unlikely to gain any runtime performance  over the equivalent long hand syntax.  

 Bench mark(Requires PB1.64K)

[pbcode]


   Dim Table(1000)

   Max=10000

   BumpValue=10

Do

   Cls 0

      frames++
      
      T=timer()
      Table(pos)=0
      for lp=1 to max   
         Table(pos)=Table(pos)+BumpValue
      next
      tt1#+=(Timer()-t)
      print Table(pos)
      print "long Hand:"+str$(TT1#/frames)      


      T=timer()
      Table(pos)=0
      for lp=1 to max   
         // use the +=
         Table(pos)+=BumpValue
      next
      
      tt2#+=(Timer()-t)
      print Table(pos)
      print "Short Cut:"+str$(TT2#/frames)      

      pos =mod(pos+1,1000)


   Sync
loop

[/pbcode]  

 Both loops run at identical speeds.
Title: Re: PlayBasic V1.64k WIP Gallery
Post by: Makeii Runoru on October 20, 2009, 09:21:06 PM
THANK YOU! This will really help shorten code lines!
Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on October 22, 2009, 08:58:34 AM
 PlayBasic V1.64k  - Byte + Word Fields in Types

     I've moved onto adding support from some more field types in UDT structures.  Starting with BYTE  and WORD data types.   While internally PB has no concept of anything as small as a byte or word,  supporting byte & word fields in UDTs will let us communicate better with 3rd party structures.    Which can be handy when calling windows functions or your own dll's perhaps.   You could of course use them in your programs, but the PB runtime is optimized for 32bit integers.   So it's often best to keep things as integers or floats, rather than mixing the datatypes.


Sample

[pbcode]


   Type TestType
      a as integer
      b as float
      c as byte
      d as byte
   EndType


   DIm me as TestType

   me.a =12345678
   me.b =123.456
   me.c= $aa
   me.d =$bb
   print me.a
   print me.b
   print hex$(me.c)
   print hex$(me.d)
   
   print Sizeof(TestType)   
   sync
   waitkey
   
[/pbcode]


Outputs


12345678
123.456
$000000AA
$000000BB
10





Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on October 24, 2009, 08:02:18 AM
 PlayBasic V1.64k  Beta 5 - Math Short Cuts Cont.

   While the new math operation shorts cut can used on the majority of the datatypes/structures in PB, there's still a few structures that they couldn't be applied to.   Namely  array fields in user defined type structures.    However this ommission has been implemented in the BETA 5 of V1.64k.  

    Accessing array fields requires PB to resolve multiple levels to actually get to the element you require, as such,  these are the slowest types of data to access.  However math short cuts and certainly help improve the performance of operations between them.

[pbcode]

   Type TestType
      a as integer
      b as float
      c as byte
      z as word
      d as byte
      Stuff(100)
      Stuff2#(100)
      yeah$
   EndType

   Dim me(100) as TestType


   Max=10000

   BumpValue=1

   Do

      Cls 0

      frames++
      T=timer()
      Me(50).stuff(pos)=0.0
      for lp=1 to max   
         Me(50).stuff(pos)=me(50).stuff(pos)+BumpValue
      next
      tt1#+=(Timer()-t)
      print Me(50).stuff(pos)
      print "long Hand:"+str$(TT1#/frames)      


      T=timer()
      Me(50).stuff(pos)=0
      for lp=1 to max   
         // use the +=
         Me(50).stuff(pos)+=BumpValue
      next
      
      tt2#+=(Timer()-t)
      print Me(50).stuff(pos)
      print "Short Cut:"+str$(TT2#/frames)      

      pos =mod(pos+1,100)

   Sync
loop
[/pbcode]
 
    In this example we're adding a value to a nested integer array.  This time using the new += operator gives up about as %30 speed boost over the long hand version.  


 
Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on October 25, 2009, 12:00:19 PM
  PlayBASIC V1.64k  Beta 5b - Bit wise operator Math Short Cuts.

 Added support for bit AND (&=), OR(|=) and XOR(~=) as short cuts, as well as fixing a few casting issues short cuts in the previous beta.
   

[pbcode]
   a=$aabb
   
   a&=$ff

   print hex$(a)


   Dim Test(1)
   
   Test(1)= $aabbccdd
   
   Test(1)&=$ff0000ff
   print hex$(Test(1))

   Sync
   waitkey

[/pbcode]


Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on October 25, 2009, 10:25:54 PM
  PlayBASIC V1.64k  Beta 5b - Cont.

  This is just some test/bench code to see if there's any extra operations (casts) creeping into math shorts operations upon variables, when they're not the same data type.. But thankfully there's not now.  If there was, there'd be a performance penalty for using the short cut in this case..  

[pbcode]
   Max=10000

   BumpValue#=10

Do

   Cls 0

      frames++
      
      T=timer()
      IntVar=0
      for lp=1 to max   
         IntVar=IntVar+BumpValue#
      next
      tt1#+=(Timer()-t)
      print IntVar
      print "long Hand:"+str$(TT1#/frames)      


      T=timer()
      IntVar=0
      for lp=1 to max   
         IntVar+=BumpValue#
      next
      tt2#+=(Timer()-t)
      print IntVar
      print "Short Cut:"+str$(TT2#/frames)      
   Sync
loop

[/pbcode]


Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on October 26, 2009, 02:07:13 AM
 PlayBASIC V1.64k  Beta 6 - Cont.

  If you're read the blog in the maintenance area you'll have no doubt noticed that i wanted to make a few more tweaks to VM1's performance, namely with how some the low level opcodes we're set up..  So this afternoon i've been going through the rather laborious process of restructuring how the VM executes the pointer and stack opcodes.    

  The results  have been fairly pleasing,  with approximately a 10% speed improvement on function calls and around a %40 speed improvement on writing into  array fields.. More tweaks to come

[pbcode]

   Type Stuff
         a
         b#
         c$
         Array(1000)
   EndType


   Dim me as stuff
   
   

   Tests=10000

   Do
      cls 0
      inc frames

         print "Writing to Typed Fields Performance Test"

         // ===================================
         // USer Functions VS Projected Subroutines
         // ===================================

         // ==========
         // Test #1
         // ==========

         T=timer()
         For LP=0 to Tests
            me.a=255
         next         
         tt1#=tt1#+(timer()-t)
         Print "Write Integer Average Time:"+Str$(tt1#/frames)   



         T=timer()
         For LP=0 to Tests
            me.b=255
         next         
         tt2#=tt2#+(timer()-t)
         Print "Write Float Average Time:"+Str$(tt2#/frames)   


         T=timer()
         For LP=0 to Tests
            me.c="255"
         next         
         tt3#=tt3#+(timer()-t)
         Print "Write String Average Time:"+Str$(tt3#/frames)   


         T=timer()
         For LP=0 to Tests
            me.array(10)=255
         next         
         tt4#=tt4#+(timer()-t)
         Print "Integer Array Average Time:"+Str$(tt4#/frames)   
   
      Sync
   loop   

[/pbcode]
   
Title: Re: PlayBasic V1.64k WIP Gallery
Post by: Makeii Runoru on October 26, 2009, 11:39:18 AM
I'm pleased with this. : )

Maybe you can add multi-dimensional support to arrays in types?
Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on October 26, 2009, 11:59:17 PM
    Multi dimensional array fields are a possibility, and It's something that'd id like to add at some point..  The problem now is, that this type addressing comes with a lot more runtime overhead..  The more dimensions you have,  that more work it requires to locate the field being addressed.  

   For  Example.
[pbcode]
    Type Stuff
              x,y,z
              SomeArray(20,40)
              SomeOtherArray(20,40)

    EndType
   Dim Obejcts(100) as stuff
   Objects(50) = new stuff
   Objects(50).SomeArray(10,5)  = 45
   Objects(50).SomeOtherArray(10)  = 12
[/pbcode]

    To actually read/write into this a field, we've first got to locate the structure first within the object array (ie mult and peek it out),  then work the filed offset within this structure.     To get the field offset (the element within the array)  we multiply the first (or second field) by what the number of elements is, then  add the other field..

     FieldOffset =  (FirstDim * 41) + SecondDim

     So to access one field there's possibly as many of 5/6 (low and high level) opcodes  that need to  pass through the VM.     So the cost operating upon such fields would be rather high.  

     Often it's best to export a pointer from the sub field and write directly into that parent structure yourself, which removes the need for the parent to be constantly dereferenced.   Which pretty much emulates what the With / EndWith statement pairs do in Visual Basic for example.  

     The best solution really is to make the embedded array a reference.  But the way the current parser works, this isn't really practical in PB atm.    What this would mean is that you could have fields that allow to attach arrays (dynamically sized) to them..   These could then be passing into handler functions that can receive this data type..  So rather and access the nested fields through the parent constantly,  you could dim the array, then pass it to a handler.  


     NOTE: This is CONCEPT ONLY sample code...


    Type Stuff
              x,y,z
              SomeArray()
              SomeOtherArray()
    EndType
     Dim Obejcts(100) as stuff
     Objects(50) = new stuff
     Dim Objects(50).SomeArray(20,40)   // alloc this field and set it up as a 2d array
     Dim Objects(50).SomeOtherArray(105)   // alloc this field and set it up as a 1d array
     Fill1DArray(Object(50).SomeOtherArray(),666)

Function Fill1DArray(Me(),Value)
      for lp=0 to getarrayelements(me(),1)
           me(lp)=Value
      next
EndFunction


    Due to how arrays work in VM1 (PB runtime), adding this type of functionality  PB isn't so easy.  However, such functionality is supported in the VM2 runtime ( PBFX) , which is designed to allow  such controls and more.  

Title: Re: PlayBasic V1.64k WIP Gallery
Post by: Makeii Runoru on October 27, 2009, 01:53:20 AM
Well, Alright. I understand. And it's not terribly hard to find array indices for a 1D array, so multi-dimensional arrays aren't really needed. I didn't know how much work would be put into adding them.

Is there a possibility of making classes in PB, like C++ does? The only reason I ask is because sometimes I'd like functions not to be global, but rather inside of an object, preferably a type.

[pbcode]
constant NORTH = 1
constant EAST = 2
constant SOUTH = 3
constant WEST = 4

type t_player
  x#
  y#

  Function Move(dir)
     ...
  Endfunction
endtype

Dim Player as t_player
Player.Move(WEST)
[/pbcode]
Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on October 27, 2009, 08:40:00 AM

QuoteIs there a possibility of making classes in PB, like C++ does?

     Yes & No.   Eventually some limited Object Orientation   will appear,  but this is really isn't practical in PB today.  Comparably,  implementing OO support makes multi dimensional arrays look like a cake wake.  So it's not something you can just drop in quickly here.

Title: Re: PlayBasic V1.64k WIP Gallery
Post by: Makeii Runoru on October 28, 2009, 06:36:57 PM
Alrighty. But that's nice that OO support is going to be supported. I mean, I write code in such a way that it presents itself in an OO manner, but it's not the same as some other languages out there. Usually I make types and Dimension them right after, and then in a separate tab create the functions or "events" that the object uses.
Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on October 29, 2009, 12:33:10 AM
 PlayBASIC V1.64k  Beta 7 - Stacks opt's = Better recursion speed.

  Been working on the stack controls the past couple of days,  made a few improvements in previous beta's, which turned out to be hindrances also, but ya get that !  -  The stack is really a hidden bottle neck in how various parts of PB runtime (VM1) perform.  So improving the stack functionality can make the overall runtime performance that little bit snappier.  Which means your programs can run faster.  

 The current changes have been mostly relating to how a change of scope occurs (function calling).   The old version is very polite and includes a wealth of error trapping and type matching that isn't always needed (however, some times it is!) -  So, what I've been doing is restructuring the call function stack usage ,  to remove as much of nanny code as possible.  

  It's taken a lot longer than i'd originally expected to get working, but finally the scope change caller is yielding almost universally better results.  For a simple function calls (small functions) it's only slightly faster though.    In fact,  BEta 7 is slower than previous betas in this regard.  However, previous beta's relies upon a few too many assumptions, in others words,  they don't actually work correctly :)  

  Beta 7 is quicker than previous PBV1.64j retail editions and thats what matters, but only marginally (by a couple of %), where it starts to shine is in calling larger scopes (big fat functions with lots of locals) and in particular recursive function calls.    

  In the example bellow we have a parent/child structure that's designed to use recursion.   V1.64k Beta 7 runs this example approximately %30 faster then V1.64J Retail.    Which is nothing to sneeze at..


[pbcode]

   Constant MaxChildren=255

   Type tObjectParent
         x#,y#   
         TranslatedX#,TranslatedY#   
         Angle#
         ScaleX#
         ScaleY#
         Colour
         Size
         Parent
         ChildCount         ; max kids
         Children(MaxChildren)      // This obejct can have a 255 children attached to it
   EndType

   Type tObjectChild as TobjectParent
   Endtype


   // This array holds the entire data structure of parents and their children
   Dim Ball(0) as tobjectParent


  TestParent=CreateParent(100,200,45)

   // Append Child to the parent
    Child2=AddChildToParent(testParent,100,100,00)

   // append a bunch of kids to the Child
   Kids=50
   Dim Children(Kids)
   for lp=1 to Kids
         angle#=(360.0/Kids)*lp
         x#=cos(angle#)*150
         y#=sin(angle#)*150
        Children(lp)=AddChildToParent(Child2,x#,y#,0)
   next
       
      
;    setfps 100   


    Do
         cls $204080

         TurnObject(TestParent,2.25)
         
         PositionObject(TestParent,mousex(),mousey())
         
         sangle#=wrapangle(sangle#,1)
         s#=2+cos(sangle#)*1
         s#=1
         ScaleObject(Child2,s#,s#)
         

         // loop through and process all the parent objects
         lockbuffer
         t=timer()
            for lp=1 to GetArrayElements(Ball(),1)
               if TypeOf(Ball(lp))=tObjectParent
                     // process a parent object
                     
                     ParentX#=Ball(lp).x#
                     ParentY#=Ball(lp).y#
                     Angle#   =Ball(lp).angle#
                     ScaleX#   =Ball(lp).scalex#
                     ScaleY#   =Ball(lp).scaley#
                     circlec parentx#,parenty#,Ball(lp).size,true,Ball(lp).colour
                     // DRaw it's kids
                     DrawChildren(lp,ParentX#,ParentY#,angle#,scaleX#,scaleY#)
               endif
         next
         tt#=tt#+(Timer()-t)
         unlockbuffer

         inc frames
         print tt#/frames
      Sync   
    loop




   
   
Function CreateParent(X#,y#,angle#)
      Index=GetFreeCell(Ball())
      Ball(index).x#=x#
      Ball(index).y#=y#
      Ball(index).ScaleX#   =1
      Ball(index).ScaleY#   =1
      Ball(index).Angle#=angle#
      Ball(index).size =20
      Ball(index).colour =$ff0000
EndFunction Index



Function TurnObject(Index,AngleStep#)
      Ball(index).angle#=wrapangle(Ball(index).angle#,AngleStep#)
      
EndFunction Index



Function ScaleObject(Index,ScaleX#,scaley#)
      Ball(index).ScaleX#   =ScaleX#
      Ball(Index).ScaleY#   =ScaleX#
EndFunction


Function PositionObject(Index,X#,y#)
      Ball(index).x#=x#
      Ball(index).y#=y#
EndFunction Index



Function AddChildToParent(ParentIndex,X#,y#,angle#)

      ChildIndexInParent=FindFreeChildInPArent(ParentIndex)
      if ChildIndexInParent

         ChildIndex=GetFreeCell(Ball())

         Ball(Parentindex).ChildCount=Ball(Parentindex).ChildCount+1
         
         // store the index of this child in the parents local array                  
         Ball(Parentindex).Children(ChildIndexInParent) =ChildIndex

         // create the child.  The child is local to the parent  
         Ball(childIndex)             = new tObjectChild
         Ball(Childindex).Parent      =ParentIndex
         Ball(Childindex).x#         =x#
         Ball(Childindex).y#         =y#
         Ball(Childindex).Angle#      =angle#
         Ball(Childindex).ScaleX#   =1
         Ball(Childindex).ScaleY#   =1
         Ball(Childindex).size       = 10
         Ball(Childindex).colour      =255
         
      endif
EndFunction ChildIndex





   
Function DrawChildren(ThisParent,ParentX#,ParentY#,Angle#,ScaleX#,ScaleY#)

      ca#=Cos(angle#)
      sa#=Sin(angle#)
   
      for lp=1 to MaxChildren-1
         ThisChild=Ball(ThisParent).Children(lp)
         if ThisChild

               Colour=Ball(ThisChild).Colour
               Size   =Ball(ThisChild).size   
               X#=Ball(ThisChild).x#*ScaleX#
               Y#=Ball(ThisChild).y#*ScaleY#
               rotatedX#=ParentX#+( (ca#*x#)-(sa#*y#))
               rotatedY#=ParentY#+( (ca#*y#)+(sa#*x#))
               Ball(ThisChild).TranslatedX#=RotatedX#
               Ball(ThisChild).TranslatedY#=RotatedY#
               circlec RotatedX#,RotatedY#,size,true,colour         
         endif
      next

      // draw children
      if Ball(ThisParent).ChildCount
         for lp=1 to MaxChildren-1
            ThisChild=Ball(ThisParent).Children(lp)
            if ThisChild
                     x#         =Ball(ThisChild).TranslatedX#
                     y#         =Ball(ThisChild).TranslatedY#
                     DrawChildren(ThisChild,X#,Y#,wrapangle(Ball(ThisChild).Angle#,Angle#),Ball(ThisChild).ScaleX#,Ball(ThisChild).ScaleY#)
            endif
         next
      endif

EndFunction


function LocateAbsoluteParentOffset(ThisChild)
      repeat
         parent =Ball(ThisChild).Parent
            x#=x#+Ball(ThisChild).x#
            y#=y#+Ball(ThisChild).y#
      until   Parent=0
EndFunction x#,y#



Function FindFreeChildInPArent(ThisParent)
      for lp=1 to MaxChildren
         ChildIndex=Ball(ThisParent).Children(lp)
         if ChildIndex=0
               exitfunction lp
         endif
      next
EndFunction Index



[/pbcode]


Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on October 29, 2009, 11:48:39 PM
 PlayBASIC V1.64k  Beta 8 - Mismatched Assignment Casting.

 hadn't noticed this before, but PB doesn't seem to like assigning pointers to integer/float variables.  From the parsers perspective this is perfectly legal, but the runtime doesn't actually feature the require opcodes.  So in older version of PB you'll get a unknown opcode error.   As such I've dropped in some support for this.   Seems to work ok..

 eg.

[pbcode]

   ; declare pointer (generic)   
   Dim a as pointer

   ;  assign the Integer variable PTR the integer value of 5   
   ptr=5


   // move integer to pointer
   a = ptr   

   // move pointer to integer
   i=a
   print i


   // Add  pointer to integer
   i+=a
   print i

   sync
   waitkey

[/pbcode]


 Edit: Should work on all the main structures now.

[pbcode]

// declare pointer (generic)   
   Dim a as pointer

   //  assign the Integer variable PTR the integer value of 5   
   ptr=5

   // move integer to pointer
   a = ptr   

   // move pointer to integer
   i=a
   print i

   // Add  pointer to integer
   i+=a
   print i



   Dim Stuff(100)
   Dim Stuff#(100)
   
   
   Stuff(1) +=a
   Stuff(1) +=a
   Stuff(1) +=a
   print Stuff(1)

   Stuff#(1) +=a
   print Stuff#(1)


   Type SomeData
         x,y,z
         f#
   endtype

   Dim Y as SomeData
   Dim W(10) as somedata



   y.x +=a
   y.f +=a
   y.x +=a
   y.f +=a

   print "typed variable"
   print y.x
   print y.f

   w(1).x =a
   w(1).f =a
   w(1).x *=a
   w(1).f *=a

   print "typed array"
   print w(1).x
   print w(1).f

   sync
   waitkey


[/pbcode]

Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on November 01, 2009, 12:02:37 AM
 PlayBASIC V1.64k  Beta 9 - Array operators / Assignments.

   Currently working my way through adding some more array functionality in the way of operators.   So far this beta has some (limited) support for array handle assignments.    In case you didn't know (if so, you might want to read the Helps->About tutorials at some point!),  when we use handle in PB we're talking about about the entire array, be it a Integer array,  Float array ,String array, Typed array or Typed variable .    The container is basically the housing the around the elements inside the array structure.  So these operations are not applied upon individual elements inside the array, but the entire arrays contents.

   So far, all we can do is copy the right side to the left.   Ie.   DestArray() = SrcArray(),  which at this point is really only a short cut for CopyArray command.    I've a few other ideas that might be handy also, but it'll keep those under wraps for the time being.    

   Anyway, here's a example.  

[pbcode]

   // dim two 1d arrays
   Dim Array(1)
   Dim Array2(20)

   // fill array2 with some random values   
   For lp=1 to 20
      Array2(lp)=rnd(100)
   next

   // show the current state of both arrays
   print "Arrays Before Assignment"
   print ShowArray(Array())
   print ShowArray(Array2())


   // __COPY___ Array2 into Array()   
   Array() = Array2()

   // show the current state of both arrays
   print "Arrays After Assignment"
   print ShowArray(Array())
   print ShowArray(Array2())


   // refresh display and wait for keypress
   Sync
   WaitKey
      
Function ShowArray(Me())
   for lp=1 to getarrayelements(me(),1)
      s$=s$+digits$(me(lp),3)+","
   next
   s$=trimright$(s$,",")
EndFunction s$

[/pbcode]


  Outputs



Arrays Before Assignment
000
078,099,042,026,083,064,094,028,081,088,005,031,086,046,084,099,084,024,042,087
Arrays After Assignment
078,099,042,026,083,064,094,028,081,088,005,031,086,046,084,099,084,024,042,087
078,099,042,026,083,064,094,028,081,088,005,031,086,046,084,099,084,024,042,087




[plink]See developers blog for more on new features concerning arrays (http://www.underwaredesign.com/forums/index.php?topic=3627.75)[/plink]

Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on November 02, 2009, 12:53:03 AM
 PlayBASIC V1.64k  Beta 10 - Returning UDT's from Functions.

  Today I've been looking into the best way to insert such functionality into PlayBasic V1.64k.  Implementing this today is basically about bridging the gaps, and trying not to leak memory in the process.   While it's not currently working, I'm reasonably sure that VM1 includes enough control to wedge such an ability into it.  Might not be most elegant solution internally, but it should work ok.
 
   I should point out here, that we're talking about returning a single UDT pointer instance, not a container (array/list etc)..  

[pbcode]

   Type Vector2D
      x#,y#
      stuff(20000)
   Endtype

   Dim Cool as Vector2D

   Cool = TestUDTFunction(4444,555)
   print Cool.x#
   print Cool.y#

   Sync
   WaitKey
      

Function TestUDTFunction(x#,y#)

   LocalType = new Vector2D   
   LocalType.x#=x#
   LocalType.y#=y#   

   print LocalType.x#
   print LocalType.y#
   print "This:"+STR$(Int(LocalType))

EndFunction LocalType as Vector2D

[/pbcode]


Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on November 02, 2009, 10:22:26 AM
 PlayBASIC V1.64k  Beta 10b - Returning UDT's from Functions (Continued) .

    It's been a pretty creative and productive couple of days code wise. Thus far, every thing seems to have come together to fairly well, which is  surprising.  It hasn't all gone to script with the odd WTF moment,   but  most things on my to do are getting ticked off fairly quickly this time, and i'm happy to say that  Returning User Defined Types  is now one of them.    
 
    Lets not get too far ahead ourselves though,  currently you can only return a single new instance of TYPE from a FUNCTION (NOT a PSUB).  This type is accessible through a UDT pointer inside the function,  then exported as new type bank from the function.   So what's returned from the function call is virtually the same as what the NEW operator returns.   Which is the 'buffer' this type structure is stored within, and not an array/list container.   Therefore PB will expect you to write this buffer handle into a container such as typed variable/array or list.  If you don't, you'll leak this memory !

    Now since the return type is a UDT pointer inside the function, we actually need to initialize this using the NEW operator. If you don't do this, it'll crash anytime you read/write to the field.   I could possibly do this for you (init it as the types declared parent type), but then you'd lose some control, since types can be inherited in PB. So what you could is  Dim the return type as the general parent, but actually allocate one of it's siblings.  Which is perfectly legal.

    Anyway, here's a bit of a working example..      


[pbcode]

    setfps 60

   // declare our type structure   
    Type MyObject
            x#,y#
            radius
             deathtime
            colour
    EndType


   // declare & create our global LIST conatiner to hold all our ships  
    Dim Ship as MyObject list


   // ==========================================
   // main loop
   // ==========================================

 Do

        Cls 0

         lockbuffer
              CurrentTime=Timer()
            for each  Ship()
               if CurrentTime<Ship.DeathTime
                  circlec Ship.x#,Ship.y#,Ship.Radius,true,ship.colour      
               else
                  Ship=Null
               endif   
            next
         unlockbuffer  


         if  Rnd(1000)>250
            // add 5 to the list container
            for lp=1 to 5
               Ship= SpawnNewObject()
            next
         endif
 
        Sync

 loop   


Function SpawnNewObject()

   // NOTE!! - You MUST NEW the return type prior to reading or writing to it
   This = New MyObject

   This.x#=rnd#(getscreenwidth())
   This.y#=rnd#(getscreenHeight())
   This.Radius=rndrange(10,50)
   This.Colour =rndrgb()
   This.DeathTime=Timer()+rndrange(1000,2000)

EndFunction  This as MyObject

[/pbcode]

Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on November 03, 2009, 12:43:13 AM
 PlayBASIC V1.64k  Beta 11 - Improving 'As Datatype' support in function declarations.

    I don't really see this as a feature, it's one of those additions that will make declarations a little more uniform with the outside world.  Currently, I've only added 'As integer" trapping in EndFunction declarations (see example bellow).    But will extend this to Floats and Strings also at least.   It's here we start to run into some problems.   PlayBASIC, like traditional BASIC languages is Multi instance.  Where as the majority of modern languages (including most modern BASICs) are single instance.

   What does this mean ?  - Well it means that each keyword is unique and always associated with a particular object/data type regardless.  In multi instances dialects, the same keyword can be used to represent various data types, the language differentiates between the instances by looking at the postfix symbols.   So in PlayBASIC we can the have a variables (and even arrays) called   XPOS,  XPOS#, XPOS$ etc etc.  

   Now in most declarations in PB we can generally use the postfix shortcuts,  Local/Static/Global/Declaration/EndDeclaration blocks ie     Local A, B#   (declares A an integer and B# as float)

  The same applies to type declarations, for example you can create a pair of float fields in two ways..

  #1 - Using post fix as short cuts

Type Vector2D
  X#
  y#
EndType


 #2 or as data type method (long hand)


Type Vector2D
  X as float
  y as float
EndType


  You'll notice that X & Y "as float"  overrides the fields X & Y from integers (default) to become floats.   Which is the same as if you use dim to declare a float long hand.

  ie.

[pbcode]
   Explicit on
   
   Dim X as float
   
   X# = 123.456   
   Print X#
   
   Sync
   Waitkey
     
[/pbcode]

  However, just because the declaration doesn't use the postfix, that doesn't mean you can drop it during operations upon this variable. If you do, the parser with assume you mean the Integer instance.  So If you're running  in explicit mode,  you'll get the a declaration error.  Like so,


[pbcode]
   Explicit on
   
   Dim X as float
   
   X = 123.456   
   Print X#
   
   Sync
   Waitkey
[/pbcode]


    Notice the dropped # when accessing the X variable.  Since no integer X  has been previously declared this will pop a compile time error.  This is the intended behavior !

    The point i'm getting at here, is that this same behavior will occur in Function/EndFunction & Psub/EndPsub  declarations.  
   
    Anyway, here's a sample of what's currently running..

[pbcode]

   explicit on

  Dim a as integer
  Dim b as integer

  a,b=Cool()

   print a
   print b
   
   Sync
   waitkey   

Function Cool()

      result=45.4
      dude=666
EndFunction Result as integer,dude as integer


[/pbcode]

Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on November 03, 2009, 09:44:55 PM
 PlayBASIC V1.64k  Beta 11 - Improving 'As Datatype' support in function declarations (continued).

    The success of yesterdays initial session implementing such parser changes, was soon soured upon running into a rather awkward logical issue to resolve.  In fact, it's taken most of the day to come up with something that even works.. grrrr

     Anyway,  so what this all means is that you can use the as datatype declarations in your Function/EndFunction headers. (They'll also work in Psub/EndPSub too) .

   Here's today's (Thrilling :) )example...


[pbcode]

   explicit on

  Dim a as integer
  Dim b as integer
  Dim c as float  
 
     
;   a,b=Cool()
;   print a
;   print b
   Dim MyPtr as pointer

  a,c#=Cool_Floats(MyPtr)
 
   print a
   print c#
   
   Sync
   waitkey
   

Function Cool()
      result=45.4
      dude=666
EndFunction Result as integer,dude as integer


Psub Yeah()

EndPsub Testing as float



Function Cool_Floats(x as pointer)
      result=45.4
      dude#=int(666.4)
EndFunction Result as integer,dude as float


Function Cool_Floats2(X)
      result=45.4
;      dude#=666.66
EndFunction Result as integer,dude$ as string


Function Cool_Strings(X)
      result=45.4
      dude$="Yeah"
EndFunction dude$,Result as integer

[/code]



And here's some more test code with AS Datatype screen in FUNCTION/PSUB headers.   Equally thrilling, but it's there if you want it..


[code]

   explicit on

  Dim a as integer
  Dim b as integer
  Dim c as float  
 
     
;   a,b=Cool()
;   print a
;   print b
   Dim MyPtr as pointer

  a,c#=Cool_Floats(MyPtr)
 
   print a
   print c#
   
   Sync
   waitkey
   

Function Cool()
      result=45.4
      dude=666
EndFunction Result as integer,dude as integer


Psub Yeah()

EndPsub Testing as float



Function Cool_Floats(x as pointer)
      result=45.4
      dude#=int(666.4)
EndFunction Result as integer,dude as float


Function Cool_Floats2(X)
      result=45.4
;      dude#=666.66
EndFunction Result as integer,dude$ as string


Function Cool_Strings_Input(InputString$ as string,SecondInputString as string)
      result$="45.4"
      dude$="Yeah"
EndFunction dude$,Result$ as string




Function Cool_Floats_Input(InputFloat# as float,AnotherInputFloat as float)
      result$="45.4"
      dude$="Yeah"
EndFunction dude$,Result$ as string



[/pbcode]
   
Title: Re: PlayBasic V1.64k WIP Gallery
Post by: Makeii Runoru on November 03, 2009, 10:04:56 PM
I like it. It's not really necessary, but you have to fill in all the holes if you intend to make a solid programming language, right?

I look forward to this new release, as it hardens the core of the code's syntax.

Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on November 03, 2009, 10:26:03 PM
QuoteI like it. It's not really necessary

    Well, that depends upon who you ask.   
 

Quotebut you have to fill in all the holes if you intend to make a solid programming language, right?

     Support for the optional "as datatype"  syntax,  is due to this convention becoming common place over the past years, so it makes sense to adopt such things into PlayBasic also.     So there's some universal similarities for people who come from a programming background.   


QuoteI look forward to this new release, as it hardens the core of the code's syntax.

      Rather than waiting for the finally upgrade to be released, you should be running the beta's as they're posted.   Other wise the final, will be a beta!

Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on November 04, 2009, 11:48:09 AM
  PlayBASIC V1.64k  Beta 12 - Passing Individual User Defined Types Into Functions .

      With the addition of being able to return individual UDT's from functions, then it makes sense to add the ability to pass Individual User Defined Types into Functions also.   This gives us two methods to move data between scopes.   You have the original container methods and now you can pass individual type buffers.  

      To declare an input param as individual UDT we use the VARIABLE as UDT declaration.   When you call this function, PB  expects this field to be a UDT bank.  The bank is then resolved to a pointer and pass through to the function internally.   So the UDT variable inside the function is actually UDT pointer.   So the local UDT has no container.  You're writing directly into this type data.   However,  When you pass a Typed array/Typed variable in,  your moving the entire array/list structure.



[pbcode]

   Type SomeObject
      x#,y#
      name$
   Endtype

   Dim Cool as SomeObject

   Cool = TestReturnUDTFromFunction(4444,555,"Bill")


   print "------------------------------"
   print "Show returned contents"
   print "------------------------------"
   print Cool.x#
   print Cool.y#
   print Cool

   Test_Pass_UDT_To_Function(Cool)


   Sync
   WaitKey
      


Function TestReturnUDTFromFunction(x#,y#,name$)

   LocalType = new SomeObject
   LocalType.x#=x#
   LocalType.y#=y#   
   LocalType.name=Name$

   print "------------------------------"
   print "Created Data"
   print "------------------------------"
   print LocalType.x#
   print LocalType.y#
   print LocalType.Name$
   print "This:"+STR$(Int(LocalType))

EndFunction LocalType as SomeObject




Function Test_Pass_UDT_To_Function(LocalType as SomeObject)

      // Manually chekc if this thing exists or not..
      if int(LocalType)

         ;  Yep so,  display the fields
         print "------------------------------"
         print "passed UDT bank"
         print "------------------------------"
         print int(localType)
         print LocalType.x#
         print LocalType.y#   
         print LocalType.Name   
      endif      
      
   
EndFunction

[/pbcode]



   Here's a quick reworking of the previous example,  this version features passing individual types in and out of user defined functions.  

[pbcode]

    setfps 60

   // declare our type structure   
    Type MyObject
            x#,y#
            radius
             deathtime
            colour
    EndType

   // declare & create our global LIST container to hold all our ships  
    Dim Ship as MyObject list


   // ==========================================
   // main loop
   // ==========================================

 Do

        Cls 0

         lockbuffer
              CurrentTime=Timer()
            for each  Ship()
               if CurrentTime<Ship.DeathTime
                        DrawShip(ship)
               else
                     Ship=Null
               endif   
            next
         unlockbuffer  


         if  spacekey()   ;Rnd(1000)>250
            // add 5 to the list container
            for lp=1 to 5
               Ship= SpawnNewObject()
            next
         endif


         print "Object count:"+Str$(getListSize(Ship()))

        Sync
 loop   



Function DrawShip(ThisShip as MyObject)
            circlec ThisShip.x#,ThisShip.y#,ThisShip.Radius,true,Thisship.colour      
EndFunction


Function SpawnNewObject()

   // NOTE!! - You MUST NEW the return type prior to reading or writing to it
   This = New MyObject

   This.x#=rnd(getscreenwidth())
   This.y#=rnd(getscreenHeight())
   This.Radius=rndrange(10,50)
   This.Colour =rndrgb()
   This.DeathTime=Timer()+rndrange(1000,2000)

EndFunction  This as MyObject

[/pbcode]



  Here a version that uses array handles/containers.  This is functionally the same as the version above, expect one Key difference.  The version above is passing the individual TYPEs in and OUT of the functions,  so inside the SpawnNewObject/drawMe functions, we can only access stuff in this stucture, we can't acccess the list that came from.  

   However in the  version bellow, we're passing the entire array (LIST) container.   This allows us to perform operations upon the passed LIST inside the , rather than just upon the single passed instance.    

[pbcode]

    setfps 60

   // declare our type structure   
    Type MyObject
            x#,y#
            radius
             deathtime
            colour
    EndType

   // declare & create our global LIST container to hold all our ships  
    Dim Ship as MyObject list


   // ==========================================
   // main loop
   // ==========================================

 Do

        Cls 0

         lockbuffer
              CurrentTime=Timer()
            for each  Ship()
                    // pass the SHIP list into the function as well as the death time
                   UpdateAndDrawShip(Ship(),CurrentTime)
            next
         unlockbuffer  


         if  spacekey()   ;Rnd(1000)>250
            // add 5 to the list container
            for lp=1 to 5
               // pass the Ship LIST into this function, so we can add stuff to it
               SpawnNewObject(Ship())
            next
         endif


         print "Object count:"+Str$(getListSize(Ship()))

        Sync
 loop   



Function UpdateAndDrawShip(ThisShip.MyObject,CurrentTime)
      if CurrentTime<ThisShip.DeathTime
         circlec ThisShip.x#,ThisShip.y#,ThisShip.Radius,true,Thisship.colour      
      else
         ThisShip=Null
      endif   
EndFunction




Function SpawnNewObject(This.MyObject)

   This = New MyObject

   This.x#=rnd(getscreenwidth())
   This.y#=rnd(getscreenHeight())
   This.Radius=rndrange(10,50)
   This.Colour =rndrgb()
   This.DeathTime=Timer()+rndrange(1000,2000)

EndFunction

[/pbcode]



Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on November 04, 2009, 10:17:05 PM
  PlayBASIC V1.64k  Beta 12b - Returning Local Arrays from Functions (Maybe).

      This afternoon I've been continuing my work on the Function Parser.   Now that most of the big issues are resolved, it should be possible to export a locally created array (an array dimmed inside a function), and return and assign it to another array().   Those with a keen eye will no doubt see why I was messing around with Array() operators a few days back :)  -  Anyway,  while it doesn't currently work,  ideally this could mean that you can dynamically create arrays.

      However, there's a catch (isn't there always),  exported arrays will be returned as their underlying bank handles,  these are use plain integer values.  Since the return isn't strongly typed (for flexibility here), it's going to be possible for you to leak arrays if you're not careful.

     Anyway, here's the current WIP snippet.  So far this parses correctly, but doesn't generate the runtime code for the array exporting.

[pbcode]

   Dim Table(0)
   
;   Table() = MakeTable(Size)

   print "Yep, i'm not dead"
   Sync
   waitkey


Function MakeTable(Size)
   // Declare and create our local array.  You'll need to DIM this manually
   Dim LocalArray(Size)
   
EndFunction LocalArray()         ;  Export local array from function
      
[/pbcode]


Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on November 05, 2009, 08:41:29 AM
  PlayBASIC V1.64k  Beta 12c - Returning Local Arrays from Functions (continued).

    Well, we can tick off another feature.  I thought this might take a little longer to get working, but it's really gone fairly seamlessly this time.  The implementation isn't complete mind you (only currently supports return integer arrays)  but the frame work is in now working.  Hopefully, there's no hidden drama's awaiting the implementation of the other array types.   But, anyway..


    So here's a basic functionality example... Not too exciting, but it shows the concept.

[pbcode]

   Dim Table(0)

   // show the initial array state
   print ConvertArrayToString(Table())

   // Make and return a array 15 elements in size.. The returned array
   // is written back into the Table() array.  When you make and assignment
   // like this,  it first undims the data in the destination array, then
   // stores the arrays bank in the dest.
   Table()=MakeTable(15)

   // show the initial array state
   print ConvertArrayToString(Table())

   // Make and return a array 25 elements in size.. The returned array
   // is written back into the Table() array.

   Table()=MakeTable(25)
   print ConvertArrayToString(Table())

   Sync
   waitkey
   


Function MakeTable(Size)
   // Declare and create our local array.  You'll need to DIM this manually
   Dim LocalArray(Size)

   for lp =0 to size
      LocalArray(lp)=rnd(50)
   next
   
EndFunction LocalArray()         ;  Export local array from function
      

Function ConvertArrayToString(Me())
   for lp=0 to getarrayelements(Me(),1)
      s$=s$+digits$(me(lp),2)+","   
   next
   s$=trimright$(S$,",")
EndFunction s$


[/pbcode]

Outputs..


00
19,14,06,19,44,17,35,47,49,47,48,19,33,22,33,01
07,45,45,46,39,22,29,20,33,46,01,45,06,46,37,06,00,46,05,50,49,40,31,40,00,03





Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on November 05, 2009, 11:57:46 AM
  Here's another example.  This one is using a 1D array, to store 1D array handles in.   So we're conceptually creating functionality to resembles the  'arrays within arrays'.    To access the dynamically created arrays here we're using a manually declared redirection array via MakeArray.   So before we can access any array handles within TABLE() we need to, copy the array bank into our redirect array.   Once that's done, the array appears like any other.



[pbcode]


   setfps 100


   // ----------------------------------
  // Conceptual Array of Arrays
  // ----------------------------------


   Dim Table(100)

   // make a redirection array.  We'll use this it access the 'array banks' stored
   // with the TABLE() array.    We need this in this example since, Table is just
   // an integer array.
   MakeArray ints()       

   EndTime=timer()+1000*10

   do
      Cls 0


         if spacekey() or (rnd(100)>20)  and (Timer()<EndTime)
               Index=GetFreeCell(Table())
               Table(Index)=MakeTable(rndRange(10,20))
;               Flushkeys
         endif

   
         // press enter to randomly create an array and then store it's bank
         // table() array.  So we're making an 'lose' associate
         if EnterKey()=true or (rnd(100)>10)
            //      
            index=Rndrange(1,GetArrayElements(Table(),1))
            if Table(Index)            

                  ints()=Table(index)
                  Table(index) = 0  ;clear this handle from the array we used to remember them in               

                  Ints()=0            ; free this array buffer

;                  Flushkeys
            endif
         endif   
   

         // Display the arrays
         for Index=1 to getarrayelements(Table(),1)
            if Table(Index)            
               ints()=Table(index)
               print ConvertArrayToString(Ints())
            endif         
         next
   
      Sync
   loop


   Sync
   waitkey
   



Function MakeTable(Size)
   // Declare and create our local array.  You'll need to DIM this manually
   Dim LocalArray(Size)

   // Fill it full of stuff
   for lp =0 to size
      LocalArray(lp)=rnd(50)
   next
   
EndFunction LocalArray()         ;  Export local array from function
      

   // Convert array to
   
Function ConvertArrayToString(Me())
   for lp=0 to getarrayelements(Me(),1)
      s$=s$+digits$(me(lp),2)+","   
   next
   s$=trimright$(S$,",")
EndFunction s$




[/pbcode]



Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on November 06, 2009, 04:46:03 AM
    It now supports returning Integer/Float and String Arrays


[pbcode]

   print "Integers -----------------------------------------------"

   Dim Table(0)
   // show the
   print ConvertArrayToString(Table())

   Table()=MakeIntegerTable(15)
   print ConvertArrayToString(Table())


   print "Floats -----------------------------------------------"
   Dim Table#(0)
   // show the
   print ConvertArrayToStringF(Table#())

   Table#()=MakeFloatTable(5)
   print ConvertArrayToStringF(Table#())


   print "Strings -----------------------------------------------"
   Dim Table$(0)
   // show the
   print ConvertArrayToStringS(Table$())

   Table$()=MakeStringTable(7)
   print ConvertArrayToStringS(Table$())


   Sync
   waitkey
   



Function MakeIntegerTable(Size)

   // Declare and create our local array.  You'll need to DIM this manually
   Dim LocalArray(Size)

   for lp =0 to size
      LocalArray(lp)=rnd(50)
   next
   
EndFunction LocalArray()         ;  Export local array from function
      


Function ConvertArrayToString(Me())
   for lp=0 to getarrayelements(Me(),1)
      s$=s$+str$(me(lp))+","   
   next
   s$=trimright$(S$,",")
EndFunction s$




Function MakeFloatTable(Size)
   // Declare and create our local array.  You'll need to DIM this manually
   Dim LocalArray#(Size)

   for lp =0 to size
      LocalArray#(lp)=rnd#(50)
   next
   
EndFunction LocalArray#()         ;  Export local array from function
      



Function ConvertArrayToStringF(Me#())
   for lp=0 to getarrayelements(Me#(),1)
      s$=s$+str$(me#(lp))+","   
   next
   s$=trimright$(S$,",")
EndFunction s$




Function MakeStringTable(Size)
   // Declare and create our local array.  You'll need to DIM this manually
   Dim LocalArray$(Size)

   for lp =0 to size
      LocalArray$(lp)="Text:"+Str$(rnd(50))
   next
   
EndFunction LocalArray$()         ;  Export local array from function
      



Function ConvertArrayToStringS(Me$())
   for lp=0 to getarrayelements(Me$(),1)
      s$=s$+(me$(lp))+","   
   next
   s$=trimright$(S$,",")
EndFunction s$


[/pbcode]


Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on November 06, 2009, 09:36:09 PM
  PlayBASIC V1.64k  Beta 13 - Returning Typed Arrays & Lists from Functions.

    Well well,   this is getting a lot more interesting than just being able to return integer arrays dynamically.  Now we can return locally created float/string/ typed arrays and even Typed lists from within functions also.  

   When an local array is exported it's exported as the databank that represents this item in memory.    We can assign the bank indexes to a receiver array (MyArray() = SomeFunction() ),  or we can store them in an integer fields (as per the example above).

  If we do this, we can't access the data directly, we need to first create an array stub using MakeArray.  Then any time we want to access the data, we assign the array stub our bank index and hey presto, we're able to read write to the array.   It's not the prettiest solution, but it's something that works today!

    Here's a simple example.


[pbcode]

   Type Vector2D
            x#,y#
   EndType

   print "[Pass Typed Array============================]"
   Dim Dude(0) as vector2D
    MakeVectorTable2(Dude(),200)

   print "[Return Typed Array============================]"
   Dim Dude2(0) as vector2D
   Dude2().vector2d=    MakeNewVectorTable(45)

   print "[Return Link List==============================]"

   Dim MyList as vector2D list
   MyList()=    MakeNewVectorList(10)
   for each MyList()
         s$=str$(mylist.x#) +", " +str$(mylist.y)
         print s$   
   next

   
   Sync
   Waitkey


   

Function MakeNewVectorTable(Size)
   // Declare and create our local array.  You'll need to DIM this manually
   Dim LocalArray(Size) as Vector2D

   for lp =0 to size
      LocalArray(lp).x=rnd(50)
      LocalArray(lp).y=rnd(50)
   next
   
EndFunction LocalArray().Vector2D         ;  Export local typed array from function


Function MakeNewVectorList(Size)
   // Declare and create our local array.  You'll need to DIM this manually
   Dim LocalArray as Vector2D list

   for lp =0 to size
      LocalArray = new Vector2D
      LocalArray.x=rnd(50)
      LocalArray.y=rnd(50)
   next
   
EndFunction LocalArray.Vector2D         ;  Export local typed array from function

   
   

Function MakeVectorTable2(LocalArray().Vector2D,Size)
   // Declare and create our local array.  You'll need to DIM this manually

   Dim LocalArray(size) as Vector2D

   for lp =0 to size
      LocalArray(lp).x=rnd(50)
      LocalArray(lp).y=rnd(50)
   next
   
EndFunction         ;  Export local typed array from function


[/pbcode]
   
Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on November 06, 2009, 11:21:27 PM
    Here's a much more practical example that uses attached typed lists to store character inventories in.  So each character has it's own typed linked list attached.   This can go as deep as you like really and gets rid of the ugly dereferencing issues mentioned earlier in this thread...  
 

[pbcode]
; PROJECT : Inventory
; AUTHOR  : Kevin Picone
; CREATED : 11/7/2009
; EDITED  : 11/7/2009
; ---------------------------------------------------------------------

   SetFps 60

   type tInventory
         itemname$
   EndType


   // Declare a game object called of SHIP
   type tShip
         x#,y#
         speedx#,speedy#
         radius
         colour
         InventoryArray
   EndType      


   Dim Ship as tship list

   //  throw some ships randomly into the list so we're someting to look at
   for lp =1 to 20
      ship = new tship
      ship.x=rndrange(100,700)         
      ship.y=rndrange(100,500)         
      angle#=rnd#(360)
      ship.speedx=cos(angle#)
      ship.speedy=sin(angle#)
      ship.radius =rndrange(10,20)
      ship.colour =rndrgb()
      
      // Store the inventory arrays bank index, for later use      
      Ship.InventoryArray =CreateShipsInventory()
   next


   
   // This the items that characters can pick up.
   type tItem
         x#,y#
         Starttime,DeathTime
         Name$               ; name of the pick up item characters can pick up
         BoundingBoxShape
   endtype

   Dim Item as tItem list


   // create an array to hold the names of the inventory items that game character can pick up
   Dim ItemNames$(0)
   s$="Gold Bar, Silver Bar, Cricket Bat,20 cents,Commodore 64"
   NumberOfItems=SplitToArray(s$,",",ItemNames$(),0)
   

   
   ; ---------------------------------------------------------
   Do         // game LOOP
   ; ---------------------------------------------------------

      Cls 0
   
            ; ---------------------------------------------------------
            ; Show Items
            ; ---------------------------------------------------------
            CurrentTime=timer()
            if CurrentTime>SpawnNewItem
                  SpawnNewItem=CurrentTime+rndrange(50,250)

                  Item = new tItem
                  Item.x = Rnd(GetScreenWidth())
                  Item.y = Rnd(GetScreenHeight())
                  Item.StartTime=CurrentTime                  
                  Item.DeathTime=CurrentTime+2500                  

                  Item.name =ItemNames$(int(rnd#(NumberOfItems-1)))                     

                  width=gettextwidth(item.name)
                  height=gettextheight(item.name)

                  x1=-(Width/2)
                  x2=(Width/2)
                  y1=0
                  y2=(Height)
                  Item.BoundingBoxShape =NewBoundingBoxShape(x1,y1,x2,y2)


            endif
            
            for each Item()
                  timepast#=currenttime-item.StartTime
                  scaler#=(TimePast#/(item.DeathTime-item.StartTime))            
                  Scaler#=1-cliprange#(scaler#,0,1)
                  ink rgbfade($ffffff, scaler#*100)
                  centertext item.x, item.y, Item.name
                  if CurrentTime>Item.DeathTime
                        item=Null
                  endif                                                
            next            
            ink $ffffff

            ; ---------------------------------------------------------
            ; Move Ships
            ; ---------------------------------------------------------
            for each Ship()
                  x#=ship.x#+ship.speedx#
                  y#=ship.y#+ship.speedy#
                  if x#<10 then  x#=10 : Ship.SpeedX*=-1            
                  if x#>790 then  x#=790 : Ship.SpeedX*=-1            
                  if y#<10 then  y#=10 : Ship.Speedy*=-1            
                  if y#>590 then  y#=590 : Ship.Speedy*=-1            

                  ship.x=x#
                  ship.y=y#

                  ; chekc if ship hit an inventory item
                  ShipHitItem(Ship())
                  
                  circlec x#,y#,ship.radius,true,ship.colour

                   ShowShipInventory(ship())
                  
            next   

      Sync      
   loop



Function CreateShipsInventory()
   Dim MyInventory as tInventory list
EndFunction  MyInventory.tInventory



Function ShowShipInventory(ThisShip.tship)
   Makearray Inventory.tInventory

   Inventory() =ThisShip.InventoryArray
   
   x#=thisShip.x#
   y#=thisShip.y#
   th=gettextheight("Y")
   ink $ff0000
   for each Inventory()
         centertext x#,y#,Inventory.itemname      
         y#+=th   
   next
   ink $ffffff

EndFunction


   // Check if this ship hit any of the inventory items

Function ShipHitItem( ThisShip.tship)
   Makearray Inventory.tInventory

   x#=thisShip.x#
   y#=thisShip.y#
   radius#=thisShip.radius

   // Seed the Inventory array with this objects List    
   Inventory.tInventory =ThisShip.InventoryArray

   // run through and global ITEMS list and see if this ship hit it
   for each item()

         if circlehitshape(x#,y#,Radius#,Item.BoundingBoxShape,item.x,item.y)
               // Add a new item to this objects inventory
               inventory =new tInventory
               // set it's name
               inventory.itemname$=Item.name$

               // release this item
               FreeCurrentItem(Item())
               continue
         endif
         
   next


EndFunction



Function NewBoundingBoxShape(x1,y1,x2,y2)
      ThisShape=NewShape(4,4)
      SetShapeVertex ThisShape,0,x1,y1         
      SetShapeVertex ThisShape,1,x2,y1         
      SetShapeVertex ThisShape,2,x2,y2         
      SetShapeVertex ThisShape,3,x1,y2         

      SetShapeEdge ThisShape,0,0,1
      SetShapeEdge ThisShape,1,1,2
      SetShapeEdge ThisShape,2,2,3
      SetShapeEdge ThisShape,3,3,0
      refreshshape ThisShape
EndFunction ThisShape




Function FreeCurrentItem(ThisItem.tItem)
      if GetshapeStatus(ThisItem.BoundingBoxShape)
            deleteshape ThisItem.BoundingBoxShape
      endif
      ThisItem=null
EndFunction
[/pbcode]

Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on November 11, 2009, 08:19:15 AM
 PlayBASIC V1.64k  Beta 14 - Post Fix Support On User Defined Functions.

    This additions bring user functions into line with the internally bound & native VM operations.   In other words you can declare a user function name and use the # and $ symbols at the end.    The parser doesn't use this are the return prototype though,  the return type still comes from the what exported after the EndFunction statement.  


[pbcode]

   Print Yeah$(45)
   print SomeOtherFunction#(11.22)
   
   Sync
   waitkey

Function Yeah$(A)
      This$="Yeah Function="+str$(a)
EndFunction This$
   
Function SomeOtherFunction#(ThisFloat#)
      Print Thisfloat#
      This#=Thisfloat#*10
EndFunction This#

[/pbcode]

  Note: Function name matching is explicit.  So if the function is declared with the post fix, then you can't just drop it, at least not now anyway.



  This also works on LinkDLL functions now..

 
[pbcode]

linkDll "Some.Dlll"

      TestFunction#(Param) alias "Something" as float
      TestFunction$(Param) alias "Something" as string

EndlinkDll

[/pbcode]

Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on November 13, 2009, 01:00:03 PM
 PlayBASIC V1.64k  Beta 15 - Yet Another Asteroid Clone.

    Been busy today with other real world stuff,  so tonight I thought i'd knock up a  demo rather than tinker with parser/compiler.    This one is yet another asteroids demo,  it's really just the first thing that came to mind (that didn't require artwork :) ) .  The Interesting thing is, that Asteroids is a game that's often discussed (ie. a common question I get) but I don't really recall seeing too many people get a demo up and running.  So I knocked this up.

    The demo doesn't actually use anything new in terms of rendering, it's just some alpha additive shapes on depreciated buffer (image blurring).   The only thing that makes it a 1.64K program  is in the code.    Which just uses some of the new features here and there.   It could be made to run it in V1.64I/V1.63LE but then there's no point posting it here.. :)

     So far the demo features player controls, basic asteroids and player firing, collisions and some particles.   Looks ok when running...


   YAAC - (Yet Another Asteroids Clone) Blog (http://www.underwaredesign.com/forums/index.php?topic=3258.0)




 
Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on November 15, 2009, 11:20:39 PM
 PlayBASIC V1.64k  Beta 16 - Exporting Pointers from PSubs.

   Functions and Psubs might look very similar on the surface, but internally they're very different.   Originally PlayBasic was only ever designed to be support the three basic data types,  Integer,Floats & Strings.    So a lot of PB runtime internals we're built around this assumption.   However, later on during development, Pointer support was added internally, then later (partly) exposed to the user.    Of course, when we tack new functionality in, this has  habit of creating some potential issues with older parts of the core parser & code generation.  

  One such omission  was that even though PSUB declarations allow pointer fields to be declared,  internally the code generator couldn't meaningfully resolve such operations.    So the generator would spit out opcodes that didn't make sense to the runtime, resulting  in a Unknown  Opcode error upon execution.    While here we're focusing upon export pointers, importing them and also cause similar issues.

  So resolving these situation is the my current focus.  So far,  basic pointers can be exported with 'type mismatching' applied.


[pbcode]

   explicit true

   Dim Cool as integer
   
   Cool =Test_Sub_PointerReturns()


   Dim MyPtr as pointer
   
   MyPtr =Test_Sub_PointerReturns()

   print Cool
   print Int(MyPtr)

   Sync
   waitkey
   




Psub Test_Sub_PointerInputs(A as integer pointer)
      print int(a)   

EndPsub


Psub Test_Sub_PointerReturns()

      a=45554
      print int(a)   

EndPsub A as integer pointer




[/pbcode]


Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on November 17, 2009, 11:46:30 AM
 PlayBASIC V1.64k  Beta 16 - Pointer & Buffer support from PSubs.

    Today's update continues on from the last update.  These changes allow pointers to be passed into Psubs.  Beyond that that support for importing and exports type and array buffers has been added.


[pbcode]


   Type Vector2D
         x#,y#
   EndType

   Dim Cool as Vector2D
   
   Cool.x#=11.22
   Cool.y#=22.33
   

   Dim Buffer1(50)
   Dim Buffer2(50)


   print "return array from sub"
      for lp=0 to 1000
         buffer1()=TestArrayReturnFromSub(100)
      next
      

   print "return array from function"
      for lp=0 to 1000
         buffer2()=TestArrayReturnFromFunction(200)
      next
   
   
    TestUDFPassToFunction(cool)
   
    TestUDFPassToSub(cool,9999)
   
   Sync
   waitkey
      



Function TestArrayReturnFromFunction(size as integer)

   Dim MyArray(size)
   Dim lp as integer
   for lp=0 to size
      MyArray(lp)=1000+lp
   next

EndFunction  MyArray()



psub TestArrayReturnFromSub(size as integer)

   Dim MyArray(size)
   Dim lp as integer
   for lp=0 to size
      MyArray(lp)=1000+lp
   next

EndPsub  MyArray()




function TestUDFPassToFunction(this as vector2d)

   print "Passed UDT buffer into function"
   print THis.x
   print THis.x
;
EndFunction

Psub TestUDFPassToSub(this as vector2d,qqqq as integer)

   print "Passed UDT buffer into sub"
   print THis.x
   print THis.x
   print qqqq

EndPsub




[/pbcode]


 Download BETA

 [plink]Get PlayBasic V1.64k Beta 16 (http://www.underwaredesign.com/forums/index.php?topic=1150.msg21493#msg21493)[/plink]


Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on November 19, 2009, 02:33:03 PM
 PlayBASIC V1.64k  - Debugger Syntax Highlighting Tech Test

     While this is currently not a built in feature,  Here I'm just prototyping a new approach for doing 'Syntax Highlighting', with the hope that it'll make it's way into PB in the not too distant future.  The prototype is actually written in PlayBasic V1.64k beta 16.

     The goal of this test, is to see how fast I can get the parsing and rendering in pure PlayBasic.   The current results are very pleasing,  with the loader being able to process over 5000 lines of source in around 250 milliseconds.    And the render being able  to render basic page of text as between 200->300 FPS, and in some cases even higher.  

     I don't imagine it'll stay this quick as I introduce more features, but this is light years ahead of the previous approach.  Although it's nowhere near as refined atm..  :)


     


Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on November 20, 2009, 07:49:26 AM

PlayBASIC V1.64k  - Debugger Syntax Highlighting Tech Test (continued)

      Worked pretty much through the night and most of the day trying to get the tech demo to a point where it incorporates all the main features found in the IDE without costing the earth.    So this version pays more attention to the formatting and support multi line comment segments, which the original tech didn't.   

     Performance wise it's really no slower than it was,  at yet as least.  Obviously the more aware it is, the more work it has to do at runtime.  And by aware I mean it's knowledge of what the code actially is.    Ideally an IDE version could be aware of the data type of things you type and help you as you enter code.   Much like the current IDE does, but just taking that to a higher lever.   But I digress,  at the moment what i'm looking at first is building a version that could used in the debugger view.   Hopefully with some type of 'hover' support.  So you can see the contents of variables, just by hovered over them... But, lets not get too far ahead of ourselves.   

      Anyway, here's the second piccy of the bare bone tech demo running in PB1.64k.   This time i've doubled the size of the test source to over 10000 lines.. Which as expected doubles the parse time to around 525 milliseconds, but it's still running in the 200->300fps range. (approximately 3 to 5 millisecond refresh)),  which is nothing compared to some of these tools..


Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on November 20, 2009, 01:34:46 PM
 PlayBASIC V1.64k  Beta 17 - Fixes Array Passing Inside With PSUBS.

   It seems that with the updated condensed function compiler in Beta #16 (and prior I think), there's been an omission with the importing array buffers into PSUB's.    But this has been fixed in beta #17.


[pbcode]

   Type That
            x,y,z
   EndType

   Dim Dude as That
   Dim DudeArray(0) as That

   Dude.x=666
   DudeArray(0).x=7777

   print dude.x
   Test1(11,Dude())
   Test1(11,DudeArray())

   Dim IntArray(100)
   Dim FloatArray#(100)
   Dim StringArray$(100)
   IntArray(0)=44
   FloatArray#(0)=11.22
   StringArray$(0)="CCOOL"


    TestInteger(a,IntArray())
    TestFlt(a,FloatArray#())
    TestStr(a,StringArray$())

   Sync
   waitkey



Psub Test1(a,This.That)
      print "Exists"
      print This.x
EndPsub



Psub TestInteger(a,This())
      print "Exists"
      print This(0)
EndPsub

Psub TestFlt(a,This#())
      print "Exists"
      print This#(0)
EndPsub

Psub TestStr(a,This$())
      print "Exists"
      print This$(0)
EndPsub

[/pbcode]  

    it's good to see this was picking up by all the diligent beta testers out there ..  :)

Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on November 24, 2009, 05:37:04 AM

  PlayBASIC V1.64k  Beta 18 - Tweaks For Geeks

     Starting work on this revision a couple of days back,  the objective is to bring some environmental functions into the user command set.   So ideally you'll be able query the runtime (VM) environment (about your  programs state), which in turns means being able to write routines that are more generic.    This presents a few problems I hadn't bargained for.    From the how these things will appear to the user and the core implementation.   So rather than progressing at a steady pace, work has been revolved around following the instruction set chain down the rabbit hole.   Which has uncovered a few issues that need to be altered in order to progress. 

     Long story short,  so rather than focusing on what i'd intended upon doing, i've been revisiting some of the core instructions trying to wedge in the needed functionality.   This can presents some bigger than expected problems.  Generally if you add more instructions , this often adds more weight to the execution.    It's not as cut and dry and one operation does one thing.  As the general purpose opcodes are used throughout the language. So adding a bit of weight to this hardly used operation (or so you assumed), can end effecting something you didn't really expect.. 

     To counter this i've been trying to reduce the instruction set, but without removing functionality.   This means quickly rethinking the implementation of a number of embedded core operations.  What i've been looking for is effectively ways to remove/short cut some existing opcodes, to make space for needed additions.  Unfortunately, this sounds easy in principal, but getting it working, just isn't going  smoothly.  So far, all i've succeeded in doing in either making it much slower,  or making it die in bizarre ways.     
 
    erm.. what fun...

Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on November 24, 2009, 10:58:00 PM
 PlayBASIC V1.64k  Beta 18 - Tweaks For Geeks (Cont.)

    Had a rather lovely evening of tweaking/removing/rewriting some 5 or 6 year old code fragments.   The good news is that Beta 18 is working again, but i'm not too sure I can fit what I actually need into the instruction set without making some really major changes :( .

   Given we're talking about working  on VM#1 here,  i'm really not too fond of the idea of giving a major overhaul now,  given the VM2 runtime makes it completely obsolete..   While my objective at start of the 1.64K upgrade was to give PB1.64K as much functionality as possible,  but there are limits to how far i'm willing to go with it.. 

   The changes thus far have given Beta 18 a little more bite for you buck though.   A good example of this can be seen when running the Debugger Syntax Highlight prototype (http://www.underwaredesign.com/forums/index.php?topic=3264.0) in Beta 18, as compared with Beta 17.    Beta 18 can load & parse the 20000 plus lines of source 200 milliseconds faster than beta 17...  Same program, but only difference is the revisited runtime.     

   
Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on November 25, 2009, 12:58:34 PM
 PlayBASIC V1.64k  Beta 18 - CallFunction (Dynamic Function Calling)

     All of the recent work has been edging towards adding more operations that allow greater freedoms in user code.   What CallFunction  does, is it allows you to call  a function in your code by name.   While it's early days as yet (i've only just got a simplified version working in fact)  this functionality will hopefully allow users to write routines that can dynamically call other routines, without the user having to explicitly code it.  

     This type of functionality tends to pop up when we need to write code that's going to be used between many projects,  while still remaining generic.  A good example that comes to mind, would be a GUI library.   Where the GUI could be written to call a particular user defined action(s).   For example, if the GUI detected a button click, the GUI could check if the  button has an associated function (something the designer could to do at design time).  This function be the code that react to this button click.  So the programmer wouldn't have to explicitly add code to react to the button click

      Another situation could be in collision detection.   If each object had a user associated 'destroy function', then the collision code could be simplified into a more generic version.  This would allow the programmer to add more object types and destroy methods, without having to patch them into all the collision routines.     So basically it's going to be used a call back mechanism.  

      Anyway, so far all that's working is calling simple subs without and parameters or returns..   In the example bellow it's calling Psubs,  in the future I hope to be able to support user defined functions/psubs and bound functions.    But first things first...

       This example randomly calls either the functions bellow by name.


[pbcode]

  Print "Dynamic Function Calling"
 
   Dim FunctionNames$(1)

   
   FunctionNames$(0)="Test"
   FunctionNames$(1)="ThisOtherTest"


   Do
      Cls 0
         for lp=0 to 10  
            Index=Rnd(1)   
            CallFunction FunctionNames$(Index)
         next
      Sync
   loop
   


Psub Test()
   Print "Callled Test Sub"

EndPsub


Psub ThisOtherTest()

   Print "Called The Other Test Sub"

EndPsub




[/pbcode]

Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on November 25, 2009, 04:20:14 PM
 PlayBASIC V1.64k  Beta 18 - CallFunction (Dynamic Function Calling) (cont.)

    While it's only a few hours later, but the implementation has progressed a bit further already.   The current version supports user defined functions and Psubs.   Moreover function calls support basic parameter passing.  I suspect that only Integer/Float & strings will work (at this point), but I haven't actually tested anything else.  Arrays certainly won't work, but pointers and individuals types may work.      It doesn't returns though.

    Given the function is called by NAME,  this means function name has to be resolved back to it's internal pointer.    This process was pretty slow in the initial version.  With the following benchmark (bellow) taking some 750 milliseconds to execute 10,000 times.    However, with a bit of a rethink i've been able to trim this back to a much more respectable 22.8 milliseconds for 10,000 calls.  
 
    In the final you'll be able to call functions by name, or by index, which gets rids of the need to search for the function by name.  So that'll be a fair be quicker I'd imagine.


[pbcode]


  Print "Dynamic Function Calling"
 
   Dim FunctionNames$(3)

   
   FunctionNames$(0)="Test"
   FunctionNames$(1)="ThisOtherTest"
   FunctionNames$(2)="Test"
   FunctionNames$(3)="ThisOtherTest"

   MaxTests=10000

   Do
      Cls 0
      
         frames++

         t=timer()
            for lp=0 to MaxTests
               CallFunction FunctionNames$(lp &3)
            next
         tt1#+=(timer()-t)
         print tt1#/frames

         CallFunction "Yeah",45
        
      Sync
   loop
   





Psub Test()
;   Print "Callled Test Sub"

EndPsub


Psub ThisOtherTest()

;   Print "Called The Other Test Sub"

EndPsub


Function  Dude()
;   ink $ff0000
;   Print "Called The Other Test Sub"
;   ink $ffffff

EndFunction


Function  Yeah(x)

   ink $ff0000
   print "Running Function"
   Print x
   ink $ffffff
EndFunction

[/pbcode]


    Quickly tested calling via Function Index..  And it'll execute the equivalent loop in about 3.8 milliseconds.  So clearly, if via index will be the best of the options, If speed is a concern.   CallFunction will always be slower than native function call though.  
 
Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on November 26, 2009, 04:30:46 PM

PlayBASIC V1.64k  Beta 18 - CallFunction (Calling Bound DLLs)

    Still working on getting this feature to work as robustly as possible.   Which means being able to call the all thenative function types, those being Psubs, Functions and bound (via linkDll) functions.

    There's a few big issues that need error trapping, in particular with calling bound (dll) functions.  Namely the issues resolve around there being no way to really screen the CallFunction parameters at compile time.  So this stuff can get lightly sanitized at run time. So if you try and shovel the wrong parameters types into a function call, then there's not too much I can do about it.  So in this case you should expect it die...   There's some type matching but that's about it.

    The other drama is managing whats returned from the various types of function calls.  Which of course all work differently and return data differently also.   Which is further compounded by not actually knowing the return type of the function.   Since this can't be resolve during compliation.. Which is turning out to be a tricky one.   My gut feeling is that it'll only returning Integer/Floats and Strings though, unless something magical happens. 

Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on November 27, 2009, 10:55:54 AM
 PlayBASIC V1.64k  Beta 19 - CallFunction (Dynamic Function Calling)

   As of BETA 19, the call function command works with User defined Functions, User Defined Psubs and Linking DLL's -   However the implementation in this version can only pass basic  parameters (Integers/Floats & Strings), and can not return anything from the called function.      

   Here's a basic example..  


[pbcode]

  Print "Dynamic Function Calling"
 
   Dim FunctionNames$(3)

   FunctionNames$(0)="Yeah"
   FunctionNames$(1)="SubYeah"

   

   Do
      Cls 0
      
   
            for lp=0 to 1
               Name$=FunctionNames$(lp)
               CallFunction Name$,Rnd(100),rnd#(200),Name$
            next
         
      Sync
   loop
   




Function  Yeah(x,y#,Name$)
   ink $ff0000
   print "Running Function ["+Name$+"]"
   Print x
   Print y#
   ink $ffffff
EndFunction



Psub  SubYeah(x,y#,Name$)
   ink $00ff00
   print "Running Psub ["+Name$+"]"
   Print x
   Print y#
   ink $ffffff
EndPsub




[/pbcode]

Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on November 29, 2009, 10:23:38 PM
 PlayBASIC V1.64k  Beta 20 - FunctionExist /FunctionIndex

   These couple of functions are just to round off the CallFunction operation above.  I'd hope hope what they do is pretty self explanatory, but just in case...    FunctionExist allows us to check if a Function Name exists,  FunctionIndex lets us pre-calc the internal index of the function.   The latter is so that you can store the index to the function rather than it's name.  

   Calling by name is fine if you're only calling the function a small amount, but the 'name searching' overhead sure adds up with you call them lot (1000's of times).    So in those situations it'd better to pre-calc the functions index, then call it using the index,rather than it's name..


[pbcode]

   print "function Exist"
   print FunctionExist("Yeah")
   print FunctionIndex("Yeah")
       CallFunction FunctionIndex("Yeah"),222,333.44,"This is working"
        

       Sync
       Waitkey


Function  Yeah(x,y#,z$)

   ink $ff0000
   print "Running Function"
   Print x
   Print y#
   Print z$
   ink $ffffff
EndFunction



[/pbcode]
 

Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on November 30, 2009, 01:45:16 PM
  PlayBASIC V1.64k  Beta 20 - limited Optional Parameter Support For Command Calls

   Optional parameter support is one of those features that's been on the design doc for what seems like years, so it's long overdue.  This feature, allows us to drop from the trailing parameter(s) from certain internal commands calls.  When you drop the parameter, the command uses the 'internal default' for this parameter.  These will be the mostly settings for a command.  

   At this point, it only supports commands and not internal functions.   But obviously that'll come after i've weeded the bumps out.     The main issue with adding it is how the internal parameter matching and moreover how the parameter passing works in vm.   So it's a little messy getting it work and there are a number limitations, but it should be ok for the most part.  

    Bellow is a tiny example of new change.  Spot the difference ?  - it's pretty subtle.. Notice the CLS commands parameter is now optional.   If left out, the command defaults to BLACK (rgb(0,0,0))..   Which reminds a very long winded discussion we had with somebody about what the 'default' colour of Cls should be.   But anyway..


[pbcode]

   Do   

      Cls

      print "Optional CLS "
   
      box 100,100,200,200,true
   
      Sync
   loop

[/pbcode]


Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on November 30, 2009, 05:47:10 PM
  PlayBASIC V1.64k  Beta 20 - limited Optional Parameter Support For Command Set Function Calls

    Continuing on from where the last post left off,  now we have optional parameter support in both internal commands and internal functions.   So far there's only one function with a optional and that's the MID$() function.     The Length parameter is now optional in this function,  if you leave it out it'll default to a length of 1.

     So it's like the MID() function (they are different !) except MID$(String$,pos) returns a single character as a string.  Where MID(String,pos) returns the single character (it's ASCII value)  as an integer.    So MID() is the  equivalent of asc(mid$(String$,pos,1)) in old school BASIC.  


[pbcode]


   Do   

      Cls

      print "Optional Parameters in Commands"
      
      box 100,100,200,200
   
      circle 400,400,50
      
      

      print "Optional Parameters in Functions"
      a$="Hello"

      for lp=1 to len(a$)
            print mid$(a$,lp)         ; notice the length is missing, it defaults to one now
      next
      
      Sync
   loop




[/pbcode]  

 

 Benchmark

  Does dropping an optional parameter wins us some speed ?  -   Well, lets check...  

[pbcode]
   MaxTests=10000


   a$="      Hello        "

   Do

         Cls 0
         frames++

         t=timer()
            for lp=0 to MaxTests
               b$=trim$(a$," "+chr$(9))
            next
         tt1#+=(timer()-t)
         print tt1#/frames


         t=timer()
            for lp=0 to MaxTests
               b$=trim$(a$)
            next
         tt2#+=(timer()-t)
         print tt2#/frames

      Sync
   loop
[/pbcode]

   
    Both loops execute at virtually identical speeds.  So no...  Why ? -  Well,  just because the parameter is optional, this doesn't mean nothings being passed into the function.    While you may not have explicitly sent anything in, behind the scenes the compiler is outputting the code to pass the 'default' parameter for you.  So the operation is the same in the output code.    
 
 
Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on December 02, 2009, 10:44:35 PM
  PlayBASIC V1.64k  Beta 21 - Optional Parameter For User Defined Functions

    I doubt this comes as any great surprise,  as it's a bit of no brainer that I'd be adding optional parameter support to User Defined Functions (& Psubs) next.      Adding this one requires a little more tinkering than the internal stuff.  Mainly because the pre-parser has to decipher the input parameters (and what they mean), beyond that,  it's just matter tweaking up the user function matching to generate the optional parameters in the function call.    

    So far the first stage (the parsing) is basically working,  ie

[pbcode]



      MyFunction(100,200,300)
      

      Sync

      waitkey
      


   ; Declare A,B and C as an optional that defaults to 1
Function  MyFunction(a,b,c=1)

      print a
      print b
      print c

EndFunction

[/pbcode]




Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on December 03, 2009, 02:22:39 PM
  PlayBASIC V1.64k  Beta 21 - Optional Parameter For User Defined Functions (Continued)

  Well, we can just about tick another feature off the to do list.   The current version has optional integer parameter support up and running for user defined  functions.     Currently the parser only supports the explicit syntax in the function header, rather than the 'As Datatype"  method.   Bit it's at least working..        
 
  To declare a parameter as being optional, this parameter uses the equals sign to declare this parameters default value(or string) in the function header.  

   ie.
[pbcode]

Function IncreaseVariable(ThisVariable, IncreaseAmount = 1)
     Result =ThisVariable +IncreaseAmount
EndFunction Result

[/pbcode]

  In the example,  this user defined function is basically the equivalent of the INC operation.   If the user calls this function and omits the second param, then PB uses the functions default value for this parameter (which is 1).   So calling it with only one parameter, will add one to the input variable.   but if you use two params, then it's use what value you passed in for IncreaseAmount


  Limitations,

     * optional parameters can only be simple types. (Integers, floats and strings)
     * optional parameters must be the last parameters.  So you can't currently mix optional parameters in between fixed parameters.   So this   Function Dostuff(A , B=10 , C)  is not supported.


  Sample,

[pbcode]


      print Add()            ; Use all the optionals
      print Add(10)         ;  u8se last 2 optionals
      print Add(10,20)      ;  use last optional
      print Add(10,20,30)   ;  no optional parameters, so all parameters are manually sent

      Sync
      WaitKey


Function Add(a=50,b=100,c=200)
      A+=b+c      
EndFunction a

[/pbcode]


Outputs,

Quote
350
310
230
60




 Samples

    Had  few issues adding float + string support, but the follow examples of what's currently running in the latest build of beta 21
 
[pbcode]

      print TestStrings("Hello")

      Sync
      WaitKey


Function TestStrings(a$,b$="World")
      result$=a$+" "+b$
EndFunction Result$


[/pbcode]

   Outputs Hello World



   Here's a version testing floats.  


[pbcode]

      print TestFloats("Flt")
      print TestFloats2("Flt")

      Sync
      WaitKey


Function TestFloats(a$,b#=123.456)
      result$=a$+"="+str$(b#)
EndFunction Result$


 ; Notice the mismatched assignment in the cast (B# = integer constant)
Function TestFloats2(a$,b#=123)
      result$=a$+"="+str$(b#)
EndFunction Result$

[/pbcode]

  outputs
Quote
Flt=123.456
Flt=123.0




    The pre-parser had to be updated to handle both of these cases... but they're working ok now..




Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on December 06, 2009, 05:43:42 AM
  PlayBASIC V1.64k  Beta 22 - Optional Parameters In User Defined Functions/Command Calls

     This addresses an omission in the previous beta, where functions that didn't return a result couldn't use optional parameters,  which has since been addressed.   The only thing missing now (off the top of my head) is Psub support for optional parameters.  


[pbcode]

      Dude 10,20,30
      Dude 10,20

      a=MyFunction(100,200)

      Sync
      WaitKey


Function Dude(a,b,c=55)
      print "DUDE"
      print a
      print b
      print c
EndFunction


   ; Declare A,B and C as an optional that defaults to 1
Function  MyFunction(a,b,c=234,f$="Yeah",g=true)
      print "My Function"
      print a
      print b
      print c
      print f$
      aa=a+b+c
EndFunction aa

[/pbcode]




 Psub Support


[pbcode]


      SubDude 10,20
      SubDude 10,20,30
      SubDude 10,20

      a=MyFunction(100,200)

      Sync
      WaitKey


Function Dude(a,b,c=55)
      print "DUDE"
      print a
      print b
      print c
EndFunction



Psub SubDude(a,b,c=55)
      print "DUDE as a SUB"
      print a
      print b
      print c
EndPsub



   ; Declare A,B and C as an optional that defaults to 1
Function  MyFunction(a,b,c=234,f$="Yeah",g=true)
      print "My Function"
      print a
      print b
      print c
      print f$
      aa=a+b+c
EndFunction aa


[/pbcode]






   
Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on December 06, 2009, 10:48:09 PM
  PlayBASIC V1.64k  Beta 22 - SortArray (string)
 
   Dropped this old chestnut back in.  While it works, it's not particularly quick.


[pbcode]


   Size=10
   Dim name$(Size)
   for lp=0 to size
      name$(lp)=ReadData$()   
   next
   
   
   SortArray name$(),0,size
   
   for lp=0 to size
      print name$(lp)
   next
   Sync
   waitkey
      
   Data "zack","wolf","kev","andy","michelle","dogs","tess","c64","zynaps","dudes","Alpha"

[/pbcode]
Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on December 09, 2009, 11:53:21 PM
  PlayBASIC V1.64k  Beta 24 - More As DataType Support in Function/Psub Declarations
 
    Since we've added support for the As DataType convention in function declarations for  Variables/Pointers/Types it stands to reason that some people will want to declare Arrays in such a fashion also.   While this is a little problematic given how the prototyping pass works in PB,  it should be doable. But the solution just isn't pretty.

 Sample,

[pbcode]
   Dim Stuff(100)
    RandomizeIntegerArray(Stuff(), 100)

   Sync
   waitkey
   
Function RandomizeIntegerArray(Me() as integer,  Max as integer)
   For lp =0 to Getarrayelements(me())
      Me(lp) =rnd(Max)         
   next
EndFunction

[/pbcode]


 Continued

     Due to running into a few catch 22's lately in how the pre-pass #1 prototyping and Pass#2 used to work, I've ended up biting the bullet and making the prepass that little bit smarter.  Turned out to be fairly straight forward as virtually all the code have been previously written, it just need to be unified better.    Which just means that the pass#2 doesn't need to bother about the parameters anymore, so expression solver won't have a fit with the extra info in the function declaration.


[pbcode]

   Dim Stuff(100)
   RandomizeIntegerArray(Stuff(), 100)

   Dim Stuff#(100)
   RandomizeFloatArray(Stuff#(), 100)


   Dim Stuff$(100)
   RandomizeStringArray(Stuff$(), 100)

   Sync
   waitkey
   
   
Function RandomizeIntegerArray(Me() as integer,  Max as integer)
   For lp =0 to Getarrayelements(me())
      Me(lp) =rnd(Max)         
   next
EndFunction


Function RandomizeFloatArray(Me() as float,  Max as integer)
   For lp =0 to Getarrayelements(me#())
      Me#(lp) =rnd(Max)         
   next
EndFunction


Function RandomizeStringArray(Me() as string,  Max as integer)
   For lp =0 to Getarrayelements(me$())
      Me$(lp) =str$(rnd(Max))         
   next
EndFunction




[/pbcode]



 Lists

  Updated the Function parameter parser to support the As UDT LIST convention.   So you can declare the parameter as a Typed LIST the same way as it's created.    The function doesn't really need to known it's a LIST, it's more for the user.    Internally a typed variable and typed list are the same structure underneath.  So they're interchangeable, it's just doesn't make list management enabled.    Moreover, a typed variable is really a 1D typed array.  


 List Declaration Example.

[pbcode]

   Type Pos
         iValue
         fValue#
   EndType

   Dim Numbers1 as pos list
   Dim Numbers2 as pos list
      
   AddValuesToLIst_LH(Numbers1(),10,2000)
   AddValuesToLIst_LH(Numbers2(),10,2000)
   
   print getlistsize(Numbers1())
   print "Size:"+Str$(getlistsize(Numbers1()))
   for each numbers1()
      print numbers1.ivalue
   next

   print "Numbers #2"
   print "Size:"+Str$(getlistsize(Numbers2()))
   for each numbers2()
      print numbers2.ivalue
   next

   Sync
   waitkey
   
     ; Long hand declarations using AS DataType  LIST
Function AddValuesToLIst_LH(Me as pos list, Count as integer, Max as integer)
   For lp =0 to Count-1
      me = new pos
      Me.ivalue =rnd(Max)         
   next
EndFunction


     ; short hand declarations, same as above!
Function AddValuesToLIst_SH(Me.pos, Count, Max)
   For lp =0 to Count-1
      me = new pos
      Me.ivalue =rnd(Max)         
   next
EndFunction

[/pbcode]





   
Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on December 12, 2009, 09:53:38 PM
PlayBASIC V1.64k  Beta 24b - Optional Parameter Tweaks

   Optional parameters can now use either literal constants or language constants.    Although, you can't use User Defined constants at this time.  


[pbcode]
   TestOptionalStringConstant("Testing")
   TestOptionalStringConstant()
   
   Sync
   waitkey

Function TestOptionalStringConstant(Yeah$=PlayBasic$)
   print Yeah$
EndFunction
[/pbcode]

Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on December 23, 2009, 11:11:45 AM
PlayBASIC V1.64k  Revision 2 - Beta 2 - Function Prototype Tweaks

    For the next few days/week I'll be working on a tweaking up revision #2 of the V1.64K package.  Namely trying to address some issues that should been discovered during the beta testing, but weren't..  So here we are again..

     Anything not solved during this testing phase, won't be looked at until the next major update 1.64L


Function Prototyping


[pbcode]
   Dim Array(1)
   Dim Array#(1)
   Dim Array$(1)

   Type Pos
         x,y,z
   EndType

;   Yeah=1
   Global State=true

   for State=0 to 1
      print "Test:State="+str$(State)
      print Stuff_int()
      print Stuff_int2()
      print Stuff_float()
      print Stuff_float2()
      print Stuff_Str()
      print Stuff_Str2()
   next
   
   Sync
   waitkey
   waitnokey
   
   cls 0      
   for State=0 to 1
      print "Test:State="+str$(State)
         Array()=Stuff_intarray()
         print GetArrayElements(Array())
         Array$()=Stuff_Strarray()
         print GetArrayElements(Array$())
      #break
   next
   
   Sync
   waitkey
   waitnokey


Function Stuff_INtArray()
   if State
      Dim TestArray(100)   
      exitfunction TestArray()
   else
      Dim TestArray(200)   
   endif
EndFunction TestArray()



Function Stuff_FltArray()
   if State
      Dim TestArray#(100)   
      exitfunction TestArray#()
   else
      Dim TestArray#(200)   
   endif
EndFunction TestArray() as float



Function Stuff_StrArray()
   if State
      Dim TestArray$(102)   
      exitfunction TestArray$()
   else
      Dim TestArray$(202)   
   endif
EndFunction TestArray() as string




Function Stuff_INt()
   a=1
   Yeah=2   
   if State
      exitfunction a
   endif
EndFunction Yeah



Function Stuff_INt2()
   a=1
   Yeah=2   
   if State
      exitfunction a
   endif
EndFunction Yeah as integer




Function Stuff_Float()
   a#=1
   Yeah#=2   
   if State
      exitfunction a#
   endif
EndFunction Yeah#

Function Stuff_Float2()
   a#=1
   Yeah#=2   
   if State
      exitfunction a#
   endif
EndFunction Yeah as float


Function Stuff_Str()
   a$="1$"
   Yeah$="2$"   
   if State
      exitfunction a$
   endif
EndFunction Yeah$


Function Stuff_Str2()
   a$="1$"
   Yeah$="2$"   
   if State
      exitfunction a$
   endif
EndFunction Yeah as string

[/pbcode]



 
Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on December 30, 2009, 08:13:57 AM
PlayBASIC V1.64k  Revision 2 - Beta 3 - Final Clean Up

    Well, given there hasn't been a single bit of user feedback, it looks like Beta 3 will be the release version.   Apart from correcting a bug with constant floats as optional parameters, this one has a few tiny changes.  Namely this version adds the ability to enable Vsync in windowed modes.

   A couple of points though, if you enable it, then the refresh rate will be whatever the users desktop refresh rate is.   So don't assume it'll be the same as yours, and secondly, the users machine might not be able to vsync.. ie card doesn't support it or  user has disabled it in the driver..



[pbcode]

   img= MakeGridPatternImg(32,4,32,4,10,rgb(120,130,140),rgb(150,150,150),rgb(210,200,200))


   //

   StartTime=Timer()
   Do

      TileIMage img,Xpos,0,false

      TimePast=Timer()-StartTime

      Xpos-=1

      if spacekey()
         ScreenVsync 1-getScreenVsync()
         flushkeys
      endif

      Text 0,0,"Vsync:"+Str$(GetScreenVsync())
   
      Sync
   loop   



Function MakeGridPatternImg(GridWidth,GridWidthStepX,GridHeight,GridHeightStepY,Segs, BG_RGB, SubDiv_RGB, HighLight_RGB)
   oldRgb=Getink()
   oldSurface=GetSurface()
   w   =GridWidth   *Segs   
   h   =GridHeight   *Segs   

   ThisIMage=NewImage(w,h)
   RenderToImage thisimage
   Cls BG_RGB

   ink SubDiv_RGB
   lockbuffer
   For Ylp=0 to H-1 step    GridWidthStepX   
      For Xlp=0 to w-1 step GridHeightStepY
         line 0,ylp,w,ylp                     
         line xlp,0,xlp,h                     
      next   
   next   
   unlockbuffer

   ink HighLight_RGB
   lockbuffer
   For Ylp=0 to H-1 step GridHeight
      For Xlp=0 to w-1 step GridWidth
         line 0,ylp,w,ylp                     
         line xlp,0,xlp,h                     
      next   
   next   
   unlockbuffer

   ; restore old surface and ink colour
   RenderToImage OldSurface   
   ink oldrgb
EndFunction ThisImage




[/pbcode]

Title: Re: PlayBasic V1.64k WIP Gallery
Post by: micky4fun on December 30, 2009, 12:06:26 PM
Hi Kevin

QuoteNamely this version adds the ability to enable Vsync in windowed modes
now that sounds good to me , did try a few things in window mode in previous PB versions and seem to be quite glitchy ,
so this will be a great help i think

mick :)
Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on December 30, 2009, 12:23:46 PM
   yes & no.   It's nice to have a vsync'd window..  But, this comes with a cost.  
Title: Re: PlayBasic V1.64k WIP Gallery
Post by: stevmjon on January 07, 2010, 12:53:45 AM
to kev

thanks for vsync in window mode.

i avoided using vsync in my game because i wanted full screen & window to run the same. i experimented for a while to figure out the smoothest comprimise, but now i can run both in vsync. i am very happy.

was it difficult to impliment this into playbasic? could you have done this in older versions?

what is the 'cost' of having vsync in window mode?  my computer shows no difference in speed in fullsceen to window mode (i mean calc speed, not fps).

  thanks stevmjon
Title: Re: PlayBasic V1.64k WIP Gallery
Post by: kevin on January 07, 2010, 01:33:44 AM
 [plink]Read Here (http://www.underwaredesign.com/forums/index.php?topic=1182.45)[/plink]