PlayBasic V1.64M Beta 6 - Compile Time Improvements
The updated font library is done now, but before tackling the next big thing, i've been picking through the command set looking for an those obvious small omissions & tweaks. This in turn, has set off a chain of events that has found me spending most of the day updating the compilers re-solver abilities. Over time, this part of the compiler has become far less functional then it originally was. Some of this seems to be caused from the push towards changing the underlying runtimes, and how it now handles math +string functions. After really looking at the pre-solver, the only logical option was to dive in kick it into shape. Which has meant a lot of testing basically.
One good thing that's come of the the re-write (apart from the better pre-solve support) , has been taking a much closer look see at some of the compilers string & token functions. Many of which haven't been touched for years, so with a little bit tinkering i've been able to dramatically improve the speed of that library. Many of the core functions in the compilers string library are now over 20 times faster. Granted this is not something you're really likely to really notice at compile time, but as your code gets larger, the more important these types of changes are to compilation speed.
The following test snippet, is demo'ing the resolve ability. In case you're not sure what this actually is ? - Well, it just means that when the compiler see's certain built in functions being passed constants, it can solve these functions during compile time, rather than exporting the code. So the runtime doesn't have to perform the calculation, as the compile just stores the answer.
A good example of a solvable function would be something like,
The
Cos(45) function in this code can solved during compliation so the only code this expression generates is
Print 0.707107
Some ugly test code ,
// Compile Time Replace functions
constant Replace_TEST1$ =replace$("Hello Bill","Bill","World",1,false,false)
constant Replace_TEST2$ =replace$("Hello Bill",autocaps$("BILL"),"World",1,true,false)
constant Replace_TEST3$ =replace$("Bill BILL bill bIll",autocaps$("BILL"),"Dude",1,true,false)
print Replace_TEST1$
print Replace_TEST2$
print Replace_TEST3$
Show()
// Compile Time InString functions
constant Instring_TEST1 =Instring("Hello World","World",1,true)
constant Instring_TEST2 =Instring("Hello World","world",1,true)
constant Instring_TEST3 =Instring("Hello World",autocaps$("world"),1,false)
print Instring_TEST1
print Instring_TEST2
print Instring_TEST3
Show()
// Compile Time String functions
constant AutoCaps_TEST$ =autocaps$("this is a bit of text")
constant Lower_TEST$ =lower$("LOWER CASE TEXT")
constant Upper_TEST$ =Upper$("upper case text")
constant Flip_TEST$ =Flip$("Flipped Text")
constant Make_TEST$ =Make$("Hello",5)
constant Insert_TEST$ =Insert$("Hello World","Nice ",6)
constant Digits_TEST$ =Digits$(123*1000+456,8)
constant ASC_TEST =asc("a")
print AutoCaps_TEST$
print Lower_TEST$
print Upper_TEST$
print Flip_TEST$
print Make_TEST$
print Insert_TEST$
print Digits_TEST$
print ASC_TEST
Show()
// Compile Time BIN & HEX
constant BIN_TEST$=bin$(255)
constant HEX_TEST$=hex$(255)
print BIN_TEST$
print Hex_TEST$
Show()
// Compile Time VAL() pre-solves
; solve as integer
constant iVal_Test1=Val(" 123.456 ")
constant iVal_Test2=Val(" 123.456 ")
; as float
constant fVal_Test1#=Val#(" 123.456 ")
constant fVal_Test2#=Val#(" 123.456 ")
print iVal_Test1
print iVal_Test2
print fVal_Test1#
print fVal_Test2#
Show()
// Compile Time CutLeft$() + CutRight$() pre-solve
constant CutL_Test1$ = CutLeft$("Hello World",5)
constant CutR_Test1$ = CutRight$("Hello World",5)
print CutL_Test1$
print CutR_Test1$
; solved at runtime
t$="Hello World"
print CutLeft$(t$,5)
print CutRight$(t$,5)
Show()
// Compile Time Pad$() pre-solve
constant PadTest1$ = Pad$("Hello World","-",0)
print PadTest1$
Show()
// Compile Time STR$() pre-solves
constant StrTest1$ = str$(-123)
constant StrTest2$ = str$(123.001)
print StrTest1$
print StrTest2$
Show()
// Compile Time ASC() pre-solve
print StrTest1$
print StrTest2$
Show()
Function Show()
Sync
WaitKEY
waitnokey
cls
endfunction
PlayBasic V1.64M Beta 6b - optional Params support in pre-solver
This working away at the pre-solver, which is pretty boring stuff but it can't all be fun and puppy dogs. The following example is using the compile time features to format a date. Not that most useful or complete examples but it'll do as an example.
constant Date$=autocaps$("01 AUG 2010")
#if (Instring(Date$,"01 ")=1)
constant TodaysDate_1$ = replace$(date$,"01 ","1st ")
#else
#if (Instring(Date$,"02 ")=1)
constant TodaysDate_1$ = replace$(date$,"02 ","2nd ")
#else
#if (Instring(Date$,"03 ")=1)
constant TodaysDate_1$ = replace$(date$,"03 ","3rd ")
#else
#if (Instring(Date$,"21 ")=1)
constant TodaysDate_1$ = replace$(date$,"21 ","21st ")
#else
constant TodaysDate_1$ = replace$(date$," ","th ",1,true,true)
#endif
#endif
#endif
#endif
constant TodaysDate$ = replace$(TodaysDate_1$," ",",")
print TodaysDate$
sync
waitkey
This outputs
"1st,Aug,2010". The interesting thing about this chunk of code is that it's almost entirely resolved at compile time. So the actual output code the runtime is executing is basically this (depending upon the input date) would be something like this...
Print "1st,Aug,2010"
sync
waitkey
If you're wondering why this type of stuff is useful to the end programmer, well it allows us to switch sections of the code IN/OUT at compile time. So we can use flags in our code to tell the compiler how built certain bits our program, or even exclude or modifity it.
One common usage would be when you're building game is that you can add some compile time logic to change the loading process, or include /exclude title screens , debug code , based upon the type of the compile you requested.
PB has a built in constant called
PBCompileMode. This constant is set to different values depending upon what build mode you selected. If you're testing your code from the IDE (pressed F5), then you can embedd logic in your code that's only visible when you're testing it. If you build an stand alone exe (f4), the compiler could set to ignore a section of code.
#if PBCompileMode=0
print "Running from the editor"
print "put my debug code into the game"
#else
print "Code in the final game"
#endif
SInce the #IF #ELSE #ENDIF logic is executed during compilation, then compiler outputs two differs bits of code depending upon the compile mode constant.
If you select F5 (Running your game from the IDE) it'd output..
print "Running from the editor"
print "put my debug code into the game"
if you selected to build an exe (f4) it'd output
print "Code in the final game"
So when we build our EXE, the compile completely ignores the DEBUG code.. The beauty here is that is done for us at compile time. We don't have to switch it on to build our final game...
PlayBasic V1.64M Beta 7 - Download
PlayBASIC V1.64M