



Manual  for  CLIPS2C  1.0:  a  CLIPS  to


C++  translator
____________________________________________________________________


Julian Smart

Artificial Intelligence Applications Institute

University of Edinburgh

EH1 1HN
March 1994
                                 Artificial Intelligence Applications Institute
                                                University of Edinburgh
                                                      80 South Bridge
                                                            EH1 1HN
                                                     Tel. 031-650-2746


Contents



1  Introduction                                                   1


   1.1 Why translate CLIPS?  : : : : : : : : : : : : : : : : : : : : : : : :  1


   1.2 Output details   : : : : : : : : : : : : : : : : : : : : : : : : : : : :*
 *  2


   1.3 What compromises must I make?  : : : : : : : : : : : : : : : : : :  3


   1.4 CLIPS2C change log  : : : : : : : : : : : : : : : : : : : : : : : : :  3



2  Running CLIPS2C                                             4



3  Compiling generated code                                      5



4  Syntax reference                                               6


   4.1 Commands   : : : : : : : : : : : : : : : : : : : : : : : : : : : : : :  6



5  Errors and bugs                                                8


   5.1 Errors  : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : *
 *:  8


       5.1.1 Unresolved type   : : : : : : : : : : : : : : : : : : : : : : :  8


   5.2 Bugs  : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : : *
 *:  8



6  Examples                                                      9


   6.1 CLIPS input example   : : : : : : : : : : : : : : : : : : : : : : : :  9


   6.2 C++ output example   : : : : : : : : : : : : : : : : : : : : : : : : 12



Glossary                                                         18
                                                                   i


Copyright  notice

Copyright (c) 1994 Julian Smart.


Permission to use, copy, modify, and distribute this software and its documen-
tation for any purpose is hereby granted without fee, provided that the above
copyright notice, author statement and this permission notice appear in all
copies of this software and related documentation.


THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY
OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITH-
OUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR FIT-
NESS FOR A PARTICULAR PURPOSE.


IN NO EVENT SHALL JULIAN SMART OR THE ARTIFICIAL INTELLI-
GENCE APPLICATIONS INSTITUTE OR UNIVERSITY OF EDINBURGH
BE LIABLE FOR ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSE-
QUENTIAL DAMAGES OF ANY KIND, OR ANY DAMAGES WHATSO-
EVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER
OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY
THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH
THE USE OR PERFORMANCE OF THIS SOFTWARE.

                                                                  ii


1.      Introduction
____________________________________________________________________



This document describes a utility for translating programs written using a subs*
 *et
of the CLIPS language [?] into C++ source code. CLIPS2C knows about two
optional extensions to CLIPS: wxCLIPS, a set of GUI primitives, and CLIPS
for HARDY, a diagramming tool that uses CLIPS to access diagramming and
hypertext functionality.


The latest version of CLIPS2C can be accessed by anonymous ftp from:
skye.aiai.ed.ac.uk (192.41.104.6)


in the directory /pub/wxclips. It is available in SPARC Open Look and Win-
dows 3.1 versions.


CLIPS2C was developed using the free Open Look, Motif and Windows 3.1
C++ class library wxWindows, also available from the above FTP site in the
directory /pub/wxwin/beta.
1.1   Why translate CLIPS?


CLIPS is an interpreted, multi-paradigm language written by NASA and avail-
able at low cost.  Its principal advantage is an efficient and flexible rule in-
terpreter, but has functional and object-oriented constructs also, making it an
excellent development language.  Compared with compiled C++, the devel-
opment cycle is much faster, with application changes being apparent within
seconds of changing source code.


However, delivering an application in C++ has several advantages over CLIPS:



   o faster speed of execution

   o smaller size of delivered executable

   o no third-party code issues

   o security of binary code



Ideally, we would like the benefits of interpreted CLIPS for development, and
the run-time advantages of C++ for delivery.  NASA has of course thought
of this, and provides binary load/save capabilities and a compile-to-c option.
However, CLIPS must still be compiled into the executable in both cases. The
C code output by the constructs compiler is in fact a set of meaningless-looking
arrays.


