Jump to content
Sign in to follow this  
Rossman

CASE [xxx] OF [yyy] in Pascal

Recommended Posts

Hi, everyone.  I've used CASE statements in Pascal with CHAR and INTEGER types without a problem.  But it doesn't look like I can use a CASE with a STRING type.  I get "Illegal type of expression" from the compiler on the CASE statement with a string.  If I redefine it to a CHAR, it compiles.  But I need more than a CHAR.  STRING types are valid in IF statements, but that's not the most efficient way to structure logic.  

 

It's not an intractable problem.  Just wondering if anybody has run into the same.  Yeah, yeah, there are 3 of us or so doing Pascal development on the 99/4A.  Maybe I can use a packed array of CHAR.  Maybe other development communities have run into the same on the CASE statement, that it can only resolve primitive data types.  

 

Of course, the bad news is that I'm back at it.  Expect more tedious Pascal development entries in the Development forum.  

 

  • Like 4

Share this post


Link to post
Share on other sites

Hi,

Are you doing this on a  real TI, or an emulator? TurboPascal99 or UCSD?

Share this post


Link to post
Share on other sites
Posted (edited)

Developing it on Classic99.  I've not experienced any compiler inconsistencies between Classic99 and real iron.  Plus, Classic99 is a far more efficient way for me to determine how lousy a developer I am.  

 

I've edited this post from here.

 

My first reaction was that, ok, maybe there is a potential difference given the environment.  But on thinking about it, that's not even remotely in the realm of the possible.  A difference between the two environments wouldn't manifest in a logic error at compile time.  If a CASE using STRING type works on real iron, it'll work on Classic99.    

 

So my question still stands as a language construct.  Anybody know whether Pascal allows STRING types in CASE statements?  

 

 

 

Edited by Rossman

Share this post


Link to post
Share on other sites

Have you tried a packed array of char just for kicks? I've never tried it but there is no specific mention against its use as a selector in UCSD Pascal. Packing and unpacking of packed arrays is done automatically in UCSD Pascal, unlike standard Pascal.

Share this post


Link to post
Share on other sites
On 4/13/2020 at 6:20 AM, dhe said:

Hi,

Are you doing this on a  real TI, or an emulator? TurboPascal99 or UCSD?

I have not had any issues using either MAME or Classic 99 for UCSD Pascal development after Tursi fixed the disk image issues, then transferring to real hardware using HDX. As a matter of fact, it's far better to use an emulator for development for reliability, plus you can use a modern text editor like Notepad++ and then copy and paste into the Pascal editor instead of using the latter for source code development because you are limited to 32 columns at a time in an 80 column field and the editing commands are very clunky at best. It's quite obvious that UCSD Pascal is very teletype-friendly :)

 

  • Like 1

Share this post


Link to post
Share on other sites

What buttons (figuratively) need to be pressed to tell classic99 to enable the p-code card?

Share this post


Link to post
Share on other sites
4 minutes ago, dhe said:

What buttons (figuratively) need to be pressed to tell classic99 to enable the p-code card?

None. Just select p-code card from the cartridge menu and use the DSK images for the system. You will probably need to initialize a blank disk from within Pascal  to use as a work disk as well.

ASM-LNK.DSK COMPILER.DSK EDT-FIL.DSK p-System Program Development.pdf UCSD_p_system_Assembler_Linker_Part_2_Linker.pdf UCSD_p_system_Compiler.pdf UCSD_p_system_Editor_Files_Utilities_Part_1_Editor.pdf UCSD_p_system_Assembler_Linker_Part_1_Assembler.pdf UCSD_p_system_Editor_Files_Utilities_Part_2_Filer.pdf

  • Like 2
  • Thanks 1

Share this post


Link to post
Share on other sites

The disks are also included in the Classic99 distribution under the Contributors folder. :)

 

Share this post


Link to post
Share on other sites
16 hours ago, Vorticon said:

Have you tried a packed array of char just for kicks? I've never tried it but there is no specific mention against its use as a selector in UCSD Pascal. Packing and unpacking of packed arrays is done automatically in UCSD Pascal, unlike standard Pascal.

