Hello all
Phil Hanson (2558) 75 posts |
So the READ command, let me understand if I get what this does on a simple level. You basically reserve a certain amount of memory beforehand early in the program (In the example two variables, one 13 characters, one 7) So it’s reserving the equivalent of 20 characters in memory? I can understand the first variable as it is all numbers, so 1 byte per character right? But the second is all days of the week with different word character lengths. So maybe I don’t get it. Then you load of the variables using the DATA line, I get that. The example had a part that asked if you wanted to give the program another go. If you say Yes it goes back to a REPEAT after the READ, so I’m assuming the variables are still in memory and not read again. But if you say no, if that reserved memory returned? The example is on pg. 36 of the $.Documents.Books.First Steps Programming.First/pdf (Is this path right?) |
Phil Hanson (2558) 75 posts |
This is what I’m trying to wrap my brain around: 10 REM > Days2 |
David Feugey (2125) 2709 posts |
One more typo :)
I did use it. And even 4.70a on one computer. Same effect on all. Yesterday, I just install it again, with modes and configuration folder. And no problem any more. Strange. Nota: I did have this problem for more than one year and test many different versions of StrongED (perhaps with the same configuration folder). |
Steve Pampling (1551) 8170 posts |
— always throw an error reporting bit in very early, it covers all stupid mistakes we make.
Dimension some memory reserved for an array of 13 integer elements and some more for an array of 7 string elements. The string elements are big enough to hold a complete string of 254 characters plus 0 termination.
Slightly wasteful, yes. A DIM of 11 and a FOR 0 to 11 would have been neater.
It reads array string 0 then moves on to read another 6 totalling 7 reads.
Yes in memory.
Yes they tend to be there in memory, until something comes along and zeros that block – pretty typical of any computer system. There are ways you could look at the memory and read the debris left there. |
Rick Murray (539) 13840 posts |
It is BASIC, the termination is &0D (13). If you are working with OS routines that expect null terminated input, a |
Steve Drain (222) 1620 posts |
Sorry, pedant police here. A string variable, including an array element, can be up to 255 characters and there is no terminator. Until a string variable is assigned no memory for the string is used. A string variable is a 5-byte string information block (SIB) which is a 4-byte pointer to the string itself and a byte for the length. When the string is null these are zero.
If you are running the program from the BASIC command prompt (>) with RUN then they remain in memory, but using RUN again CLEARs them. There is no CONTINUE command, but you can do GOTO 70, for instance. You can see what variables exist using the command LVAR (list variables) at the command prompt. If you alter the program, the variables are lost. If the program is run by double-clicking a BASIC file, then all the memory is returned to the OS when the program ends. |
Steve Drain (222) 1620 posts |
Pedant police, again.
This is true only for indirected strings, and it would be confusing for Phil to go there just yet. ;-)
If you mean SWIs, then BASIC passes null terminated strings without any need for the programmer to take any action.
In general, BASIC returns string variables from SWIs without any special treatment, but it is always worth checking that there is not a problem. |
jim lesurf (2082) 1438 posts |
Not used BASIC for ages, but IIRC percent is for integer (as distinct from floating point) numbers. That may be irrelevant for what you’re doing, though. Jim |
Steve Fryatt (216) 2105 posts |
and its even more fun going the other way if null terminated strings are written to data blocks… Not when written to data blocks, it doesn’t (such as user message blocks received from the Wimp). That’s when you end up doing ugly stuff like SYS "XOSGenerateError", block% + 20 TO string$ and relying on the fact that BASIC does correctly decode strings directly pointed to by a register on exit from a SWI. You remember I said that BASIC quickly got nasty when you try to work with the OS API? ETA. Or you go for less of a hack, and write an DEF FNstring(string%) LOCAL string$, ptr% WHILE string%?ptr% <> 0 AND ptr% < 255 string$ += CHR$(string%?ptr%) ptr% += 1 ENDWHILE =string$ so that you can do string$ = FNstring(block% + 20) Except that I got my wrists slapped hereabouts for doing that, as I was told that it was less efficient than abusing an unintended side effect of the “most useless SWI” as nominated by Acorn User. |
Steve Drain (222) 1620 posts |
Who, me? ;-) Still, that WHILE loop routine you offer is pretty inefficient. Could you not just hide that “most useless SWI” away in a FN instead? Of course, it is not the SWI that is being abused, it is the keyword SYS, and there are others who use a different SWI to the same effect. One of the very early features of Basalt was RETURN$(pointer%) to do this job. It is only about 3 times as fast as that SYS call.
Indeed. Although most/many OS routines are happy to accept a CTRL-terminated string, it is not something to be relied on. |
Rick Murray (539) 13840 posts |
Reality police here… The internal representation of a string is not really relevant as I would imagine that there are few people who have delved into BASIC’s workspace and would need to know such a thing (I wasn’t aware of the representation as I’ve never needed to do such a thing).
You will note, byte &F is &0D. Passing data blocks with strings written into them will contain &0D as a string terminator. The operating system may or may not accept that, but since most APIs specify a null-terminated string… The exception here is when giving and accepting strings in the SYS call. BASIC is clever enough to bodge the strings around accordingly, for example:
Quite a few of the older APIs return either a string length or a pointer to the end of the string in one of the registers. With this information, it is possible to do something like
Unfortunately, yes. The overheads of SWI call and BASIC setting up the SWI parameters are still a lot less than doing a string scan in BASIC. I wrote a little test program to time doing this 10,000 times. The BASIC scan (using single character variable names) took 376cs (RPCEmu). The SWI version did the same thing in a mere 67cs. |
Andrew Conroy (370) 740 posts |
Wouldn’t this be easier to just write: 50 monnum%()= 0,3,3,6,1,4,6,2,5,0,3,5 |
Phil Hanson (2558) 75 posts |
So guys, what is an SWI? |
Phil Hanson (2558) 75 posts |
Dimension some memory reserved for an array of 13 integer elements and some more for an array of 7 string elements. The string elements are big enough to hold a complete string of 254 characters plus 0 termination. A string variable is a 5-byte string information block (SIB) which is a 4-byte pointer to the string itself and a byte for the length. So the Integer elements take 13 bytes? And the string elements in this example take 35 bytes? A single character is a byte correct? Number, letter. Why does the integer take a byte per number where as the string fits 254 characters in 5 bytes (4 not including length?) |
Rick Murray (539) 13840 posts |
If there are 13 of them, it should be 13×4 (integers are a 32 bit value). The string? Where did you get 35 from? The base string definitions (pointer plus length) would logically take 35 bytes1 but that is not including any string data.2
It does not, and this is one of the problems of delving too deeply into the internal workings of BASIC. An integer is a 32 bit (4 byte) value. There is probably another word or such somewhere else that tells BASIC where this integer is stored. You cannot normally access this, it is for BASIC. Ignore it, it isn’t your concern. A string is a sequence of bytes representing characters. The length of the string is the length of the string. Somewhere else is a 5 byte value pointing to the string and giving its length. You cannot normally access this, it is for BASIC. Ignore it, it isn’t your concern.
A system call. Essentially the backbone of RISC OS and necessary to do anything that BASIC cannot do directly for itself. If you have documentation on BASIC, look at the Phil – you don’t need to read beyond this point. Techie questions for Steve Drain follow. ;-) 1 Just out of interest, if there are multiple strings and the definition for each takes five bytes, do they follow on from each other or are they word aligned? 2 Likewise, if a string takes 13 characters, is the next word aligned? What happens if a 13 character string is doubled, do the rest shift around or is it reallocated at the end potentially leaving gaps in the allocation? |
Phil Hanson (2558) 75 posts |
Okay I shall ignore how BASIC does it’s black magic for now, heh. Thanks Rick. |
Dave Higton (1515) 3526 posts |
Phil: ignore what Rick and anyone else are telling you about the internal workings of BASIC. You don’t need to know for now. It Just Works. It’s simpler and easier than some people here are suggesting. Get on with trying it, and enjoy! I suspect that Rick has an agenda to put you off BASIC because he’s made up his mind that BASIC Is Bad, and is ignoring the fact that many people happily and successfully use BASIC to write lots of things. When you have learned and practiced one language, try another. When you’ve learned and practiced that too, you can make up your own mind about the virtues and vices. A tip for learning any programming language: look at other people’s code whenever you can, and see what useful tips you can pick up from it. |
Rick Murray (539) 13840 posts |
Dave – which part of this did you miss? “and this is one of the problems of delving too deeply into the internal workings of BASIC” A newbie programmer does not need to know how BASIC does stuff internally. To go to this sort of level of detail for a simple question is going to be confusing. That said, it is worth pointing out that when strings are used in blocks (which is frequently), simply poking a string into the data may not work. It’s a simple reason that can solve hours of frustrated attempts at debugging something. I was a learner once too, you know, and I didn’t have the benefit of forums to ask about it. Did you somehow manage to miss the part where I said, twice, in italics, that the complicated internal stuff should be ignored? Hell, I don’t know how BASIC does stuff inside. This sort of knowledge really isn’t necessary in order to write programs in BASIC.
I have no idea what gives you the idea that I think this. I did write another paragraph here, but it’s too late and I’m tired and if that’s how it appears then I’m just going to drop out of this conversation. Bye. |
Garry (87) 184 posts |
Hi Phil, My first language was BASIC, and while it lets you learn the basics of programming, it’s so different from any modern language, I don’t think it really helped me in learning other languages. Importantly, if you decide to take programming further, especially as a career, then you’re going to end up learning a different language anyway, because the number of people using BASIC in a professional setting are, well, limited. Visual Basic is basically nothing like BASIC, so you can’t really count that. I think C is no harder than BASIC really, and for anything even slightly advanced, it’s probably a load easier. I’d also second Gavin’s advice to have a go of Lua, it’s a superb language and Gavin has done RISC OS a great service in porting it. You could also try out Python, which is available for RISC OS. Personally, though I use Python for a great deal of my work, I think Lua suits RISC OS better, it’s very lightweight, and it’s easy to make bindings so that Lua can call C functions, if you ever want to get that advanced. Basically, Lua starts off very simple but can go pretty much as advanced as you like. Cheers Garry |
Phil Hanson (2558) 75 posts |
Mask number took me AWHILE of staring at the screen before I got it. Wow. |
GavinWraith (26) 1563 posts |
Thanks for the puff, Garry. One (advanced) feature of BASIC should be mentioned: its wonderful assembler and the facility to CALL assembled code. Lots of ARM assembly language programmers must have cut their teeth on this before moving on to ObjAsm; I did. This may not mean much to Phil at this stage. LuaJIT has a foreign function interface. Sadly, LuaJIT is not readily portable to RISC OS, because its ARM incarnations use a different calling convention. BASIC and C use quite different runtime systems – a technical aspect that is not relevant for first steps in programming, but which is vital for any discussion of calling between different languages (and is the reason that BASIC’s assembler and ObjAsm are not interchangeable tools). |
Steve Drain (222) 1620 posts |
OK, Rick, but I apologise for the intrusion in Phil’s simple BASIC topic. ;-)
In an array the 5-byte SIBs are byte aligned.
The memory for the actual characters for a BASIC string variable is allocated from the heap. Such allocations are word-aligned and are permanent. BASIC has a string allocation table to keep track of allocations that are free and will use a free one if it matches the string size (MOD 4) in preference to claiming new memory from the heap. Allocations become free when an assignement means a string no longer fits in its current allocation or is made null. There is no garbage collection 1 or coalescing of adjacent allocations. To answer your question, a string of 13 characters is in an allocation of 16 bytes. When it is doubled to 26 characters it will be stored in a free allocation of 28 bytes if there is one or in a new allocation of 28 bytes. As you and Dave said, none of this is relevant to someone just using BASIC. However, the nature of SIBs has been documented in the BASIC Reference Manual for nearly 30 years, yet there is a persistent meme that strings are stored in BASIC V as they were in BASIC II, in fixed buffers:
Steve P was not referring to indirected strings, nor were you when you corrected him:
And I specifically avoided indirected strings when trying to quosh the meme:
Which was also true of my comments on strings and SYS, which was an attempt to quosh another persistent meme that you have to pass and receive single strings as pointers to terminated buffers – and that has nothing to do with data blocks containing strings. Enough. ;-) 1 Before anyone steps in, there is one circumstance when a single allocation will be returned to the heap, but it is quite rare. |
Phil Hanson (2558) 75 posts |
So, working with memory now and it asks to go to the Dir where I have my practice BASIC programs stored and run one IN BASIC. I realize, I have no idea how to navigate the file structure inside of BASIC O.o. Am I thinking about this wrong, I can’t find anything online about navigating file structures. FYI I just skipped that part, heh. |
Phil Hanson (2558) 75 posts |
Doing the Pac Man game now. This is REALLY fun. |
Phil Hanson (2558) 75 posts |
Trying to run it for the first time and BASIC can’t find the sprites file. The BASIC file and the sprite file are currently in the same Dir. I thought it would look in the current directory if not given a full path, but it doesn’t seem to be doing so. |