Lisp FAQs

 

Overview

This chapter contains Frequently Asked Questions (FAQs) about AIS Lisp and supplied by its user community. Each FAQ is signed by its author. Any AIS Lisp user may add FAQs to this chapter and all AIS Lisp users are encouraged to contribute.

Accessing Elements of a Foreign Class

Author:   anonymous

How do we access elements of a foreign class agent in AIS Lisp? From the example below, if we have a foreign class agent 'foo' and we would like to access it's class variable 'x' declared in foo's svars. Unfortunately, we are not a method of foo (in which case we inherit foo'as svars). We can access 'x' by defining a template that will hold the format of the svar structure of class 'foo' which is 'foo.Sv'. Then declare a register pointer 'pr' to be used to offset the class element 'x' thru the template. (This is similar to C/C++'s arrow notation pr->x). The pointer holds the address of the foreign object while the template holds the format.

Example

 

    (defclass foo() svars:((Number:x 2.0)) true)

    (defun test(self Number:y)

       regs:(WordPointer:pr)

       (define template foo.Sv)

       (setq pr self)

       (+= pr[template(x)] y))

    (setq self (new foo))

    (test self 3.0)   Returns   5.0

Hints & Notes

Warning

Don't forget to load the address of the foreign class object into the pointer!

Embedding macros in a defmacro

Author:   Loryfel Nunez

Can we embed macros inside a defmacro?

Yes, we can as long as we use macroReplace to generate a new List everytime the macro is called in any agent. Using macroReplace will eliminate the chance of the compiler to mess up the original macro.

Aside from macros created using the defmacro agent, there are several other buil-in macros in LISP, to wit:

++
+=
/=
*=
-=
--

To illustrate:

We have a parent agent and two child agents with each child agent calling a macro with the macro inside a list constant :

;; Parent Agent
(defun parent() pvars:(child MacroTest parentVar) true)

;; Macro ++ is embedded inside a defmacro using a list constant, for instance,
(defmacro MacroTest()
'(++ x)
) ;; end defmacro

;; Define the first child agent
(defchild parent:child1() (parent@MacroTest))

;; Define the first child agent
(defchild parent:child2() (parent@MacroTest))

When at least two child agents call the MacroTest, the List constant is destroyed with macros passing back a List constant. Therefore,
'(begin (setq x 10) (++ x))
generates (++ x) in child1 but it generates (setq ++ x) in child2 which is an error.

To solve this problem, we use macroReplace to create a new List each time MacroTest is replaced in every agent. The new MacroTest looks like this:

(defmacro parent:MacroTest()
(macroReplace '(++ parentVar)))

Hints & Notes