Yeah my intention is to try a packed array but I've not had the time in the last couple of days to do that.   That's great to know about the unpacking.  String made me lazy.

 

Share this post


Link to post
Share on other sites
16 hours ago, BillG said:

No, standard Pascal does not allow a case statement with strings with the exception of single characters.  Some dialects allow two or even four character string constants.

 

It is not on the 99, but Free Pascal does for arbitrary strings.

 

https://www.freepascal.org/docs-html/ref/refsu56.html

 

Thanks for this.  CHAR and INTEGER worked fine, so I suspected as much, but I didn't want to rule out the possibility that I had an implementation problem.

 

 

 

Share this post


Link to post
Share on other sites
Posted (edited)

You don't. It's normal for Pascal implementations of the time to allow only simple data types for the selection variable. This is because the compiler makes a jump table with the different outcomes, and that becomes too complex if strings can be used for the case variable.

You also need to be aware of this when you select your constants to compare with in the case statement.

 

Compare these two case statements.

case a of
   1: bla;
   2: blah;
end;

case a of
   1: bla;
   20: blah;
end;

They will do the same, but the first requires a case jump table using two words of memory. The second will require 20 words of memory, where 18 of the words will just be unused fillers! Thus if you enter the two constants 1 and 20000, you'll get the dreaded ERROR: STACK OVERFLOW*REBOOT

On the other hand, this overhead makes the case statement very fast.

The same principle applies if you use char constants, with 'A' and 'B' versus 'A' and 'Z'.

Now when you know how the compiler implements this statement, it should be obvious why an array can't be used. Neither can real numeric values, but only integers.

 

Edited by apersson850

Share this post


Link to post
Share on other sites
5 hours ago, apersson850 said:

The same principle applies if you use char constants, with 'A' and 'B' versus 'A' and 'Z'.

Yikes, I did not know this.  So, in the case of a range of values like this:

 

case charval of
  '1' : do something
  'B' : do something 
  'Z' : do something

