define-macro and debugging

Started by Excalibor, December 16, 2004, 02:29:14 AM

Previous topic - Next topic

Excalibor

Hello!



Last development version of newLisp is really pretty (I should try and work on the vim mode, I will during the holidays) and have some nifty features, sp. regarding lexical scope with contexts...



So I want to write a protected macro, let's say a silly one that doesn't work:



(define-macro (do-but:do-but condition body)
  (if (= (eval condition) true)
   true
   (begin
    (eval body)
    (do-but condition body))))


I am basically trying to make a new construct that works like do-until, i.e. "do body but stop at condition".



Tested with:

(set 'x 1)
(do-but (= x 10) (begin (+ x 1) (print x)))

I get:

[code>

1

call stack overflow : if

[/code]



Now, I launch the debugger and the editor but I find this:



(define-macro (do-but:do-but MAIN:condition MAIN:body)
  (if (= (eval MAIN:condition) true)
   true
   (begin
    (eval MAIN:body)
    (do-but MAIN:condition MAIN:body))))

This is what newLisp sees, and once inside the debugger I cannot see the condition... both MAIN:condition and do.but:condition are nil...



Now, I suspect I should throw a labdba or two on that to make it work, but my question(s) is(/are): is the editor showing a bug? did I read badly that the macro arguments would be in its context when defining it this way? How do I see the value of something inside the debugger (specially when I'm debugging a macro)?



Lastly, though I want to fight this myself, a helping hand will be appreciated :-)



thanks,
david



PS: there's a Common Lisp tutorial on the web that's making a simple interactive rpg game. I wanted to translate it to newlisp as a means of practising and if the original author allows as a tutorial on newlisp for others... He proposes calling macros SPEL: Semantic Program Enhancing Logic... his reasons are probably sound, and nevertheless he makes a kind of macro alias, I am trying to get his defspel done in newlisp if its possible, and I don't see why not... URL: http://www.lisperati.com/spels.html">http://www.lisperati.com/spels.html Thx!

Lutz

#1
The way you write your macro, the local variables 'conition' and 'body' are still part of the MAIN context. There are two ways to write you marco correctly:



;; first method, bracketing with context statements

(context 'do-but)
(define-macro (do-but:do-but condition body)
  (if (= (eval condition) true)
   true
   (begin
    (eval body)
    (do-but condition body))))
(context 'MAIN)

;; second method using the function 'def-static' described
;; in the 8.3.2 rev-2 manual

(def-static 'do-but (fn-macro (condition body)
 (if (= (eval condition) true)
   true
   (begin
    (eval body)
    (do-but condition body))))

Either method will ensure that symbols in the macro are in a lexically closed context 'do-but'.



When using the debuger make sure you write:



(debug (do-but:do-but ......))



not:



(debug (do-but ....))



This is a bug in the debugger not recognizing default functions. I was not aware of this and it will be fixed for 8.3.3.



To have your debugging display less cluttered you also might swithc to the context first:



(context 'do-but)

(debug (do-but:do-but ......))



etc.



To check the variabes when debugging, just enter the name of the variable or any expression. When in the newLIS-tk window debugger, just enter the name or expression in the console window. When using 'debug' without the debug-window its the same, just enter the variabe-name or expression at the commandline, example:



[-> 6 ] s|tep n|ext c|ont q|uit  do-but:condition



Lutz