PDA

View Full Version : LEFT$ and RIGHT$ not fully functional



ReneMiner
03-02-2024, 02:44
I will not say it's buggy or broken but actually Powerbasic (and a few other basic languages probably too) accepts negative values for Left$ or Right$ -
and i was certain thinbasic would work this way too.
Anyway i try to avoid LEFT$ and RIGHT$ the standard way, in thinbasic i prefer LENF, LEFTF$ and RIGHTF$. For module production i created myself some macros and macro-functions that will avoid the unnescessary creation of local strings and these work as powerbasic Left$ and Right$




MACRO StrLen(p1)=PEEK(DWORD, STRPTR(p1)-4)

MACRO StrLeft(p1,x)=IIF$(x=0, "", IIF$(StrLen(p1)<ABS(x), p1, PEEK$(STRPTR(p1), IIF(x > 0, x, StrLen(p1)+x))))

MACRO StrRight(p1,x)=IIF$(x=0, "", IIF$(StrLen(p1)<ABS(x), p1, PEEK$(STRPTR(p1)+ IIF(x > 0, StrLen(p1)-x, ABS(x)), IIF( x > 0, x, StrLen(p1)+x))))


MACRO FUNCTION InLimits(p1,p2,p3)=IIF((p1<p2) OR (p1>p3),0,-1)
' alike thinbasic- keyword between



When using StrRight(s, -1) it works is as Right$(S, Len(s) + (-1))

string s = "thinBasic"
MsgBox StrRIGHT(s, -5) & $CRLF & Strleft(s, -4)

output would be:

thin
Basic




Btw. Function
data = Choose and Choose$(Index, firstVal, secondVal, thirdVal,...,ELSE lastVal )
works in PB with an ELSE for a final choice that will be used if no matching element for index.
I would appreciate if thinbasic had it too.


I have some idea that could reduce Select Case-crimes & times and also provide a feeling of "i am in control".

Imagine to make use of Enum (and Bits if developed ) and apply a node where to store and to bring up some new kind of conditional selective code-block execution that will work using only such values that are present as clearly ordered enumerations or as bitwise flagged status-information. Constants that leave not the slightest doubt about the datatype to use or what kind of test is to perform. It were an approach that would change any kind of these for certain purposes created lists of entitled values ( not to name them "key-value-pairs" ) from their currently static apearance to become objects that allow the programmer to combine the value-lists with required functionalities that are -created once- reuseable within any project.






Enum Bits MyFlags As [Byte|Word|Dword]


flagging bits are keeping track of states, there is no signed type needed for it. Actually when logic ops are performed the presence of negative numbers is irritating while for enumerations it always makes sense to use a signed type even the values below 0 are not in valid range - we can use such values - where we instantly know when we see it: this does not belong here, so it has a special meaning.

To flag just bits - its more simple to use Byte-arrays as Len-Fixed string,When we just set bits by theirs names the bits values are relative. We dont need to know the arithmetic value when all bits have names and we can make the handling easier when we unify all bitflags to be adressed from bit 0 of byte 0 to bit 7 and continue with Byte 1.



Enum Bits MyFlags * <nBytes>

That will not limit bitwise flagging-enumeration to the sizes of the available datatypes. because It were not a real array and we wont use bytes but bits, it were great to have a few features built-in to enums. A few standard methods as
.toString or .List( %Enum_ListMembers | %Enum_ListValue | %Enum_ListFullDetail ) ,
.TypeOf , .SizeOf for Enums and for Bitflags something as enumName.Byte[<byteNumberHi> [To <byteNumberLo>]]. toBin$ | .toHex$
.toConfig/toIni/ (.json?)

.ExportToInclude(): uses the enumerations name for the filename, creates a tBasicI-file probably under App_Path & "thinair\Users\_shared\Inc\Enum"
writes the code to create the enum including all the elements names and values as ready to include-portion of code. thinair should have a few more tabs where codebrowser & explorer are, giving access to "Tools", a local code-archive (for snippets and even such ready-to-include-stuff) to manage the sample-scripts etc.

Many objects( not enums only ) as classes, udts, ... should have like an ExportToInclude-method implemented

And enums that are not bitflags could come with some methods.
Example here a built-in functionality to the enumerations that allows to exeute conditional branches of code by compairing any expression





