Jump to content
  • 0

Vectorscript User Guide needs more Label information


SLFY

Question

I will preface this by saying that to the extent I can write scripts, I am self taught. I had one Fortran class in college in the mid 80's.

 

There is very little information about LABELS in the Vectorscript user guide that I could find, short of what it states in the GOTO statement section. And it is not easy to find info online for Labels in Pascal...not that there is much info needed: must be declared, where / how to declare them, do not declare labels not being used, AND a couple other little tidbits...

 

I just spent HOURS learning that if the main procedure script uses Labels, then user any user defined functions / sub-routines ALSO HAVE TO USE LABELS...even if it is just 1 label for 1 statement. 

 

If I am mistaken please let me know, so that I can go bang my head on a wall again. 

 

----

 

I am modifying a relatively large (for me) script and added a user defined function to replace the Str2Num function as suggested on the developer page http://developer.vectorworks.net/index.php/VS:Str2Num.

I was changing the input from a dimension type to a popup (showing / limiting options to the dimensions available) ...and needed to be able to get the input back into dimension form.

 

The script compiled fine before adding the user defined Str2Num function...however, after adding it, I continually got errors regarding the LABEL associated with every GOTO statement in my script. After much before mentioned head banging, experimenting and googling. I found an old website for pascal that gave a little more information about Labels - stating "Line labels defined within a procedure are exclusive to that procedure", and it gave an example showing Labels in the main and sub sections .

This information didn't solve my problem, but it did eventually ring the very small bell my head...."Do I need to add a label to the user defined function?" No idea WHY this would be necessary but I have tried everything else. So:

 

FUNCTION Str2Num(str :STRING) :REAL;
Label 1;
Var
num : Real;
BEGIN
1: Str2Num := 0;
IF ValidNumStr(str, num) THEN Str2Num := num;
END;

 

And it compiles without any errors regarding the Labels in the main procedure. 

 

So not only do I think there should be a blurb about the possibility of adding separate labels to sub routines / procedures/ user defined functions within a main procedure or $INCLUDE files, it should state that you HAVE to use labels in those sub routines if you use them in the main procedure.

 

Again, if I am wrong please let me know, and where I screwed up. 

 

Now I will have to see if it actually works. 😉 

 

Sean

 

 

 

Link to comment

10 answers to this question

Recommended Posts

  • 0

Hello Sean,

 

I have no idea why on Dev there is written to actually override Str2Num. You don't have to.

I don't know who wrote that. You CAN override it, but don't have to. I will add now a warning note on dev. Please don't override stuff if you don't feel comfortable with scripting.

 

BTW, GOTO are more difficult to handle than, say, CASE or IF conditions.

 

Quote

I just spent HOURS learning that if the main procedure script uses Labels, then user any user defined functions / sub-routines ALSO HAVE TO USE LABELS...even if it is just 1 label for 1 statement. 

 

This sounds quite surreal to me. I open now the guide which I found here. It states:

 

GOTO statements have several cautions which must be observed whenever using them:

  • GOTO statements can only transfer execution within the same procedure, function, or main body of a script. They cannot be used to jump between procedures or between scripts.
  • The destination of a GOTO statement must always be the beginning of a statement.
  • Jumping to statements that are contained within the structure of other statements can have undefined effects; the VectorScript compiler will not recognize this action as an error.

I used them myself only a handful of times. I think you'll do yourself a favour dropping them and eventually coming back to it when you feel more comfortable with VS.

 

Ciao,

Orso

Link to comment
  • 0

Thanks Orso. On the developer website it stated that Str2Num will not handle units, and this version of the function will...as I am adding both imperial and metric dimension choices to my dialog box, I need to be able to carry the units through. I haven't gotten to the point I have checked if that will in fact work in the existing str2num function. When I originally developed this vectorscript tool, I used the "dimension" input because I didn't want to try and figure out how to make a "string" input conversion work for both imperial and metric...I work in, and need to use both regularly, and in the same drawing file.

 

As for using LABELs...this is syntax that may not be neat and eligant, but it is very simple for me to understand and follow and that goes back to my 30year old basic fortran training. I understand the potential problem of where you are going to...but it is very easy to follow

the go-to statements through the script and find an issue. Follow the bouncing ball so to speak...might be time consuming on large scripts but simple to understand for my non programmer mind. I have never had errors in my compiled script that I wasn't able to diagnose pretty easily. 

 

