|
Forum Index : Microcontroller and PC projects : bug in print/?
| Author | Message | ||||
| robert.rozee Guru Joined: 31/12/2012 Location: New ZealandPosts: 2464 |
while investigating palcal's problem, i found a bug in the way ? is handled. enter the folowing exactly into mmbasic's internal editor: a$="hello" ?a$ " world" End press f2 to run, and the output will be hello world now edit the program and you'll see that ?a$ " world" has been expanded to Printa$ " world", which when saved (if you edit the program elsewhere) and run again generates an error. this is with mmbasic 5.05.01 on an mx170. essentially, when ? is expanded to Print a space should be added afterwards by the editor's save routine if there is not already one there. cheers, rob :-) |
||||
| Turbo46 Guru Joined: 24/12/2017 Location: AustraliaPosts: 1646 |
I tried that little program in DOS MMBasic and got the same result as you. It would run again and again without error. So I tried with 5.05.01 on an mx170 and got the same result. Did it again using MMEdit - same result. Then I tried: a$="hello" ?a$ " world" printa$ " world" End and got: hello world [4] printa$ " world" Error: Unknown command > list a$="hello" Printa$ " world" printa$ " world" End So it doesn't mind when it creates the PRINT with no space after but not if I do it. Weird. I think you've found a bug and it's also there in DOS MMBasic. Bill Keep safe. Live long and prosper. |
||||
| matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 10572 |
This is a perfect example of why it is better not to compromise syntax to make things easier for users. ? without a space was a special case Geoff allowed that was really only intended for immediate usage at the command line. The diagnosis of the above results is as follows: ? and print are the same command. When a program is loaded commands are converted into single byte tokens When you edit tokens are converted back to normal text At this point the print token becomes PRINT not ? If the original program didn't have a space after ? then now we don't have a space after PRINT printa$ isn't a valid command but printa$= would be as in this case printa$ would be a valid variable SOLUTION: DON'T USE ? WITHOUT A SPACE EXCEPT AT THE COMMAND LINE |
||||
| robert.rozee Guru Joined: 31/12/2012 Location: New ZealandPosts: 2464 |
but does this mean that every instance of: Print "something" is encoded with an 'inert' space character after the print token? the example of using the shorthand form, ?, demonstrates how the space contributes nothing to the interpreter running the program, however it is essential to converting from plain text to the tokenized form. and if the space character is inert/superfluous here, is it equally superfluous after most other statements: Input, GoTo, Let, Dim, to name but a few. all these spaces add up to make a significant contribution to the flash space taken up by any large mmbasic program, as well as slowing down execution. the space characters are a bit like NOP instructions sprinkled liberally throughout the code. it seems a better strategy when tokenizing and detokenizing would be for statement tokens to represent the keyword followed by a space, just as (i assume) function tokens currently represent the keyword followed by an opening round bracket. geoff or peter: is it easy for a basic program to locate the starting address where a basic program is stored in flash and to then loop through memory printing out the stored program so we can easily examine this? i'm thinking of writing something stored in the library to carry out the task. cheers, rob :-) |
||||
MicroBlocks![]() Guru Joined: 12/05/2012 Location: ThailandPosts: 2209 |
No! it is just a little bug that can be fixed easily. Microblocks. Build with logic. |
||||
| matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 10572 |
very, just use PEEK(PROGMEM, offset) Isn't hindsight wonderful I don't know the guts of MMBasic well enough to comment properly but I suspect this would be a big change == new bugsThat is for Geoff to decide. However, whether easy or not it is a special case and the more special cases in code the more difficult to maintain it becomes. The bug exists because of a special case. // first test if it is a print shortcut char (?) - this needs special treatment if(*p == '?') { match_i = GetCommandValue("Print") - C_BASETOKEN; match_p = p + 1; } else { |
||||
| Turbo46 Guru Joined: 24/12/2017 Location: AustraliaPosts: 1646 |
Shouldn't the interpreter force that? The manual say's nothing about not needing a space whether or not it's on the command line. A "special case" is an inconsistency. If it confuses people like Rob and causes a discussion like this, what chance does a simple user like me have of knowing what's going on? My tuppence worth. Bill Keep safe. Live long and prosper. |
||||
| robert.rozee Guru Joined: 31/12/2012 Location: New ZealandPosts: 2464 |
cool! i've just written a small program to do this, below is the output, with source code interspersed: i=0 <1>[253][234][159]i[198]0<0> <1>[253][234]<0> Do <1>[253][234][132]<0> j=Peek(progmem, i) <1>[253][234][159]j[198][208]progmem, i)<0> If j>127 Then <1>[253][234] [156] j[197]127 [177]<0> Print "[" Str$(J) "]"; <1>[253][234] [166] "[" [164]J) "]";<0> Else If j<32 Then <1>[253][234] [134] j[196]32 [177]<0> Print "<" Str$(J) ">"; <1>[253][234] [166] "<" [164]J) ">";<0> Else <1>[253][234] [136]<0> Print Chr$(j); <1>[253][234] [166] [134]j);<0> EndIf <1>[253][234] [142]<0> i=i+1 <1>[253][234] [159]i[198]i[186]1<0> Loop Until i=200 <1>[253][234][162] [179] i[198]200<0> <0><0> [255][255][255][255][255]... it looks like every line starts with the three byte prefix <1><253><234>. and every line ends with a <0>. statements have the expected [bad] superflous trailing space, while functions have the opening bracket omitted. oddly, maths operators are encoded into new tokens, which seems odd to me - it is a waste of tokens. any operator character not contained in a literal string can always be interpreted as a token without needing to have it converted to a new token. i guess the rationale is to simplify the token detection logic (just needing to check for the high bit set). comments? geoff, what does the three-byte preamble mean? it seems a tad wasteful if it is always the same three-byte sequence. cheers, rob :-) |
||||
| matherp Guru Joined: 11/12/2012 Location: United KingdomPosts: 10572 |
It is the default when no line number is included #define T_CMDEND 0 // flags used in the program lines #define T_LINENBR 1 #define T_LABEL 2 #define MAXLINENBR 65001 // maximim acceptable line number #define NOLINENBR (MAXLINENBR + 1) // dummy line number to indicate that a line number has not been used // if(isdigit(*tp) && i < 8) { // if it a digit and not an 8 digit hex number (ie, it is CFUNCTION data) then try for a line number i = strtol(tp, &tp, 10); if(i <= 0 || i >= MAXLINENBR) i = NOLINENBR; *op++ = T_LINENBR; *op++ = (i>>8); *op++ = (i & 0xff); p = tp; } else if(!console) { *op++ = T_LINENBR; *op++ = (NOLINENBR>>8); *op++ = (NOLINENBR & 0xff); } |
||||
| robert.rozee Guru Joined: 31/12/2012 Location: New ZealandPosts: 2464 |
that seems horribly inefficient, especially considering that line numbers are rarely used these days. it would be far more efficient to use as the first byte of every line: <0> = end of line marker (ie, is a blank line) <1> = a 2-byte line number follows, then the rest of the basic line <2> = a label followed by colon, then rest of the basic line <3> = custom function body else the contents of a basic line. this would mean that for regular lines of basic code, there would be no preamble. for custom function body there would be a 1-byte preamble. for a line with a line number there would be a 3-byte preamble. for a line with a label there would be 2 bytes + the number of characters in the label. in this way 3 bytes per line would be saved, as for the vast majority of lines there would be no preamble required. for a 1000 line program this would save around 3k of flash space, about half of what is required to include double-precision maths on an mx170 if i am not mistaken! cheers, rob :-) |
||||
| Geoffg Guru Joined: 06/06/2011 Location: AustraliaPosts: 3308 |
Yes, the three bytes at the start of each line are rather inefficient and are a hang over from when line numbers were in common use. I have had this issue on my todo list for a long time and it is the fear of causing a new set of of bugs that has caused it to remain there for so long. As an example, some time ago (in Ver 5.04.06) I standardised some of the code dealing with the line prefix (as a preliminary step towards removing these bytes) but it caused a great many odd bugs in quite a few versions after. Rather than seeing this as an issue of simply saving some bytes of flash, it should be seen as a trade off between that and reliability. There are so many users using MMBasic for real critical tasks that I am resultant to foist on them something that may have some hidden nasty bugs. Given the complexity of the interpreter and the fact that this change will affect many aspects of it, bugs are to be expected and cannot be avoided, no matter how much care is taken. The real issue is how to test and find these bugs. I have a lot of test programs but given that this is a programming language there are an almost infinite number of ways that commands can be strung together so not all bugs can be caught. Releasing beta test versions is another method of finding bugs but it is unfair to rely too much on users falling over bugs. All this hand wring does not escape the fact that this is something that needs to be changed, however I plan to do it in a series of small steps. In doing it I will also incorporate Rob's excellent idea of implying a space after every command token (probably this will be another fertile source of bugs). Geoff BTW I have just returned from a long trip overseas but will have to leave again almost immediately to see my mum who is seriously ill. As a result you will not hear much from me over the next couple of months. Geoff Graham - http://geoffg.net |
||||
| viscomjim Guru Joined: 08/01/2014 Location: United StatesPosts: 925 |
Sorry to hear that Geoff. I wish you and your mother the best! |
||||
| CaptainBoing Guru Joined: 07/09/2016 Location: United KingdomPosts: 2171 |
wishing the best for your mum. Stay safe |
||||
| Paul_L Guru Joined: 03/03/2016 Location: United StatesPosts: 769 |
My best wishes to you and your mother! Take care of yourself while you're taking care of her. Paul in NY |
||||
CircuitGizmos![]() Guru Joined: 08/09/2011 Location: United StatesPosts: 1427 |
Your mother will be in my thoughts. I'm hoping for the best for you and her. Micromites and Maximites! - Beginning Maximite |
||||
| The Back Shed's forum code is written, and hosted, in Australia. | © JAQ Software 2025 |