Enum hungryPet As Long ' the type remains valid for all members and
Cat ' the name "hungryPet" should be recognized as a datatype when it is preceeded
Dog ' by keyword AS, should "hungryPet" alias Long cause a conflict because "hungryPet" is
Pony ' name of a module class i suggest to enforce a naming rule e.g. enum-type-names should be created
Horse ' always the same way. it can be just as placing the char t and an underscore in front of the enumname
GuineaPig ' to retrieve its type-name. such simple approach will bring up trouble soon. "tEnum_" could prevent from it
Elephant ' it would allow function-parameters, declarations and udt-elements to
Lizard ' explicit use a certain type and have an exact defined range of valid parameters.
End Enum

' this were the function/method, built in to all enumerations.
' a simple comparison test. subject to test: <expr>

hungryPet.Test <expr> expr is compared to...
anything the enumeration "knows about" means all its members and theirs values
we know for every member if it matches sExpr,
if member


hungryPet.Result( Cat )


hungryPet.Result( Dog )


hungryPet.Result( Elephant )


hungry.Pet.Result( PONY )


hungryPet.Result( HORSE )


hungryPet.Result( LIZARD )


hungryPet.Result( GUINEA-PIG )


hungryPet.Result( NOTHING )


hungryPet.EndTest



Enum myColorpalette As tRGB '?


Not really.

ReneMiner
04-02-2024, 10:03
somehow the means ae disappeared in the above.
It was intended that after


<enumname>.Test(expr)
'the term
<enumname>.Result( <enums_Membername> )

was internally already compared to the passed <expr> in method <enumname>.Test() and the enum "knows" already what members are matching.
From

<enumname>.TestBits(<expr>)

it were the procedure TestBits() that would not simply return the control back to the running program but continue to parse and check where is a matching member until
<enumname>.EndTest, is encountered. If no match in the code then nothing to do. But if a match (whatever evaluates to true) is present, return back the program-control to the core engine to perform what follows after the matching statement.

thincore would execute from there and runs maybe into another <enumname>.Result...(member) before .EndTest. - what invokes an enumerations procedure again

Control is with the enums result-method now and it will do the same as before - just parse for its next matching result or the .EndTest what will cause the table of results to be cleared and without a result is nothing to check nor compare.

In the end that allows kind of multiline-CHOOSE with possibly multiple matching branches to execute but it will influence the path of execution without to select case and if-constructs. It were interesting the moment bit-flagging appears for the enumerations and we actually can test twice per member of enum bits-group
<name>.TestBits( <expr> )
tests (<enumname>.Member And <expr> ) =<expr>
<name>.ResultAND(member) ' <= if true <enumname>.test will return program control to core

...
...
executed until a method of the enumeration is causing to check the previous tests results...
test (<enumname>.Member And Not <expr>) = 0
<name>.ResultNOT(member) <= maybe not true, <enumname>ResultNot will not return control and parses until another .Result...() or .EndTest is found.

<name>.EndTest()

Petr Schreiber
04-02-2024, 21:18
Dear Rene,

you are always full of great ideas. If I may, it would help me personally if you could keep 1 idea per 1 thread - it would be then easier to discuss.

Topic Left$ / Right$ and negative values - I like the request to support negative value
Topic Choose / Choose$ - I think Switch$ could also benefit from the ELSE proposal

Apologies, but I think I did not understand 100% your last code example with `hungryPet` - could you please elaborate? Even with the additional explanation the combination of methods and specific parsing is a bit unusual construction (not following any existing pattern), but I think I got it wrong.

What would be the meaning of the following code, please?


Enum myColorpalette AstRGB



Thank you,
Petr

ErosOlmi
05-02-2024, 22:19
I was writing the same thing Peter suggested: one simple post for each request.

I will never read posts so long, please understand me (positive way): my time is precious, your time is precious, please respect it.
You always have great ideas but sometimes expressed with too much complexity, difficult to follow.