And understand that I consider myself a novice but I have created twenty or thirty "tools" in vectorscript that I use on a daily basis. Some are 12years old and have grown as I add functionality. Perhaps 6 are 1000 to 2000+ lines of code, including this one. I do use "case of" when it makes sense, but, off hand, I can't begin to image how to do what I have some of these tools doing without using at least some LABELs. Some of my "inputs" will require going through 3/4s of the script, others may only go through the first 1/8th but then jump ahead to use the middle 1/8th and again for the last bit, etc. 

 

So my suggestion stands for the User Guide, if not reinforced. Please add the extra information, or more accurately, complete the information on how to use Labels. Reinforce the encouragement to use other methods if you like. 

 

Thanks Orso,

Sean

Link to comment
  • 0

If you have a parameter of type dimension, that takes care of the units and you need no conversion.

Whenever you use values that are subject to units, you should really take exclusively parameters of type dimension.

 

You don't need to use Str2Num, ValidNumStr -also in its standard version- supports units and it's a more modern call. Making it a sub has the advantage of having it return a number instead of a boolean value. It is an old standard subroutine from my collection here:

http://www.vectorlab.info/index.php?title=Util-Valid_num_or_zero

 

You don't have to redefine the standard routine, you can define your one as you please and call it something else. I think it is better.

 

You can look also at this one, for example:

http://www.vectorlab.info/index.php?title=Util-Valid_num_enhanced

 

I don't write the documentation, I just document VectorScript quirks on dev. Before that I did it on Vectorlab.

Lucky you that you find easy to follow GOTOs, I don't! Anyway, as it is stated in the current documentation, LABELS are unpredictable if used outside their scope. Keep that in mind and all is well. 

 

Ciao,

Orso

 

 

 

Link to comment
  • 0

Hi Again Orso, 

Again, I am the novice here, BUT...I believe you are wrong about the Str2Num Function that is built in to Vectorworks. If I include unit marks in the string, I get no result. If I add the user defined Function from the devoloper page above, it works as I need.

 

 

Here is a screen capture of the Parameters of a test script I created, which includes the needed unit marks in the strings:

image.thumb.png.a6aff791d8e6fc41891834a08967d13b.png

 

This Script, using the built-in Vectorscript Str2Num Function results in nothing being drawn, regardless of which input choice I select:

image.thumb.png.0b9db886914154a5ac0177267095f909.png 

 

This Script, with the added user defined Str2Num Function works as expected:

image.thumb.png.2e47faee6bea0d818cd6a35414bd8d1c.pngimage.thumb.png.1cc819375219a434dae1e42ed51968ec.png

image.thumb.png.1cc819375219a434dae1e42ed51968ec.png

 

 

On the other hand, I have not been able to repeat my issue with the compiler registering errors on my GOTO Labels. I can add a label and a IF THEN GOTO _ to this script, but not the user defined Function and I get no compiling errors. So, my comment that "if you have labels in the main script you also HAVE to have them in any sub routines, etc. appears to be false...except in the case of my much longer script...so I guess I will go back to banging my head if I have other issues when I finalize that tool. 

 

Thanks again, 

Sean

 

 

 

Link to comment
  • 0
12 hours ago, SLFY said:

 

Again, I am the novice here, BUT...I believe you are wrong about the Str2Num Function that is built in to Vectorworks. If I include unit marks in the string, I get no result. If I add the user defined Function from the devoloper page above, it works as I need.

 

 

Please read well what I wrote: I said that ValidNumStr supports units. Not Str2Num. The two are different.

Going back to the sub, you'll want to use a sub that returns the number right away instead of a boolean and that's why you define that sub.

Link to comment
  • 0

Sorry Orso, I quickly read part of your reply in an email that popped up on my phone just as I was about to hit send on the example scripts. I didn't refresh the web page to read it before submitting, because I was afraid I would lose what I had ready to post. I only added that first line to my post. In that quick, small screen email scan, I read the comma between the two functions in that sentence as you including both as handling dimensions.