Primarily because of the third-party code issue, and for a bit of fun, CLIPS2C
has been developed to allow a subset of CLIPS to be compiled into C++. For



                                                                  1

________________________________________________________CHAPTER_1___
non-AIAI users, the third-party code issue will be reduced rather than elimi-
nated, since the generated C++ still relies on a small run-time library.


CLIPS' main reason for existence, its rule syntax, is not translated by CLIPS2C,
because CLIPS is mainly used within AIAI as an embedded, functional develop-
ment language. The object system COOL is also not yet supported by CLIPS2C,
but is likely to follow in due course.
1.2   Output details


CLIPS2C generates a single file of C++ code, with sections of constructs in the
following order:



  1. Global variables.

  2. Function prototypes.

  3. Function definitions.

  4. Top-level statements (if a CLIPS batch file is being interpreted).  They
     are collected into the function ExecuteClipsStatements.

  5. If HARDY mode is used, the function InitializeCustomCode is generated,
     which simply calls ExecuteClipsStatements.  HARDY calls InitializeCus-
     tomCode on startup.



Blocks are indented, making the output code readable. Arbitrary name scoping
within blocks is not implemented: all variables declared within a function are
in the same block, and are declared at the start of the function.


CLIPS names are converted to legal C++ names, so asterisks and hyphens are
replaced with underscores.


Integers and boolean values are all long integers in generated code, and floati*
 *ng
point numbers are floats.  Strings are implemented using the wxString class,
which has sufficient member functions and operators to support CLIPS string
functionality, and multifield lists are implemented using ClipsExpr, which is
also used in the implementation of CLIPS2C. No garbage collection is necessary,
since all variables are either global or created on the stack.


All types are resolved statically, and this applies even in list element access:
CLIPS2C must be able to resolve the type of element being accessed.


Extensions to CLIPS (such as wxCLIPS and HARDY functions) are dealt with
by mapping from the CLIPS name to an equivalent C function name. Thus, in
wxCLIPS, the CLIPS function panel-create is replaced by the C function which
implements it, namely wxcPanelCreate. The arguments are translated appropri-
ately; for example a wxString argument passed to character pointer argument
is dealt with by generating the appropriate accessor function for the wxString.
This is optimized by checking for a literal character string being passed to a *
 *char-
acter pointer argument, where it would be unnecessary to construct a wxString
and then access the character pointer data.



                                                                  2

________________________________________________________CHAPTER_1___
1.3   What compromises must I make?


As a CLIPS programmer, you need to use a subset of the language that CLIPS2C
can cope with. This essentially means sticking to the defglobal and deffunction
constructs, and being aware of which CLIPS functions are available for use.
It is also necessary to be aware that CLIPS2C attempts to resolve data types
statically, and it may need to be helped along by use of the declare statement
(defined in the wxCLIPS extensions to be a null operation within CLIPS).


In CLIPS proper, functions can return a value implicitly without using the
return statement. CLIPS2C requires all returned values to use return. It also
does not allow conditionals, switch statements, progn statements and the like
to return values within expressions:  they must be used as statements, using
intermediate variables where necessary.


External CLIPS functions which have been defined in C (like the new wxCLIPS
functions) need to be added to CLIPS2C's repertoire by modifying either of the
files clipdef1.cc or clipdef2.cc, and recompiling the translator.
1.4   CLIPS2C change log


Version 1.0:



   o Initial release.

                                                                  3


2.      Running  CLIPS2C
____________________________________________________________________



CLIPS2C accepts two arguments (input and output filenames) and trailing (op-
tional) switches.  If both filenames are given, the utility will work in batch
mode.  Otherwise, if CLIPS2C has been compiled for GUI operation, a main
window will be shown, with appropriate menu items for selecting input and
output filenames, starting off the conversion process, and so on.



-interactiveForces interactive mode even if both filenames are given.

-sync Under Windows, don't yield.