Please ask one simple question about one simple request possibly in few lines. If more requests, please make different posts.
Otherwise (I'm pretty sure), no-one will read it and no-one will reply.

Ciao
Eros

ErosOlmi
07-02-2024, 09:29
First question of Renč in first post
If understood well, Renč is not regarding RIGHT$ and LEFT$ that are already working with negative numbers since the beginning of thinBasic language.
LEFT$ and RIGHT$ accepts negative length and work like requested. It is just not documented.

Renč is asking to have LEFTF$ and RIGHTF$ (the FAST version of LEFT$ and RIGHT$) to have the same option to specify negative length
Will check but should definitely possible to add possibility to have negative length without breaking backward compatibility


Second question of Renč in first post
Is about to add an ... ELSE ... final branch in CHOOSE / CHOOSE$ / SWITCH ...

I like the idea, and I will check what I can do.
I need to consider how to do it without slowing down too much parsing because at every possible step parser has to check the presence of ELSE ... but should not be too slow

Regarding other requests, I need to read them better, actually to time but during week end I will.

Ciao
Eros

ReneMiner
10-02-2024, 03:01
Dear Rene,

...
What would be the meaning of the following code, please?


Enum myColorpalette AstRGB



Thank you,
Petr


missing a space, intended was

Enum myColorpalette As tRGB

but thats the second step already. First it were useful to apply a type to an enumeration at all. - all members are of the same type and if it were too difficult
i have always weired ideas how to solve that.
The advantage of an enumeration to represent a specific datatype were, we could limit a couple of things against wrong usage. Imagine your enumeration
is like a small piece out of billions of numbers.
As water for example is no more water below 0°C and it will evaporate when boiling at 100°C.
The valid range for water is clearly defined from 1 to 99. Now my function is a teapot and the parameters are the cups. When i just place cups to fill with liquid- i don't know what people will fill in there. Maybe coffee, sulfuric acid or lava. when i define the parameters to be filled with the members of an enumeration of water




Enum Water As Integer
melting = 1
from_refrigerator =7
cool = 15
ok_to_take_a_bath = 21
hot_shower = 36
not_funny_to_shower = 44
killing_legionella = 56
death_to_many_germs = 69
perfect_for_coffee = 78
almost_cooking =89
just the limit = 99
End Enum

Function make_Tea( Liquid as Water, Optional Sugar ) As hot_served_timekiller

'...

Imagine WATER is an Alias of "Integer". Water on the right of equal is an integer value and preceeded by AS you could - as you can in thinbasic with any variable - dim something as -whatever it is.

Like

Dim funnyName as Long

now you can

Dim anything as funnyName


it is not actually mandatory to enforce from core that params must be members or in range of an enum. It is the support of programmers that not just
know : ouch- there is an integer required but see exactly what is the integers meaning and what is a valid range for this integer. For thincore it will not
make a difference if the parameter-types are long, string or water

I suppose an enum is STATIC CONST ? I mean all members will stay in the group - but could more values -perhaps due to loading data from another source -
get added to an Enum after End Enum ?

it were a fresh wind in the basic seats if we had this



Enum validVolumeSetting As Byte, Base 0 'assumed default is 1-based
' 0 is usually the "NONE"-member of any Enum to prevent from empty enums
Mute
VeryQuiet
Silently
Whispering
EarTickles
Humming
Mumbling
'... getting noisier and noisier
End Enum

Sub audioplay( byval sTrack as String, Mandatory Byval volume As validVolumeSetting, Optional byval Stereo As Boolean )




Mandatory were the keyword to enforce that only values in range of Enum are passed - or RTE :D

And for the typing (as dataType-stuff): what if an Enum had a current value? I mean it were a strict ranged variable and we had one place free
for exactly that Enums datatype when we replace the Keyword "ENUM" for just a second in your minds by "UNION".
All members join the same size of data , are grouped already under an UDT that is actually a virtual type-placement upon the members of an array.
when now the udt_element-placements - in order of appearance - are interpreted as index, then the value is from that array but the memory of this UNION remains unused...

I think when "Enum Bits" or "Bitflags" gets developed there is somewhat as logical OR as well as AND NOT leading to new combinations that have no names yet. Someone might want to store his favorite flagging-combo and load it and where would he put this number to have the value ready when its needed?
In an empty, exactly fitting place right in the collection of possible values. It were a provided variable that can take the value of 1 member of an enumeration. We say hey enum Dogs, pick poodle! and the value of dogs.poodle is the current at the union. for bitflags were not only inclusion - what we are used to by passing parameters combined with the OR-operator.

Well, i think flags should have both : the inclusion and the exclusion side to be compared.
Otherwise we end up with something that works as logic as Windows-Styles and ExStyles do