Listing unset variables

Anything QL Software or Programming Related.
Silvester
Trump Card
Posts: 201
Joined: Thu Dec 12, 2013 10:14 am
Location: UK

Listing unset variables

Postby Silvester » Tue Apr 25, 2017 11:01 am

TYPO_LIST lists all unset variables in current SBASIC name table (and all the accumulated typing garbage if used before NEW or LRUN)

Just discovered any extensions LRESPR'd into daughter SBASIC disappear if you subsequently load a Basic program. They need to be LRESPR'd after the load. NEW also kills them. Did I miss this in SMSQ/E docs?

Never needed it myself, but it would be an interesting exercise to similarly dump list of all set variable names and their values. Not sure if it has already been done?
Attachments
typo.zip
(2.42 KiB) Downloaded 44 times


I'm not plugged into the Matrix so my responses may be delayed.
User avatar
ql_freak
Trump Card
Posts: 175
Joined: Sun Jan 18, 2015 1:29 am

Re: Listing unset variables

Postby ql_freak » Tue Apr 25, 2017 10:14 pm

There is an error in the name initialisation list:

Code: Select all

name    dc.w    1       ;one procedure (must be 2 so that BP.INIT reserves enough space in the name table
;                        cause name is longer than 7 chars)


"The approximate number" of procedures or functions is used to reserve internal table space. It should be exactly equal to the number of procedures or functions unless the average length of the procedure or function names exceeds 7, in which case it should be:

Code: Select all

(total number of characters + number of functions or procedures+7)/8
(Technical Guide pg. 134)

I have written a patch program:

Code: Select all

100 REMark Patch typo_bin
150 :
200 c%=1:PRINT#c%,'Enter full filename of "typo_bin"':
220 c%=1:fn$=EDLINE$(#c%,36,"WIN1_etc_typo_bin")
250 f%=FOPEN(fn$):IF f%<0:PRINT#c%,"Cannot open ";fn$:STOP
300 procNum%=2:PUT#f%\10,procNum%
310 FLUSH#f%:PAUSE 50
350 procNum%=0
400 GET#f%\10,procNum%
410 CLOSE#f%
450 IF procNum%=2
500   PRINT#c%,fn$;" successfully patched"
550 ELSE
600   PRINT #c%,"Oops something went wrong, No. of PROCecures: ",procNum%
650 END IF


http://peter-sulzer.bplaced.net
GERMAN! QL-Download page also available in English: GETLINE§() function, UNIX-like "ls" command, improved DIY-Toolkit function EDLINE$ - All with source. AND a good Python 3 Tutorial (German) for Win/UNIX :-)
EmmBee
Brittle Membrane
Posts: 100
Joined: Fri Jan 13, 2012 5:29 pm
Location: Kent

Re: Listing unset variables

Postby EmmBee » Wed Apr 26, 2017 2:07 pm

Silvester wrote:Never needed it myself, but it would be an interesting exercise to similarly dump list of all set variable names and their values. Not sure if it has already been done?

Where this could come in very handy is when debugging a program, and you wish to get the values of some variables in order to find out what is going on. To make it easy to find the names your interested in, it would probably be good idea to sort the info into alphabetical order. One could perhaps use a Hotkey to quickly get at this info. This would certainly save a lot of time typing at the keyboard.

EmmBee


User avatar
ql_freak
Trump Card
Posts: 175
Joined: Sun Jan 18, 2015 1:29 am

Re: Listing unset variables

Postby ql_freak » Thu Apr 27, 2017 3:04 am

Silvesters Extension allows for a channel to list the unset keywords.

So I think it is not necessary to sort the output. I's a great task to write such a program (Thank You). Just list the output to a file channel and afterwards sort the file with a suitable program.

EDIT:
Remember you have PIPE-devices on QDOS/SMS (named and unnamed). Use this, if you want to have a task which can do this in one step(!).

If you don't have a device driver for "named pipes" I recommend:
Pipe2_v1_00.zip aka "PIPEMAN" which IMHO was the original name of this excellent device driver for named pipes. I have used it a lot.

You will find it on Dilwyns page in section "Toolkits and BASIC extensions".