-clipsInterpret plain CLIPS.

-wxclips Interpret wxCLIPS extensions.

-hardy Interpret HARDY extensions.



                                                                  4


3.      Compiling  generated  code
____________________________________________________________________



To compile code generated by CLIPS2C, you need the file itself, the CLIPSLIB
run-time library provided, and either wxWindows or the files from wxWindows
that are included in the wxlib directory.


If you wish to use the functions provided by wxCLIPS, you will need to compile
the wxCLIPS library in non-CLIPS mode. Under Windows, set the USE_CLIPS
wxCLIPS makefile variable to zero.


You need to define a function:
void ClipsErrorFunction (char *s)
-
"


which deals with standard output from the generated program.


The file test.cc is an example program that makes use of CLIPS2C-generated
code. It provides a text window for standard output. Note that it assumes use
of wxCLIPS, and requires the no-CLIPS version of that library to be present.
Generate the file demo.cc from the CLIPS file hello.clp before compiling the te*
 *st
program.

                                                                  5


4.      Syntax  reference
____________________________________________________________________



CLIPS2C currently recognises the deffacts and deffunction constructs, and any
top-level statements in a batch file.


This section describes the areas and details of syntax modified or not covered
by CLIPS2C. It should be read in conjunction with the CLIPS user guide. In
addition to the following, some of the maths functions are not implemented.
4.1   Commands


build


This function is not implemented.



eval


This function is not implemented.



get-function-restrictions


This function is not implemented.



insert


Insert may only take a fixed number of arguments, unlike the CLIPS implemen-
tation.



if


This cannot return a value or be used within an expression.



loop-for-count


This may only use the form involving an index variable, and not the form that
just specifies the number of iterations.



progn


This cannot return a value or be used within an expression.



                                                                  6

________________________________________________________CHAPTER_4___
replace


Replace may only take a fixed number of arguments, unlike the CLIPS imple-
mentation.



str-index


This function is not implemented.



subsetp


This function is not implemented.



switch


This cannot return a value or be used within an expression.



                                                                  7


5.      Errors  and  bugs
____________________________________________________________________



5.1   Errors


The following sections explain some of the errors that may occur, and how to
deal with them.



5.1.1 Unresolved type


This happens when CLIPS cannot use context to resolve the type of a parameter,
local or global variable, or expression. In this case, use the syntax:
(declare var1 type1 var2 type2 ...)


where var1 is a variable name and type1 is one of STRING, INTEGER, REAL,
or LIST. If the return type of a function cannot be resolved, use a variable and
the declare syntax.
5.2   Bugs


COOL   Not implemented!


                                                                  8


6.      Examples
____________________________________________________________________



6.1   CLIPS input example


Here is an example of a valid CLIPS input file.
;;; hello.clp
;;; Shows how a frame may be created, with a menu bar and
;;; panel, using low-level windows functions.
;;; Load using -clips <file> on the command line or using the Batch
;;; or Load commands from the CLIPS development window; type
;;; (app-on-init) to start.


(defglobal ?*main-frame* = 0)
(defglobal ?*subframe* = 0)
(defglobal ?*panel* = 0)
(defglobal ?*canvas* = 0)
(defglobal ?*text-win* = 0)


