Jump to content

Recommended Posts

Posted

Back to my stock of unusual questions.

 

My batch routine can accept strings from the user, which are in essence LISP code. Naturally, these strings can be evaluated, and the LISP code can be ran. The problem is, what if the user inputs an incorrectly formatted command? Suppose instead of "(vl-cmdf "circle" (getpoint) 5)" they type "I love to sing-a, about the moon-a in the June-a in the spring-a". I need a way to determine if what they type is valid LISP code (hence the title of this thread).

 

I've done some thinking, and there are only two ways that even begin to solve this problem, but neither of them are fully satisfactory. The first is testing if the string can be read as a valid list, a sort of (listp (read )) idea. This will work if the command is formatted properly, since all commands entered this way, when passed through the 'read' function, will return a list. However, this will always return true if the user typed a list, which means it won't check to see if it's valid code. The other method is using the eval function, which pretty much does exactly what I'm trying to achieve, only I don't want the code to actually be evaluated. I just want it checked to see if it CAN be evaluated.

 

It's a small bug in retrospect, especially since one typo could throw off the whole works (suppose someone misspelled "circle", it would still be valid LISP code but it wouldn't run properly), but it's got my curiosity ablaze. Any ideas?

Posted

Good question, but there are a few restrictions that I can see...

 

Of course, you could check for a valid list using:

 

(vl-consp (read <string> ))

 

But, as you say, this would only determine if the user has entered a list.

 

My second thought was something along the lines of:

 

(vl-catch-all-error-p
 (vl-catch-all-apply 'eval (list (read <string>))))

 

And check to see if it threw an error, but of course, this would mean evaluating the code in question...

Posted

Well if there are more than 10 charecters without one of them being a parenthesis, it's obviously not valid LISP code.:D

 

Could you try evaluating it once in a test loop and if it fails, return it as invalid?

 

Sorry I don't really have a good answer, just had to be a smart alec.

 

Glen

Posted

I doubt you can check for errors without evulating the code - otherwise I reckon the VLIDE would have a function like that built in.. o:)

 

But, if you evaluate it, not only will it do what its programmed to do - you will also fall up on any user inputs it may have...

Posted

We can all see it going one of two ways.

 

Checking to see that it's a list, checking to see that it has an equal number of open and closed parentheses, et cetera, et cetera. Basically, breaking it apart and building up a valid check by the pieces.

 

Or, from the top down: using the eval function but capturing all the "activity" so nothing is actually being done.

 

The latter does seem like the cleaner and easier option, as the former seems to me that it would require checking against long lists of valid options, to the point of being all but impossible to accomplish.

 

I wonder.. would it be possible to write the code to a script, run the script, then undo all the activity? I read somewhere that a single "undo" will undo all operations in a script. That would allow an evaluation (thus, a test) and, ultimately, no changes were made. I think it would have to be a script, as there would be no way to tell how many changes were made if it was straight LISP. What do you think?

 

*EDIT* A single undo might not work. Who knows, maybe nothing was actually done.

Posted

Why use a script? :huh:

 

If you were to test the code, then undo the changes, just use vla-StartUndoMark/EndUndoMark or (command "_.undo" "_begin")/(... "_end")

 

But, to check for errors, you would have the code wrapped in the vla-catch-all-apply statement, so, I suppose you would only use the "undo" if an error was flagged.

Posted

I'd use a script because I didn't know about those other commands, but I sure as heck do now! o.o

 

If you wrap the code in a (setq variable (vla-catch-all-apply ...)), then wrap THAT in those fancy undo bits.. couldn't you then check the status of "variable" to see if it's an error? Or would the "undo" bits not work if there's nothing to undo?

Posted

By jove, I think that's it.

 

(defun c:tst_lispp()
 (setq code (getstring "\nEnter Visual LISP code: "))
 (lispp code)
 )

(defun lispp(input / chkvar)
 (vl-cmdf "_.undo" "_begin")
 (setq chkvar (vl-catch-all-apply 'eval (list (read input))))
 (vl-cmdf "_.undo" "_end" "_.undo" "")
 (vl-catch-all-error-p chkVar)
 )

Much obliged everyone, my curiosity is happy now. ^.^

Posted

Why undo it if there's no error? Surely then the code has done what it was meant to? :huh:

Posted

The idea is simply to check to see if the string can be evaluated. Actual evaluation doesn't happen at this step, but at later steps. If I didn't specify that at the start, I apologize.

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
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   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...