http://peter-sulzer.bplaced.net
GERMAN! QL-Download page also available in English: GETLINE§() function, UNIX-like "ls" command, improved DIY-Toolkit function EDLINE$ - All with source. AND a good Python 3 Tutorial (German) for Win/UNIX :-)
Silvester
Trump Card
Posts: 201
Joined: Thu Dec 12, 2013 10:14 am
Location: UK

Re: Listing unset variables

Postby Silvester » Thu Apr 27, 2017 10:20 am

ql_freak wrote:There is an error in the name initialisation list:

Ha, I usually do it correctly. It was only a quick one (sic) :!:

It would be pretty dire if the one byte made the difference.

There are other issues with it that I have yet to solve. It also lists PROC/FN parameter names (if not set already as a separate variable). Also it will print nonsense (harmless) if you Break in the middle of a PROC/FN, because system leaves temporary variables on top of name stack, until cleared. (Pointer to name replaced with pointer to real entry during PROC/FN).

It also doesn't work to well on JS/Minerva, but it isn't needed there.

I've only gone off all the documentation available, to solve it would mean looking at the SMSQ/E SBASIC source. But at the least it quickly solves the problem I encounter :)


I'm not plugged into the Matrix so my responses may be delayed.
EmmBee
Brittle Membrane
Posts: 100
Joined: Fri Jan 13, 2012 5:29 pm
Location: Kent

Re: Listing unset variables

Postby EmmBee » Wed May 03, 2017 5:03 pm

once.zip
(25.61 KiB) Downloaded 33 times
This is all about finding spelling mistakes of variable names. I have written a program called “once”. The idea is that such misspellings may only have occurred once. My program scans through the loaded program looking for names. The first time a name is seen the line number is stored in the array. Should the same name appear again, then this entry is overwritten with -1. At the end of the scan, the list of line numbers and names can be printed out. If the layout needs to be changed, I’ve included the source, so it could easily be amended and recompiled. The task file has been Turbo Commanded into a bin file. This bin file needs to be LRESPR ed in boot. A hotkey could also be set up with ERT HOT_KEY(“1”,”once”,””). All that is required then is to hold down ALT and tap the “1” key to get an instant printout of all names used only once. There usually won’t be that many. Of course, some of these names may just have been declared as locals, and not used yet. Also, if a spelling mistake has been made more than once, then it won’t be found. "once" can be used with a channel number, the default is channel 1.