(defglobal ?*small`font* = 0)
(defglobal ?*green`pen* = 0)
(defglobal ?*black`pen* = 0)
(defglobal ?*red`pen* = 0)
(defglobal ?*cyan`brush* = 0)


(defglobal ?*xpos* = -1.0)
(defglobal ?*ypos* = -1.0)


;;; Sizing callback
(deffunction on-size (?id ?w ?h)
 (if (and (> ?id 0) (> ?*panel* 0) (> ?*text-win* 0)) then
 (bind ?client-width (window-get-client-width ?id))
 (bind ?client-height (window-get-client-height ?id))
 (window-set-size ?*panel* 0 0 ?client-width (/ ?client-height 2))
 (window-set-size ?*text-win* 0 (/ ?client-height 2) ?client-width (/ ?client-h*
 *eight 2))
 )
)


;;; Painting callback
(deffunction on-paint (?id)
 (if (> ?id 0) then
 (bind ?dc (canvas-get-dc ?id))
 (dc-set-font ?dc ?*small`font*)
 (dc-set-pen ?dc ?*green`pen*)
 (dc-draw-line ?dc 0.0 0.0 200.0 200.0)
 (dc-draw-line ?dc 200.0 0.0 0.0 200.0)


 (dc-set-pen ?dc ?*red`pen*)
 (dc-set-brush ?dc ?*cyan`brush*)
 (dc-draw-rectangle ?dc 100.0 100.0 100.0 50.0)



                                                                  9

________________________________________________________CHAPTER_6___
 (dc-draw-rounded-rectangle ?dc 150.0 150.0 100.0 50.0)


 (dc-set-clipping-region ?dc 150.0 150.0 100.0 50.0)
 (dc-draw-text ?dc "This text should be clipped within the rectangle" 150.0 170*
 *.0)
 (dc-destroy-clipping-region ?dc)


 (dc-draw-ellipse ?dc 250.0 250.0 100.0 50.0)
 (dc-draw-line ?dc 50.0 230.0 200.0 230.0)
 (dc-draw-text ?dc "This is a test string" 50.0 230.0)
 )
)


(deffunction on-event (?canvas ?event)
 (bind ?dc (canvas-get-dc ?canvas))
 (dc-set-pen ?dc ?*black`pen*)
 (bind ?x (mouse-event-position-x ?event))
 (bind ?y (mouse-event-position-y ?event))
 (bind ?dragging (mouse-event-dragging ?event))
 (if (and (> ?*xpos* -1) (> ?*ypos* -1) (> ?dragging 0)) then
  (dc-draw-line ?dc ?*xpos* ?*ypos* ?x ?y)
 )
 (bind ?*xpos* ?x)
 (bind ?*ypos* ?y)
)


(deffunction on-close (?frame)
; (format t "Closing frame.%n")
 (window-delete ?*subframe*)
 (return 1))