If I understand you correctly, the compiler will create a jump table of 41 words ('Z' has ASCII value of 90 decimal, '1' has ASCII value of 49 decimal.  Not only wasteful if I only need the 3, but it risks stack overflow.  I've found it not too difficult to get a stack overflow in Pascal by having too many constants.

 

When I had the stack overflow problem a few years ago, I solved it by replacing my constants with values in arrays.  I would guess that here, suppose I had a dozen or so cases (in my program, it's a user interface that allows a lot of different types of wagers - Dozen, Column, a specific Number, High, Low, Even, Odd, etc.), I'd be better off translating the entered wager into an indexed value from, say, 1 to 12 integer.  That would reduce the memory footprint of the jump table.

 

 

Share this post


Link to post
Share on other sites
Posted (edited)

42 words, actually, since both the values 49 and 90 have to be included. This is done by the compiler to make case selections efficient, time-wise.

 

The requirement to use simple types, like integer and char, does extend to enumerated types. So this code is valid:

type
   statetype = (stopped, running, idle, feeding, disabled, unknown);

var
   state: statetype;

begin
   case state of
      stopped: stopCode;
      running: runCode;
      idle: coffeeTime;
      feeding: foodTime;
      disabled: doNothing;
   end;
end;

The jump table will occupy five words only. Had the state unknown been declared between stopped and disabled, there would have been six words. That's equivalent to using the integers 1, 2, 3, 4 and 5 versus using 1, 2, 4, 5 and 6.

Edited by apersson850

Share this post


Link to post
Share on other sites
On 4/14/2020 at 1:23 PM, Vorticon said:

Have you tried a packed array of char just for kicks? I've never tried it but there is no specific mention against its use as a selector in UCSD Pascal

Well, there is, at least implied, since only simple types can be used, and an array (of which strings are a special case) isn't a simple type. Neither is a real. A simple type consists of a limited number of elements with a well defined order. Like characters and integers, but also enumerated types.

 

In a computer like the 99/4A, there is of course a limitation of how many different real numbers you can represent. Resolution puts a limit on that. The same goes for strings, since they can't have an unlimited length. But these are implementation dependent across different p-systems. At the time of the p-system, integers were 16 bit though, so the number of possible values was known and well determined.

  • Like 1

Share this post


Link to post
Share on other sites
14 hours ago, apersson850 said:

You don't. It's normal for Pascal implementations of the time to allow only simple data types for the selection variable. This is because the compiler makes a jump table with the different outcomes, and that becomes too complex if strings can be used for the case variable.

You also need to be aware of this when you select your constants to compare with in the case statement.

 

Compare these two case statements.

case a of
   1: bla;
   2: blah;
end;

case a of
   1: bla;
   20: blah;
end;

They will do the same, but the first requires a case jump table using two words or memory. The second will require 20 words of memory, where 18 of the words will just be unused fillers! Thus if you enter the two constants 1 and 20000, you'll get the dreaded ERROR: STACK OVERFLOW*REBOOT

On the other hand, this overhead makes the case statement very fast.

The same principle applies if you use char constants, with 'A' and 'B' versus 'A' and 'Z'.

Now when you know how the compiler implements this statement, it should be obvious why an array can't be used. Neither can real numeric values, but only integers.

 

This is a classic problem;  conditional branching or computed lookup table for a case statement. 

ANS Forth took the conditional branch approach for the "standard" which is versatile but slower. In time critical situations most people create a table like Pascal is doing here.  

Now I want to know how this is done in modern Pascal systems like Delphi or Wirth's later creations, Modula and Oberon. 

Do you have any insights on this?

I suppose the compiler carries both methods in its bag of tricks and makes a decision on which one to use.  ?

 

 

Share this post


Link to post
Share on other sites

I don't know how today's system do this. Today, I use computers to support my tasks and save time. Back with the TI 99/4A, I was interested in how everything worked under the hood, so I spent a lot of time investigating that.

  • Like 1

Share this post


Link to post
Share on other sites
On 5/13/2020 at 6:01 AM, Rossman said:

I've found it not too difficult to get a stack overflow in Pascal by having too many constants.

 

When I had the stack overflow problem a few years ago, I solved it by replacing my constants with values in arrays.

That's a bit surprising, since the compiler actually handles constants by creating an array with the constants, then indexing into that array when it references a constant.

Share this post


Link to post
Share on other sites
15 hours ago, apersson850 said:

That's a bit surprising, since the compiler actually handles constants by creating an array with the constants, then indexing into that array when it references a constant.

I had to dig around for it, but I posted my learning experience here:  

 

 

I was running an experiment with sprites, using constants to hold different character patterns.  That accumulated in memory pretty quickly.  In the end, it was a poor use of constants by me.  And an inefficient use of resources.

 

I don't know if it is helpful for me to post things like this, but for those who come along with an interest in Pascal development, perhaps they can learn from my mistakes.  I make a lot of them every day, but I always make it a point to end on a successful build.

 

 

 

Share this post


Link to post
Share on other sites
On 5/13/2020 at 6:05 AM, apersson850 said:

The requirement to use simple types, like integer and char, does extend to enumerated types. So this code is valid:

This is hugely helpful.  This sentence is my next refactoring of the wager logic.  Thank you, @apersson850

 

Probably poor on my part to admit this, but it never occurred to me that enumerated types were material to resource efficiency.  I'm familiar with enumerated types and use them from time to time.  They seemed like a clever thing, a nice-to-have, a self-documenting range of values.  But if my code works in an array or a case, why bother?  Well, what you have pointed out to me is that if I don't use them I end up with 42 words when I need 3.  And the more complex the side-bets, the more the wasteful resource allocation becomes.

 

I have 2 x UCSD Pascal programming books handy (excluding the TI manuals), I'm curious now to see how the academic tomes treat enumerated types.  

 

Thanks again.  This changes my thinking about how to handle classes of input.  This game (roulette) is more complex than the last for wagers.  This helps.

 

Share this post


Link to post
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
Sign in to follow this  

  • Recently Browsing   0 members

    No registered users viewing this page.

×
×
  • Create New...