Code: Select all

 
1000 REMark                            win1_once_bas               03 May 2017
1010 REMark By Michael Bulford
1020 :
1030 REMark A program to list variables used only once
1040 REMark Can be useful for spotting typing mistakes
1050 :
1060 REMark %%win1_turbo_rem_code,6,10
1070 :
1080 TURBO_windo 0 : TURBO_objfil "win1_once_task": TURBO_taskn "once": DATA_AREA 5
1090 :
1100 IF COMPILED
1110   WHEN_ERROR
1120     OPEN #1,CON_
1130     SET_CHANNEL #0,0 : REMark SB's #0
1140     PRINT #0,"once: Error" ! ERNUM% ! "at line" ! ERLIN%; "  ";
1150     REPORT ERNUM%
1160     STOP
1170   END_WHEN
1180 END IF
1190 :
1200 MANIFEST : serial_device = 0 : windowing_device = 1 : file = 2
1210 base = 0 : last_row = 0 : t = 0
1220 IF NOT COMPILED
1230   c = 1 : con = 1
1240 ELSE
1250   t = DEVTYPE(#31)
1260   IF t<0
1270     c = 1 : con = 1
1280     ww = SCR_XLIM
1290     wh = SCR_YLIM - 30
1300     OPEN #1,CON_ : WINDOW ww,wh,0,0 : PAPER 2 : INK 7
1310   ELSE
1320     c = 31
1330     t = t && 3
1340     SELect ON t
1350     = serial_device, file
1360       con = 0
1370     = windowing_device
1380       REMark CON_ or SCR_
1390       CURSOR_ON #c
1400       base = PEEK_L(SYS_VARS+76)-104
1410       CURSOR_OFF #c
1420       con = PEEK_L(base+108)<>0 AND PEEK_L(base+116)<>0
1430     = 3
1440       OPEN #1,CON_
1450       SET_CHANNEL #0,0 : REMark SB's #0
1460       PRINT #0,"once: "; : REPORT -6 : REMark invalid channel ID
1470       STOP
1480     END SELect
1490   END IF
1500 END IF
1510 IF con
1520   CURSOR_ON #c
1530   base = PEEK_L(SYS_VARS+76)-104
1540   CURSOR_OFF #c
1550   ww = PEEK_W(base+28)
1560   last_row = (PEEK_W(base+30) DIV 10) * 10 - 10
1570 END IF
1580 :
1590 REMark Tokens
1600 MANIFEST : space  = 128 : keyword = 129
1610 MANIFEST : symbol = 132 : opsym   = 133 : monosym   = 134
1620 MANIFEST : name   = 136 : byte    = 137 : integer   = 138 : string = 139
1630 MANIFEST : text   = 140 : lineno  = 141 : separator = 142
1640 MANIFEST : nomin  = 240 : nomax   = 255 : REMark floating-point
1650 REMark types
1660 MANIFEST : resident_proc = 8 : resident_fn = 9
1670 REMark keys
1680 MANIFEST : ENTER = 10 : Esc = 27
1690 :
1700 max_names% = (BASIC_L(28)-BASIC_L(24)) / 8
1710 DIM once%(max_names%)
1720 Record_Onces : Print_Names : STOP
1730 :
1740 DEFine PROCedure Record_Onces
1750 LOCal s, scan, token, i, Lnum
1760   s = BASIC_L(16)+2 : Lnum = 0
1770   REPeat scan
1780     token = BASIC_B%(s)
1790     SELect ON token
1800     = symbol : s = s+2 : IF BASIC_B%(s-1)=10: s = s+2: IF s>BASIC_L(20): RETurn
1810     = lineno : Lnum = BASIC_W%(s+2) : s = s+4
1820     = name : i = BASIC_W%(s+2) : s = s+4
1830              IF once%(i)=0 : once%(i) = Lnum : ELSE once%(i) = -1
1840     = space, keyword, opsym, separator, monosym, byte : s = s+2
1850     = integer : s = s+4
1860     = nomin TO nomax : s = s+6
1870     = string, text : s = s+4 + BASIC_W%(s+2) + BASIC_W%(s+2) MOD 2
1880     = REMAINDER : s = s+2: PRINT #c,"Unknown token" ! token ! "at line" ! Lnum
1890     END SELect
1900   END REPeat scan
1910 END DEFine Record_Onces
1920 :
1930 DEFine PROCedure Print_Names
1940 LOCal found, i, n_ptr, type, x, y, wait, k
1950   IF con OR t=windowing_device : CLS #c : PRINT #c,""
1960   PRINT #c,"Candidates for possible spelling mistakes .."
1970   PRINT #c,"Name(s) occurring once only ..";
1980   found = 0
1990   FOR i = 0 TO max_names%-1
2000     IF once%(i) > 0
2010       n_ptr = BASIC_L(24) + i*8
2020       type = BASIC_B%(n_ptr)
2030       IF type<>resident_proc AND type<>resident_fn
2040         PRINT #c,\"At line "; once%(i) !!! BASIC_NAME$(i);
2050         found = 1
2060         IF con AND PEEK_W(base+36) >= last_row AND i < max_names%-1
2070           x = PEEK_W(base+34) : y = PEEK_W(base+36)
2080           IF x > ww-6 : x = ww-6 : CURSOR #c, x, y
2090           CURSOR_ON #c : k = CODE(INKEY$(#c,-1)) : CURSOR_OFF #c
2100           IF k = ENTER  OR  k = Esc : PRINT #c,"" : RETurn
2110         END IF
2120       END IF
2130     END IF
2140   END FOR i
2150   PRINT #c,""
2160   IF NOT found : PRINT #c,"  .. nothing found"
2170   IF t<0
2180     CURSOR_ON #c
2190     REPeat wait: k = CODE(INKEY$(#c,-1)): IF k = ENTER OR k = Esc : EXIT wait
2200     CURSOR_OFF #c
2210   END IF
2220   IF t = file : CLOSE #c : REMark to let the file be opened and read
2230 END DEFine Print_Names


Recently, Per Witte mentioned the program by DP called XREF. This can identify variables that have been used, but not declared, and those declared but not used. So, it would seem this is the real program we need to take seriously. This is available here …

THE_DISTRIBUTION_emu_zips_PROGUTIL_ChasUtil.zip/xref

Michael Bulford (EmmBee)



Who is online

Users browsing this forum: No registered users and 6 guests