Later I read your reply more completely. I took your recommendation and changed the function name, and decided to leave it in my scripts to include as needed. Rather than 0, I set the default - fail / error value to something very odd - I used 6.66mm - with a note to remind me. This way something will be drawn, but to the wrong size, if I ever use the Function in a script with a unit typo. Knowing how I think (or don't, obviously), nothing showing up is much harder for me to troubleshoot than figuring out why it is the wrong size. I also added a message to notify me of the error, but I use enough messages in some scripts that it may well be over written before I notice it. 

 

Sorry. 

 

But the added documentation for Labels was the intent of my post - and I still think a little more space should be provided to address the rules of using them - where they are to be declared, do not declare labels not being used, and that separate labels can be used in subroutines and perhaps an example that shows that. Again, in hindsight, this seems obvious, but until I saw an example of it, I don't think it would have occurred to me as a possibility. 

 

I still don't have any clue why I need to include a Label declaration in the user defined function within my long script, when I don't in others. This has me a little worried going forward with the evolution of this script and wondering if it is a different issue that I am unaware of still. Will a new vectoworks version expose the issue? Will I have trouble breaking it up into sub routines that I can use in other scripts as I plan? Cross those bridges if they ever come up I guess.

 

For now it works.  

 

Sorry again Orso and thanks for your help,

Sean

Link to comment
  • 0

Hello, labels are just as old as MiniCad. You won't see any change there. Raymond Mullin will able to point you to very good literature about PASCAL. If he's not following this thread already, I'll send him a note to come here and help you.

 

If GOTOs don't work as expected, you are making some mistake in their scope. And then they work unpredictably.
I seem to understand that you are using GOTO globally in your whole script. That will not work. 

 

As a principle GOTO statements are only good within a singular routine. No more. You won't be able to solve this problem until you switch to a different script structure. More subroutines, IF and CASE conditions.

Link to comment
  • 0

Hello @SLFY 

   I don't know that I can add much to what was previously written, except to support what @orso b. schmid has written. Orso's advice is spot on.

 

   You definitely want to use ValidNumStr() to convert string data to numbers in document units. This function will also perform rudimentary arithmetic such that the string ' 1mm + 1" ' will evaluate to 1.03937 if the document is in INCHES or it will evaluate to 26.4 if the document is in mm. Note leading and trailing white spaces are ignored. This is indeed a very powerful function.

 

   LABELS must be declared and used (with the GOTO command) at the same level in the program. If you need to escape nested routines, then you will need to use a unique LABEL at each nestled level and use a GOTO at that level to jump to the end of the routine you are escaping. You will also need one, or more, global variables (boolean flags) to signal that you are coming out early. This way you can leapfrog all the way to the end of the main program, if that is your intention.

 

Here's a quick example of 3 nested subroutines, each with a LABEL used to escape out to the next level.:

PROCEDURE MAIN;
LABEL 1;
VAR
	gError :Boolean;

	procedure SubroutineA;
	LABEL 2;

		procedure SubroutineB;
		LABEL 3;
		BEGIN		{ SubroutineB }
			AlrtDialog('I am at 3 - Sub B entry');
			{ stuff that coud cause an error. }

			if gError then GOTO 3;
		
			{ Do stuff here if no ERROR }
			AlrtDialog('I am at 4');
			
			3:	AlrtDialog('I am at 5 - Sub B exit');
		END;		{ SubroutineB }

	
	BEGIN		{ SubroutineA }
		AlrtDialog('I am at 2 - Sub A entry');
		SubroutineB;
		if gError then GOTO 2;
		AlrtDialog('I am at 6');
	
		{ Do stuff here if no ERROR }

		{ more stuff that coud cause an error. }
		if gError then GOTO 2;
		AlrtDialog('I am at 7');
		
		{ Do stuff here if no ERROR }
		
		2:	AlrtDialog('I am at 8 - Sub A exit');
	END;		{ SubroutineA }


BEGIN	{ MAIN }
	AlrtDialog('I am at 1 - MAIN entry');
	SubroutineA;
	if gError then GOTO 1;
		AlrtDialog('I am at 9');

	1:	AlrtDialog('I am at 10 - MAIN exit');
END;
Run(MAIN);

 

As written, this will execute with all Alert Dialogs counting up from 1 - 10.

 

Add this line into the code to simulate ERRORS that will invoke the GOTO calls to escape out of nested sections. Try placing it at line 15 for starters.

	gError := True;	{ move this statment around to see how it affects execution. }

 

   Lastly, it should be possible to write PASCAL code entirely without GOTOs, but if they are working for you there is no need to rewrite anything. Use what works save the new stuff for a rainy day.

 

 

   I'm not sure if I helped you, but I hope this helps someone, somewhere.

 

All the best,

Raymond

 

 

 

  • Love 1
Link to comment
  • 0

I can only support the recommendation that GOTO should be avoided.

 

Also I think that describing about how to use GOTO should not be in the documentation. New users should not even think about following that path.

 

(Luckily at university, we had to use a Fortran 77 compiler that supported structural programming. However I know GOTOs from a few BASIC versions.)

  • Like 1
Link to comment

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Answer this question...

×   Pasted as rich text.   Restore formatting

  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.

×
×
  • Create New...