(deffunction on-menu-command (?frame ?id)
 (switch ?id
  (case 200 then
   (message-box "CLIPS for wxWindows Demo by Julian Smart (c) 1993" "About wxWi*
 *ndows CLIPS Demo")
  )
  (case 3 then
   (on-close ?frame)
   (window-delete ?frame)
  )
  (case 4 then
   (bind ?s (get-choice "Choose from the list" (mv-append "One" "Two" "Three")))
   (frame-set-status-text ?*main-frame* ?s)
   (format t "Answer was %s" ?s)
   (open "test.txt" mystream "w")
   (format mystream "The id of the menucommand is %ld%n" ?id)
   (format mystream "This is a second line.")
   (close mystream)
  )
  (case 1 then
    (bind ?file (file-selector "Choose a text file to load"))
    (if (neq ?file "") then
     (text-window-load-file ?*text-win* ?file))
  )
 )
)


;;; Button callback
(deffunction frame-button-proc (?id)
                                                                 10

________________________________________________________CHAPTER_6___
 (bind ?parent (window-get-parent ?id))
 (bind ?grandparent (window-get-parent ?parent))
; (format t "Pressed button %d%n" ?id)
 (message-box "Hello")
)


;;; Test program to create a frame
(deffunction app-on-init ()
 (if (= ?*small`font* 0) then
   (bind ?*small`font* (font-create 10 wxSWISS wxNORMAL wxNORMAL 0))
   (bind ?*green`pen* (pen-create GREEN 1 wxSOLID))
   (bind ?*black`pen* (pen-create BLACK 1 wxSOLID))
   (bind ?*red`pen* (pen-create RED 3 wxSOLID))
   (bind ?*cyan`brush* (brush-create CYAN wxSOLID))
 )


 (bind ?*main-frame* (frame-create 0 "Hello wxCLIPS!" -1 -1 500 450))
 (frame-create-status-line ?*main-frame*)
 (frame-set-status-text ?*main-frame* "Welcome to wxCLIPS")


 (window-add-callback ?*main-frame* OnSize on-size)
 (window-add-callback ?*main-frame* OnClose on-close)
 (window-add-callback ?*main-frame* OnMenuCommand on-menu-command)


 ;;; Make a menu bar
 (bind ?file-menu (menu-create))
 (menu-append ?file-menu 1 "&Load file")
 (menu-append ?file-menu 4 "&Test choice dialog")


 (bind ?pull-right (menu-create))
 (menu-append ?pull-right 100 "&Twips")
 (menu-append ?pull-right 101 "&10th mm")


 (menu-append ?file-menu 2 "&Scale picture" ?pull-right)
 (menu-append-separator ?file-menu)
 (menu-append ?file-menu 3 "&Quit")


 (bind ?help-menu (menu-create))
 (menu-append ?help-menu 200 "&About")


 (bind ?menu-bar (menu-bar-create))
 (menu-bar-append ?menu-bar ?file-menu "&File")
 (menu-bar-append ?menu-bar ?help-menu "&Help")


 (frame-set-menu-bar ?*main-frame* ?menu-bar)


 ;;; Make a panel and panel items


 (bind ?*panel* (panel-create ?*main-frame* 0 0 500 250))
 (panel-set-label-position ?*panel* wxVERTICAL)


 (bind ?*text-win* (text-window-create ?*main-frame* 0 250 500 300))


 (bind ?button (button-create ?*panel* frame-button-proc "A button"))
 (bind ?text (text-create ?*panel* "" "A text item" "Initial value" -1 -1 200))
 (bind ?check (check-box-create ?*panel* "" "A check box"))


 (panel-new-line ?*panel*)
                                                                 11

________________________________________________________CHAPTER_6___


 (bind ?choice (choice-create ?*panel* "" "A choice item"))
 (choice-append ?choice "One")
 (choice-append ?choice "Two")
 (choice-append ?choice "Three")
 (choice-append ?choice "Four")


 (message-create ?*panel* "Hello! A simple message")


 (bind ?list (list-box-create ?*panel* "" "A list" 0 -1 -1 100 100))
 (list-box-append ?list "Apple")
 (list-box-append ?list "Pear")
 (list-box-append ?list "Orange")
 (list-box-append ?list "Banana")
 (list-box-append ?list "Fruit")


 (panel-new-line ?*panel*)


 (bind ?slider (slider-create ?*panel* "" "A slider" 40 22 101 150))


 (bind ?multi (multi-text-create ?*panel* "" "Multiline text" "Some text"))


;  (window-fit ?*panel*)
;  (window-fit ?*main-frame*)


 (text-window-load-file ?*text-win* "hello.clp")
 (bind ?*subframe* (frame-create 0 "Canvas Frame" 300 300 400 400))
 (bind ?*canvas* (canvas-create ?*subframe* 0 0 400 400))
 (window-add-callback ?*canvas* OnPaint on-paint)
 (window-add-callback ?*canvas* OnEvent on-event)
 (canvas-set-scrollbars ?*canvas* 20 20 50 50 4 4)


 (window-show ?*subframe* 1)
 (window-show ?*main-frame* 1)


 (return ?*main-frame*))

6.2   C++ output example


Here is an example of a C++ file output from CLIPS2C.
/*
 * DEMO.CC
 * File generated by Clips2C from HELLO.CLP
 * for HARDY compatibility
 */


#include "math.h"
#include "stdlib.h"
#include "wxstring.h"
#include "clipslib.h"
#include "wx`cmds.h"
#include "hapi.h"


/*
 * Function prototypes
 */



                                                                 12

________________________________________________________CHAPTER_6___


void on`size(long id, long w, long h);
void on`paint(long id);
void on`event(long canvas, long event);
long on`close(long frame);
void on`menu`command(long frame, long id);
void frame`button`proc(long id);
long app`on`init(void);


/*
 * Global variables
 */


long `main`frame` = 0;
long `subframe` = 0;
long `panel` = 0;
long `canvas` = 0;
long `text`win` = 0;
long `small`font` = 0;
long `green`pen` = 0;
long `black`pen` = 0;
long `red`pen` = 0;
long `cyan`brush` = 0;
float `xpos` = ((float)-1);
float `ypos` = ((float)-1);


/*
 * Classes
 */



/*
 * Functions
 */


void on`size(long id, long w, long h)
-
 long client`width;
 long client`height;
 if (((id>0) && (`panel`>0) && (`text`win`>0)))
 -
   client`width = wxcWindowGetClientWidth(id);
   client`height = wxcWindowGetClientHeight(id);
   wxcWindowSetSize(`panel`, 0, 0, client`width, (client`height/2));
   wxcWindowSetSize(`text`win`, 0, (client`height/2), client`width, (client`hei*
 *ght/2));
 "
;
"


void on`paint(long id)
-
 long dc;
 if ((id>0))
 -
   dc = wxcCanvasGetDC(id);
   wxcDCSetFont(dc, `small`font`);
   wxcDCSetPen(dc, `green`pen`);
   wxcDCDrawLine(dc, ((float)0), ((float)0), ((float)200), ((float)200));
                                                                 13

________________________________________________________CHAPTER_6___
   wxcDCDrawLine(dc, ((float)200), ((float)0), ((float)0), ((float)200));
   wxcDCSetPen(dc, `red`pen`);
   wxcDCSetBrush(dc, `cyan`brush`);
   wxcDCDrawRectangle(dc, ((float)100), ((float)100), ((float)100), ((float)50)*
 *);
   wxcDCDrawRoundedRectangle(dc, ((float)150), ((float)150), ((float)100), ((fl*
 *oat)50));
   wxcDCSetClippingRegion(dc, ((float)150), ((float)150), ((float)100), ((float*
 *)50));
   wxcDCDrawText(dc, "This text should be clipped within the rectangle", ((floa*
 *t)150), ((float)170));
   wxcDCDestroyClippingRegion(dc);
   wxcDCDrawEllipse(dc, ((float)250), ((float)250), ((float)100), ((float)50));
   wxcDCDrawLine(dc, ((float)50), ((float)230), ((float)200), ((float)230));
   wxcDCDrawText(dc, "This is a test string", ((float)50), ((float)230));
 "
;
"


void on`event(long canvas, long event)
-
 long dc;
 float x;
 float y;
 long dragging;
 dc = wxcCanvasGetDC(canvas);
 wxcDCSetPen(dc, `black`pen`);
 x = wxcMouseEventPositionX(event);
 y = wxcMouseEventPositionY(event);
 dragging = wxcMouseEventDragging(event);
 if (((`xpos`>-1) && (`ypos`>-1) && (dragging>0)))
 -
   wxcDCDrawLine(dc, `xpos`, `ypos`, x, y);
 "
;
 `xpos` = x;
 `ypos` = y;
"


long on`close(long frame)
-
 wxcWindowDelete(`subframe`);
 return 1;
 return 0;
"


void on`menu`command(long frame, long id)
-
 wxString s;
 wxString file;
 if (id == 200)
 -
   wxString(wxcMessageBox("CLIPS for wxWindows Demo by Julian Smart (c) 1993", *
 *"About wxWindows CLIPS Demo"));
 "
 else if (id == 3)
 -
   on`close(frame);
   wxcWindowDelete(frame);
 "
 else if (id == 4)
 -
   s = wxString(wxcGetChoice("Choose from the list", MakeList(new ClipsExpr(wxS*
 *tring("One")), new ClipsExpr(wxString("Two")), new ClipsExpr@
                                                                 14

________________________________________________________CHAPTER_6___
   wxcFrameSetStatusText(`main`frame`, s.GetData());
   ClipsFormat(wxString("t"), TranslateFormat(wxString("Answer was %s")),s.GetD*
 *ata());
   ClipsOpen(wxString("test.txt"), wxString("mystream"), wxString("w"));
   ClipsFormat(wxString("mystream"), TranslateFormat(wxString("The id of the me*
 *nucommand is %ld%n")),id);
   ClipsFormat(wxString("mystream"), TranslateFormat(wxString("This is a second*
 * line.")));
   ClipsClose(wxString("mystream"));
 "
 else if (id == 1)
 -
   file = wxString(wxcFileSelector("Choose a text file to load"));
   if ((file != wxString("")))
   -
     wxcTextWindowLoadFile(`text`win`, file.GetData());
   "
;
 "
;
"


void frame`button`proc(long id)
-
 long parent;
 long grandparent;
 parent = wxcWindowGetParent(id);
 grandparent = wxcWindowGetParent(parent);
 wxString(wxcMessageBox("Hello"));
"


long app`on`init(void)
-
 long file`menu;
 long pull`right;
 long help`menu;
 long menu`bar;
 long button;
 long text;
 long check;
 long choice;
 long list;
 long slider;
 long multi;
 if ((`small`font`==0))
 -
   `small`font` = wxcFontCreate(10, "wxSWISS", "wxNORMAL", "wxNORMAL", 0);
   `green`pen` = wxcPenCreate("GREEN", 1, "wxSOLID");
   `black`pen` = wxcPenCreate("BLACK", 1, "wxSOLID");
   `red`pen` = wxcPenCreate("RED", 3, "wxSOLID");
   `cyan`brush` = wxcBrushCreate("CYAN", "wxSOLID");
 "
;
 `main`frame` = wxcFrameCreate(0, "Hello wxCLIPS!", -1, -1, 500, 450);
 wxcFrameCreateStatusLine(`main`frame`);
 wxcFrameSetStatusText(`main`frame`, "Welcome to wxCLIPS");
 wxcWindowAddCallback(`main`frame`, "OnSize", (wxClipsFunction)on`size);
 wxcWindowAddCallback(`main`frame`, "OnClose", (wxClipsFunction)on`close);
 wxcWindowAddCallback(`main`frame`, "OnMenuCommand", (wxClipsFunction)on`menu`c*
 *ommand);
 file`menu = wxcMenuCreate();
 wxcMenuAppend(file`menu, 1, "&Load file");
                                                                 15

________________________________________________________CHAPTER_6___
 wxcMenuAppend(file`menu, 4, "&Test choice dialog");
 pull`right = wxcMenuCreate();
 wxcMenuAppend(pull`right, 100, "&Twips");
 wxcMenuAppend(pull`right, 101, "&10th mm");
 wxcMenuAppend(file`menu, 2, "&Scale picture", pull`right);
 wxcMenuAppendSeparator(file`menu);
 wxcMenuAppend(file`menu, 3, "&Quit");
 help`menu = wxcMenuCreate();
 wxcMenuAppend(help`menu, 200, "&About");
 menu`bar = wxcMenuBarCreate();
 wxcMenuBarAppend(menu`bar, file`menu, "&File");
 wxcMenuBarAppend(menu`bar, help`menu, "&Help");
 wxcFrameSetMenuBar(`main`frame`, menu`bar);
 `panel` = wxcPanelCreate(`main`frame`, 0, 0, 500, 250);
 wxcPanelSetLabelPosition(`panel`, "wxVERTICAL");
 `text`win` = wxcTextWindowCreate(`main`frame`, 0, 250, 500, 300);
 button = wxcButtonCreate(`panel`, (wxClipsFunction)frame`button`proc, "A butto*
 *n");
 text = wxcTextCreate(`panel`, (wxClipsFunction)NULL, "A text item", "Initial v*
 *alue", -1, -1, 200);
 check = wxcCheckBoxCreate(`panel`, (wxClipsFunction)NULL, "A check box");
 wxcPanelNewLine(`panel`);
 choice = wxcChoiceCreate(`panel`, (wxClipsFunction)NULL, "A choice item");
 wxcChoiceAppend(choice, "One");
 wxcChoiceAppend(choice, "Two");
 wxcChoiceAppend(choice, "Three");
 wxcChoiceAppend(choice, "Four");
 wxcMessageCreate(`panel`, "Hello! A simple message");
 list = wxcListBoxCreate(`panel`, (wxClipsFunction)NULL, "A list", 0, -1, -1, 1*
 *00, 100);
 wxcListBoxAppend(list, "Apple");
 wxcListBoxAppend(list, "Pear");
 wxcListBoxAppend(list, "Orange");
 wxcListBoxAppend(list, "Banana");
 wxcListBoxAppend(list, "Fruit");
 wxcPanelNewLine(`panel`);
 slider = wxcSliderCreate(`panel`, (wxClipsFunction)NULL, "A slider", 40, 22, 1*
 *01, 150);
 multi = wxcMultiTextCreate(`panel`, (wxClipsFunction)NULL, "Multiline text", "*
 *Some text");
 wxcTextWindowLoadFile(`text`win`, "hello.clp");
 `subframe` = wxcFrameCreate(0, "Canvas Frame", 300, 300, 400, 400);
 `canvas` = wxcCanvasCreate(`subframe`, 0, 0, 400, 400);
 wxcWindowAddCallback(`canvas`, "OnPaint", (wxClipsFunction)on`paint);
 wxcWindowAddCallback(`canvas`, "OnEvent", (wxClipsFunction)on`event);
 wxcCanvasSetScrollbars(`canvas`, 20, 20, 50, 50, 4, 4);
 wxcWindowShow(`subframe`, 1);
 wxcWindowShow(`main`frame`, 1);
 return `main`frame`;
 return 0;
"


/*
 * Top-level statements
 */


void ExecuteClipsStatements(void)
-
"


/*
 * Initialization function called by HARDY
 */
                                                                 16

________________________________________________________CHAPTER_6___


void InitializeCustomCode(void)
-
 ExecuteClipsStatements();
"

                                                                 17

_________________________________________________________GLOSSARY___



Glossary


CLIPS  Rule-based, functional and object-oriented toolkit from NASA, avail-
     able for free or low cost. It is written in C and may be easily integrated
     into C or C++ applications.

GUI  Graphical User Interface, such as Windows 3 or X.

HARDY    HARDY is a hypertext-based diagramming tool developed at AIAI.
     Written in C++ using wxWindows, and using CLIPS as an embedded
     extension language, it runs under Windows, Open Look and Motif.  It
     has been used for a variety of applications including systems analysis,
     knowledge acquisition, belief network analysis, process modelling, quality
     procedures acquisition, and AI planner interfacing.

HTML   Hypertext Markup Language; an SGML document type, used for pro-
     viding hypertext information on the World Wide Web, a distributed hy-
     pertext system on the Internet.

LaTEX A typesetting language implemented as a set of TEX macros. It is distin-
     guished for allowing specification of the document structure, whilst taking
     care of most layout concerns. It represents the opposite end of the spec-
     trum from WYSIWYG word processors.

Open Look  A specification for a GUI `look and feel', initiated by Sun Mi-
     crosystems.  XView is one toolkit for writing Open Look applications
     under X, and wxWindows sits on top of XView.

RTF  Rich Text Format: an interchange format for word processor files, used
     for importing and exporting formatted documents, and as the input to
     the Windows Help compiler.

wxCLIPS   GUI extensions to CLIPS, available for free from AIAI.

wxHelp  wxHelp is the hypertext help facility used to provide on-line doc-
     umentation for UNIX-based wxWindows applications.  Under Windows
     3.1, Windows Help is used instead.

wxWindows   wxWindows is a free C++ toolkit for writing applications that
     are portable across several platforms.  Currently these are Motif, Open
     Look, Windows 3.1 and Windows NT.

XView  An X toolkit supplied by Sun Microsystems, initially just for porting
     SunView applications to X, but which has become a popular toolkit in
     its own right due to its simplicity of use. XView implements Sun's Open
     Look `look and feel' for X, but is not the only toolkit to do so.



                                                                 18
