I was trying to convert a "numeric" value into a character value at work and had an error thrown which suggested that I had mismatched brackets in my assignment statement(s). Having tried the same thing here at home where I'm running RC42 to check the exact wording of the error the statements (as I recall them at least) and they compile without any issues.
At work I'm running (from memory) RC39 - just checked the .asm file - at work it is RC09!
Has this "issue" been fixed in the many releases since RC09? Or have I mis-remembered what I was doing during my cycle ride home? {Probably the latter!}
LetChrData(DataIn)=Chr(Data(DataIn))'Failed in RC09 giving mismatched brackets errorPrintChr(Data(DataIn))' worked in RC09 and did what I was trying to achieve
Guess it is time to update my work installation...
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
That first line looks pretty wacky. Probably because I don't know what "Data" and ChrData are. Are these possibly arrays or strings with DataIn being an index?
Data is an array of 255 bytes, ChrData referred to an array of 6 bytes and yes DataIn is my index.
I hadn't realised that "Data" was a reserved word. I will ensure that is changed on Monday when I'm next at work. And probably change DataIn to DataIndx to make it clearer for myself (and others) too.
I was curious that the error raised was "mismatched brackets" when the bracketing seemed not to be mismatched.
Last edit: mkstevo 2021-03-19
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
The OS would be macOS Mojave. I will have to try again at work on Monday to see if I can provoke the same error. As I said earlier, it was more the "unexpected" error message that confused me.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I hadn't thought so, but it was a few days ago now. Of course, on getting the error, I re-wrote the code which did what I was aiming for so didn't put a whole lot of thought into what was happening, just cursed that it wasn't working. Though I still found the error message to be a little misleading, which is why I thought I would bring it up.
Although I have multiple copies of the code I was working on, I tend to save a new copy as I progress from the current "working" version to the next stage. As the code didn't work, I had to modify it and almost certainly didn't save it in the "non-working" stage. It is entirely possible I didn't remember exactly what I had typed, but I did double, triple check the brackets and am sure they weren't mis matched.
In fairness, printing the "chr" is probably a better method anyway. But I have to move it from one array to another as subsequent requests for more information overwrite the original values.
I'm thinking that what I'm doing is actually some way beyond my very limited skillset, but we're very quiet at work at the moment and I'm using my time swatting up on this propriety communication protocol to see if I can implement it in our products.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
So. This morning I thought I would check to see if I could reproduce the error I was having. I could, so I made notes of what I had done and then attempted to update my macOS install here at work from RC09 to RC42 (the most recent available).
Could I get the installation from my home iMac to work here at work? Could I 'eckers like. No matter what I tried, I kept getting a message that said there was an error in "utils.bi" with a hard coded path which is a directory path on my home machine:
Aborting due to runtime error 10 ("illegal instruction" signal) in /Volumes/Mojave/Users/mkstevo/GreatCowBasic/sources/utils.bi::GETBYTE()
I checked dozens of things, but the only way I could remedy this was to recompile gcbasic.bas on this machine. I can't imagine that these paths are intended to be hard coded into the gcbasic executable but having spent all morning shouting at the screen and swearing loudly, this did fix it, nothing else did, including downloading RC42.rar from SourceForge, replacing the directory and all contents with all downloaded files then copying in ONLY the gcbasic executable compiled at home. Re-compiling gcbasic here at work was all that cured this odd runtime error.
However. I still get the same error(s) listed.
DimRecvData(255)DimNewValueAsWord'The values are loaded from a serial receive routine which places the bytes returned into the array RecvDataLetRecvData(3)=Chr(RecvData(3))'Gives an error on compile
RC09:
Great Cow BASIC (0.98.07 RC09 2020-04-20 (Darwin 64 bit))Test_401.gcb (256): Error: Brackets do not match upTest_401.gcb (256): Error: Invalid variable name: RECVDATA(3)Test_401.gcb (256): Error: Variable RECVDATA(3) was not explicitly declared
RC42:
Great Cow BASIC (0.98.07 RC42 2021-02-27 (Darwin 64 bit))Test_401.gcb (256): Error: Brackets do not match upTest_401.gcb (256): Error: Invalid variable name: RECVDATA(3)Test_401.gcb (256): Error: Variable RECVDATA(3) was not explicitly declared
On both RC09 and RC42:
LetRecvData(3)=RecvData(3)-48'Compiles, no errors.
Also on RC09 and RC42:
DimRecvData(255)DimNewValueAsWord'The values are loaded from a serial receive routine which places the bytes returned into the array RecvDataPrintChr(RecvData(1))'Compiles, no errors.PrintChr(RecvData(2))'Compiles, no errors.PrintChr(RecvData(3))'Compiles, no errors.LetRecvData(3)=RecvData(3)*100'Compiles, no errors.LetRecvData(2)=RecvData(2)*10'Compiles, no errors.LetNewValue=RecvData(1)+RecvData(2)+RecvData(3)'Compiles, no errors.
The issue seems to be the assignment of the character value into the array rather than the "Chr" conversion itself?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
If this is entire program then I cannot preproduce.
I do not know. Your chip, If #option explicit is set, if Chr() is redefined somewhere, What asm was produced (did the optimiser create a single byte variable as the element number is hardcoded and the only element specified in the array therefore the array was not needed )? What code was on line 256 ? Were other array elements used? Were other Were other array elements used with a variable for the element address.
I know this... . This BADBRACKETs error message is ONLY issue when parsing the array element.
So, I really need the code. But, this is odd.
#chip16f18855#optionExplicitDimRecvData(255)DimNewValueAsWord'The values are loaded from a serial receive routine which places the bytes returned into the array RecvDataLet RecvData(3) = Chr(RecvData(3)) 'Givesanerroroncompile
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I could not for the life of me figure out why, all things now being equal, this compiled at home, but not at work.
The difference is the SubRoutine.
At home I was placing the command "in line". At work I was placing the command where it was positioned, in the middle of a Sub, deep into some nested "If...Then" and inside a "Repeat...End Repeat" routine.
Here is a minimum program showing the problem which I hope can be reproduced:
OK. Adding Dim RecvData(3) to the Sub removed the error, but, whether that returns a value answer... I truly do not know, but, read on.
I have no idea what is truly going on. The use of the CHR() function returns a string. A string is ALWAYS two bytes long (as a minimum) #1 the length of the string #2 the first character.
So, RecvData(0) = Chr( RecvData(1) ) equates to RecvData(0) = 1 byte length, 1 byte of the ASCII code... oops two bytes into one byte does not go. So, in a vain attempt to keep compiling a variable called RECVDATA(0) is created. And, this is the real issue. The Error: Brackets do not match up is a red herring.
So, if adding Dim RecvData(3) resolves.. my guess is that the code is now a mess. And, sure enough if you look at the asm ... the code does not set RecvData(0) to anything... it calls FNCHR then goto to sleep....
The answer here. Prevent the assignment of a CHR() to a BYTE, the target variable needs to be a STRING.
Proof.
Changing the sub, as follows, is a lot easier to see what is happening. Replace the sub. Compile, then, search the ASM for myCharValue being set. myCharValue is created as a variable but it never gets set.
Sub TestSub Dim myCharValue as byte myCharValue = Chr( RecvData(1) )End Sub
Now change the sub as follows: My myCharValue is a string. Compile and search the ASM... and, myCharValue is being set.
Sub TestSub Dim myCharValue as string myCharValue = Chr( RecvData(1) )End Sub
So, meanwhile while I ask Hugh to advise.... do not assign a CHR function result to a BYTE... in must be STRING.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
That would no doubt be why it worked when I used "Print Chr(RecvData(1))".
I have been able to get my program working as I wanted, using the "Print Chr(RecvData(1))" method, it was more that the mis-match brackets error didn't match the real error.
I'd found that declaring the array inside the sub worked when I was trying to pare the program down to something that produced the error.
I was only pleased that I wasn't dreaming...
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
why declare the array in a sub?
as a beginner, I set everything at the start before any main code.
As a sub is usually called several times does it mean you can re dim an array in code?
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I normally don't declare anything in a sub. When testing the minimum possible program that showed the error, I noticed that declaring the array in the sub prevented the error being flagged - though as proven by Anobium the error was still present.
To clarify, making the declaration of the array inside the sub routine has be shown not to eliminate the problem, it merely masks it. The only correct method to convert a value using "Chr" is to ensure it is assigned to a string, not a byte.
As I understand it in GCB, all variables are treated as global and "declared" by the compiler only once, being essentially moved to the top of the program. {I may be wrong here!}
In Delphi (Pascal) it made much more sense to make declarations inside the procedure (sub). Variables declared inside a single procedure were only ever visible to that procedure, attempting to re-use the same variable name in any other procedure would result in an error when compiled. The variables had "Global" scope only if declared in the "Uses" clause at the top of the program (thus available to all procedures) or had "Local" scope if declared in the "Uses" clause within a procedure (thus visible only to that procedure - even if the same variable name was re-used in another procedure). Values could be passed between procedures with the procedural parameters - those parameters too needed to be tightly defined before they could be used. Global variables were as welcome in Pascal as "Goto" in BASIC. Ideally there would be no global variables.
Waving a magic wand, I would like to see "Local" and "Global" variables in GCB. Global variables can lead to either lots of differently named variables - to prevent one variable from overwriting another - or the danger of a variable being overwritten. Local variables can prevent this neatly. Probably better still would be correct program design and coding in the first instance!
Last edit: mkstevo 2021-03-23
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Showing my lack of understanding here, but I had thought that a "string" was an array, of byte values. Which is why I tried to use it as such in the first place.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
Me to.
That's how left.mid, right $ works.
you can rotate ie scroll a string as if it was an array.
using dim mystring as string doesn't size it if enough ram...255 bytes if plenty of ram ?
From help
String variables default to the following rules and the RAM constraints of a specific chip.
10 bytes for chips with less than 16 bytes of RAM.
20 bytes for chips with 16 to 367 bytes of RAM.
40 bytes for devices with more RAM than 367 bytes.
For chips that have less RAM then the required RAM to support the user define strings the strings (and therefore the RAM) will be NOT be allocated. Please reduce string size.
so steve I think you're correct
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
An array element is made up of a single element, that element is a byte (a single byte). Chr() returns a string - that is a minimum of two bytes. Two into one dont go.
The asm shows that my analysis is correct. I was trying to creating a variable, and, that variable has the brace..... hence, the incorrect error message.
The brace error message is the result of a much lower level issue... assigning a string to a byte.
If chr() was assigned the array then it would have worked.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I was not trying to suggest in any way what you found was incorrect, nor disputing that the returned value(s) from "Chr" require a minimum of two bytes to store it.
My ignorance was in making the assumption that a "byte" array was to all intents and purposes the same as a "string" array which I had imagined held an array of Ascii character byte values and nothing more.
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
I was trying to convert a "numeric" value into a character value at work and had an error thrown which suggested that I had mismatched brackets in my assignment statement(s). Having tried the same thing here at home where I'm running RC42 to check the exact wording of the error the statements (as I recall them at least) and they compile without any issues.
At work I'm running (from memory) RC39 - just checked the .asm file - at work it is RC09!
Has this "issue" been fixed in the many releases since RC09? Or have I mis-remembered what I was doing during my cycle ride home? {Probably the latter!}
Guess it is time to update my work installation...
Probably.... Try Rc42
Hi Stevo,
That first line looks pretty wacky. Probably because I don't know what "Data" and ChrData are. Are these possibly arrays or strings with DataIn being an index?
This now passes syntax with RC42.
Yet I see that "DATA" is a reserved word in the ReservedWords.dat file but I am not sure why it is reserved.
Last edit: William Roth 2021-03-18
Data is an array of 255 bytes, ChrData referred to an array of 6 bytes and yes DataIn is my index.
I hadn't realised that "Data" was a reserved word. I will ensure that is changed on Monday when I'm next at work. And probably change DataIn to DataIndx to make it clearer for myself (and others) too.
I was curious that the error raised was "mismatched brackets" when the bracketing seemed not to be mismatched.
Last edit: mkstevo 2021-03-19
A few questions....
What was the OS? If this was Windows then the source of the error message could be two different parts of the process.
Can you reproduce? As we should resolve.
Let me know about the OS being used.
The OS would be macOS Mojave. I will have to try again at work on Monday to see if I can provoke the same error. As I said earlier, it was more the "unexpected" error message that confused me.
I reverted to the current release Version of GCB and tried the following code
I am using Windows 10
GCB Version 0.98.06 2019-06-12 (Windows 32 bit)
This works as expected with no errors.
So even though DATA is a reserved word and should be renamed, it is likely not the source of the mismatch error.
Is it possible that one of the arrays is not correctly defined in the suspect code?
I hadn't thought so, but it was a few days ago now. Of course, on getting the error, I re-wrote the code which did what I was aiming for so didn't put a whole lot of thought into what was happening, just cursed that it wasn't working. Though I still found the error message to be a little misleading, which is why I thought I would bring it up.
Although I have multiple copies of the code I was working on, I tend to save a new copy as I progress from the current "working" version to the next stage. As the code didn't work, I had to modify it and almost certainly didn't save it in the "non-working" stage. It is entirely possible I didn't remember exactly what I had typed, but I did double, triple check the brackets and am sure they weren't mis matched.
In fairness, printing the "chr" is probably a better method anyway. But I have to move it from one array to another as subsequent requests for more information overwrite the original values.
I'm thinking that what I'm doing is actually some way beyond my very limited skillset, but we're very quiet at work at the moment and I'm using my time swatting up on this propriety communication protocol to see if I can implement it in our products.
Blinkin' 'eck! That was hard work.
So. This morning I thought I would check to see if I could reproduce the error I was having. I could, so I made notes of what I had done and then attempted to update my macOS install here at work from RC09 to RC42 (the most recent available).
Could I get the installation from my home iMac to work here at work? Could I 'eckers like. No matter what I tried, I kept getting a message that said there was an error in "utils.bi" with a hard coded path which is a directory path on my home machine:
Aborting due to runtime error 10 ("illegal instruction" signal) in /Volumes/Mojave/Users/mkstevo/GreatCowBasic/sources/utils.bi::GETBYTE()
I checked dozens of things, but the only way I could remedy this was to recompile gcbasic.bas on this machine. I can't imagine that these paths are intended to be hard coded into the gcbasic executable but having spent all morning shouting at the screen and swearing loudly, this did fix it, nothing else did, including downloading RC42.rar from SourceForge, replacing the directory and all contents with all downloaded files then copying in ONLY the gcbasic executable compiled at home. Re-compiling gcbasic here at work was all that cured this odd runtime error.
However. I still get the same error(s) listed.
RC09:
RC42:
On both RC09 and RC42:
Also on RC09 and RC42:
The issue seems to be the assignment of the character value into the array rather than the "Chr" conversion itself?
Post the source please. I need to get the error messages on the same line number.
If this is entire program then I cannot preproduce.
I do not know. Your chip, If #option explicit is set, if Chr() is redefined somewhere, What asm was produced (did the optimiser create a single byte variable as the element number is hardcoded and the only element specified in the array therefore the array was not needed )? What code was on line 256 ? Were other array elements used? Were other Were other array elements used with a variable for the element address.
I know this... . This BADBRACKETs error message is ONLY issue when parsing the array element.
So, I really need the code. But, this is odd.
Ahh...
The plot thickens...
I could not for the life of me figure out why, all things now being equal, this compiled at home, but not at work.
The difference is the SubRoutine.
At home I was placing the command "in line". At work I was placing the command where it was positioned, in the middle of a Sub, deep into some nested "If...Then" and inside a "Repeat...End Repeat" routine.
Here is a minimum program showing the problem which I hope can be reproduced:
With that program, I get the errors regarding the mis-matched brackets and others.
Write that program as:
And no errors occur.
Thank helps. I can see the error here.
OK. Adding
Dim RecvData(3)
to the Sub removed the error, but, whether that returns a value answer... I truly do not know, but, read on.I have no idea what is truly going on. The use of the CHR() function returns a string. A string is ALWAYS two bytes long (as a minimum) #1 the length of the string #2 the first character.
So,
RecvData(0) = Chr( RecvData(1) )
equates toRecvData(0) = 1 byte length, 1 byte of the ASCII code
... oops two bytes into one byte does not go. So, in a vain attempt to keep compiling a variable calledRECVDATA(0)
is created. And, this is the real issue. TheError: Brackets do not match up
is a red herring.So, if adding
Dim RecvData(3)
resolves.. my guess is that the code is now a mess. And, sure enough if you look at the asm ... the code does not set RecvData(0) to anything... it calls FNCHR then goto to sleep....The answer here. Prevent the assignment of a CHR() to a BYTE, the target variable needs to be a STRING.
Proof.
Changing the sub, as follows, is a lot easier to see what is happening. Replace the sub. Compile, then, search the ASM for
myCharValue
being set.myCharValue
is created as a variable but it never gets set.Now change the sub as follows: My
myCharValue
is a string. Compile and search the ASM... and,myCharValue
is being set.So, meanwhile while I ask Hugh to advise.... do not assign a CHR function result to a BYTE... in must be STRING.
That would no doubt be why it worked when I used "Print Chr(RecvData(1))".
I have been able to get my program working as I wanted, using the "Print Chr(RecvData(1))" method, it was more that the mis-match brackets error didn't match the real error.
I'd found that declaring the array inside the sub worked when I was trying to pare the program down to something that produced the error.
I was only pleased that I wasn't dreaming...
why declare the array in a sub?
as a beginner, I set everything at the start before any main code.
As a sub is usually called several times does it mean you can re dim an array in code?
I normally don't declare anything in a sub. When testing the minimum possible program that showed the error, I noticed that declaring the array in the sub prevented the error being flagged - though as proven by Anobium the error was still present.
To clarify, making the declaration of the array inside the sub routine has be shown not to eliminate the problem, it merely masks it. The only correct method to convert a value using "Chr" is to ensure it is assigned to a string, not a byte.
As I understand it in GCB, all variables are treated as global and "declared" by the compiler only once, being essentially moved to the top of the program. {I may be wrong here!}
In Delphi (Pascal) it made much more sense to make declarations inside the procedure (sub). Variables declared inside a single procedure were only ever visible to that procedure, attempting to re-use the same variable name in any other procedure would result in an error when compiled. The variables had "Global" scope only if declared in the "Uses" clause at the top of the program (thus available to all procedures) or had "Local" scope if declared in the "Uses" clause within a procedure (thus visible only to that procedure - even if the same variable name was re-used in another procedure). Values could be passed between procedures with the procedural parameters - those parameters too needed to be tightly defined before they could be used. Global variables were as welcome in Pascal as "Goto" in BASIC. Ideally there would be no global variables.
Waving a magic wand, I would like to see "Local" and "Global" variables in GCB. Global variables can lead to either lots of differently named variables - to prevent one variable from overwriting another - or the danger of a variable being overwritten. Local variables can prevent this neatly. Probably better still would be correct program design and coding in the first instance!
Last edit: mkstevo 2021-03-23
Guys. The redefining of the array is not the answer. I said - it will generated bad asm.
The issue will not be resolved by not assigning CHR() to a byte element with in an array.
Sorry.
I did mention that the error was no longer flagged, but was proven by you to still be present. I will endeavour to clarify this.
It is ok. I have the error. I have asked Hugh how to stop the assignment of a string function result to a byte value.
Showing my lack of understanding here, but I had thought that a "string" was an array, of byte values. Which is why I tried to use it as such in the first place.
Me to.
That's how left.mid, right $ works.
you can rotate ie scroll a string as if it was an array.
using dim mystring as string doesn't size it if enough ram...255 bytes if plenty of ram ?
From help
String variables default to the following rules and the RAM constraints of a specific chip.
10 bytes for chips with less than 16 bytes of RAM.
20 bytes for chips with 16 to 367 bytes of RAM.
40 bytes for devices with more RAM than 367 bytes.
For chips that have less RAM then the required RAM to support the user define strings the strings (and therefore the RAM) will be NOT be allocated. Please reduce string size.
so steve I think you're correct
OK. I will retry.
An array element is made up of a single element, that element is a byte (a single byte). Chr() returns a string - that is a minimum of two bytes. Two into one dont go.
The asm shows that my analysis is correct. I was trying to creating a variable, and, that variable has the brace..... hence, the incorrect error message.
The brace error message is the result of a much lower level issue... assigning a string to a byte.
If chr() was assigned the array then it would have worked.
I was not trying to suggest in any way what you found was incorrect, nor disputing that the returned value(s) from "Chr" require a minimum of two bytes to store it.
My ignorance was in making the assumption that a "byte" array was to all intents and purposes the same as a "string" array which I had imagined held an array of Ascii character byte values and nothing more.