home *** CD-ROM | disk | FTP | other *** search
/ Internet Info 1997 December / Internet_Info_CD-ROM_Walnut_Creek_December_1997.iso / faqs / comp / answers / Objective-C / sample < prev   
Encoding:
Text File  |  1997-10-19  |  24.3 KB  |  966 lines

  1. Path: senator-bedfellow.mit.edu!bloom-beacon.mit.edu!boulder!csnews!coop.net!su-news-feed4.bbnplanet.com!su-news-hub1.bbnplanet.com!cpk-news-hub1.bbnplanet.com!news.bbnplanet.com!newsfeed.internetmci.com!192.87.106.104!surfnet.nl!news.tue.nl!usenet
  2. From: tiggr@es.ele.tue.nl (Pieter J. Schoenmakers)
  3. Newsgroups: comp.lang.objective-c,comp.answers,news.answers,comp.sys.mac.programmer.info
  4. Subject: comp.lang.objective-c FAQ, part 3/3: A Sample Program
  5. Supersedes: <sample_874860434@es.ele.tue.nl>
  6. Followup-To: comp.lang.objective-c
  7. Date: 17 Oct 1997 21:37:32 GMT
  8. Organization: Eindhoven University of Technology
  9. Lines: 948
  10. Approved: news-answers-request@mit.edu
  11. Expires: 26 Nov 1997 21:36:26 GMT
  12. Message-ID: <sample_877124186@es.ele.tue.nl>
  13. Reply-To: tiggr@ics.ele.tue.nl
  14. NNTP-Posting-Host: cobra.ics.ele.tue.nl
  15. Summary: This third part of the comp.lang.objective-c FAQ postings
  16.         presents a simple sample program written in Objective-C.
  17. Xref: senator-bedfellow.mit.edu comp.lang.objective-c:7335 comp.answers:28595 news.answers:114940 comp.sys.mac.programmer.info:677
  18.  
  19. Archive-name: Objective-C/sample
  20. Version: $Id: sample.preamble,v 3.10 1997/08/11 19:32:34 tiggr Exp $
  21.  
  22.         A simple sample
  23.         Objective-C program
  24.  
  25.  
  26. This is the third part in a series of three informational postings
  27. concerning comp.lang.objective-c.  This article presents a simple program
  28. written in Objective-C.  The program consist of several files which are
  29. contained in a shar file (see instructions below on how to unpack).  [Note,
  30. from version 2.3 of this file, the sample has been changed in order to
  31. reduce the number of compiler warnings (down to 1, which is in there for
  32. explanatory purposes) and to reflect the use of `+alloc' and `-init' instead
  33. of `+new'.]
  34.  
  35. The early version of this FAQ was compiled by Bill Shirley, with the aid of
  36. many people.  The current version is being maintained by Pieter Schoenmakers
  37. <tiggr@ics.ele.tue.nl>, aided by a lot of people, including Paul Sanchez and
  38. Bill Shirley.
  39.  
  40. A World Wide Web hypertext version of this FAQ is maintained by Steve Dekorte
  41. <dekorte@suite.com> at http://www.slip.net/~dekorte/Objective-C/.
  42. A Japanese language version of this FAQ, maintained by Norihiro Itoh
  43. <nito@fsinet.or.jp>, resides at http://www.fsinet.or.jp/~nito/index-j.html.
  44.  
  45. Send your suggestions, additions, bug reports, comments and fixes to
  46. `tiggr@ics.ele.tue.nl'.
  47.  
  48. #---------------------------------- cut here ----------------------------------
  49. # This is a shell archive.  Remove anything before this line,
  50. # then unpack it by saving it in a file and typing "sh file".
  51. #
  52. # Wrapped by Pieter Schoenmakers <tiggr@cobra> on Wed Oct  8 08:50:55 1997
  53. #
  54. # This archive contains:
  55. #    objc-sample    
  56. #
  57. # Existing files will not be overwritten.
  58. # Error checking via wc(1) will be performed.
  59.  
  60. LANG=""; export LANG
  61. PATH=/bin:/usr/bin:$PATH; export PATH
  62.  
  63. echo mkdir - objc-sample
  64. mkdir objc-sample
  65.  
  66. if test -f objc-sample/Char.h
  67. then
  68.     echo Ok to overwrite existing file objc-sample/Char.h\?
  69.     read answer
  70.     case "$answer" in
  71.     [yY]*)    echo Proceeding;;
  72.     *)    echo Aborting; exit 1;;
  73.     esac
  74.     rm -f objc-sample/Char.h
  75.     if test -f objc-sample/Char.h
  76.     then
  77.         echo Error: could not remove objc-sample/Char.h, aborting
  78.         exit 1
  79.     fi
  80. fi
  81. echo x - objc-sample/Char.h
  82. cat >objc-sample/Char.h <<'__EOF__'
  83. #import <objc/Object.h>
  84.  
  85. @interface Char: Object
  86. {
  87.   int value;
  88. }
  89.  
  90. -init: (int) x;
  91. -report;
  92.  
  93. @end
  94. __EOF__
  95. set `wc -lwc <objc-sample/Char.h`
  96. if test $1$2$3 != 111498
  97. then
  98.     echo ERROR: wc results of objc-sample/Char.h are $* should be 11 14 98
  99. fi
  100.  
  101. chmod 644 objc-sample/Char.h
  102.  
  103. if test -f objc-sample/Char.m
  104. then
  105.     echo Ok to overwrite existing file objc-sample/Char.m\?
  106.     read answer
  107.     case "$answer" in
  108.     [yY]*)    echo Proceeding;;
  109.     *)    echo Aborting; exit 1;;
  110.     esac
  111.     rm -f objc-sample/Char.m
  112.     if test -f objc-sample/Char.m
  113.     then
  114.         echo Error: could not remove objc-sample/Char.m, aborting
  115.         exit 1
  116.     fi
  117. fi
  118. echo x - objc-sample/Char.m
  119. cat >objc-sample/Char.m <<'__EOF__'
  120. #import <stdio.h>
  121. #import "Char.h"
  122.  
  123. @implementation Char
  124. {
  125.   int value;
  126. }
  127.  
  128. - init: (int) x
  129. {
  130.   [super init];        // In case the parent class is doing
  131.               // something special in its init...
  132.   value = x;
  133.   return self;
  134. }
  135.  
  136. - report
  137. {
  138.   printf("   %c", value);
  139.   return self;
  140. }
  141.  
  142. @end
  143. __EOF__
  144. set `wc -lwc <objc-sample/Char.m`
  145. if test $1$2$3 != 2347279
  146. then
  147.     echo ERROR: wc results of objc-sample/Char.m are $* should be 23 47 279
  148. fi
  149.  
  150. chmod 644 objc-sample/Char.m
  151.  
  152. if test -f objc-sample/Float.h
  153. then
  154.     echo Ok to overwrite existing file objc-sample/Float.h\?
  155.     read answer
  156.     case "$answer" in
  157.     [yY]*)    echo Proceeding;;
  158.     *)    echo Aborting; exit 1;;
  159.     esac
  160.     rm -f objc-sample/Float.h
  161.     if test -f objc-sample/Float.h
  162.     then
  163.         echo Error: could not remove objc-sample/Float.h, aborting
  164.         exit 1
  165.     fi
  166. fi
  167. echo x - objc-sample/Float.h
  168. cat >objc-sample/Float.h <<'__EOF__'
  169. #import <objc/Object.h>
  170.  
  171. @interface Float: Object
  172. {
  173.   float value;
  174. }
  175.  
  176. -initFloatValue: (float) x;
  177. -report;
  178.  
  179. @end
  180. __EOF__
  181. set `wc -lwc <objc-sample/Float.h`
  182. if test $1$2$3 != 1114113
  183. then
  184.     echo ERROR: wc results of objc-sample/Float.h are $* should be 11 14 113
  185. fi
  186.  
  187. chmod 644 objc-sample/Float.h
  188.  
  189. if test -f objc-sample/Float.m
  190. then
  191.     echo Ok to overwrite existing file objc-sample/Float.m\?
  192.     read answer
  193.     case "$answer" in
  194.     [yY]*)    echo Proceeding;;
  195.     *)    echo Aborting; exit 1;;
  196.     esac
  197.     rm -f objc-sample/Float.m
  198.     if test -f objc-sample/Float.m
  199.     then
  200.         echo Error: could not remove objc-sample/Float.m, aborting
  201.         exit 1
  202.     fi
  203. fi
  204. echo x - objc-sample/Float.m
  205. cat >objc-sample/Float.m <<'__EOF__'
  206. #import <stdio.h>
  207. #import "Float.h"
  208.  
  209. @implementation Float
  210. {
  211.   float value;
  212. }
  213.  
  214. -initFloatValue: (float) x
  215. {
  216.   [super init];
  217.   value = x;
  218.   return self;
  219. }
  220.  
  221. -report
  222. {
  223.   printf ("%4.1f", value);
  224.   return self;
  225. }
  226.  
  227. @end
  228. __EOF__
  229. set `wc -lwc <objc-sample/Float.m`
  230. if test $1$2$3 != 2231215
  231. then
  232.     echo ERROR: wc results of objc-sample/Float.m are $* should be 22 31 215
  233. fi
  234.  
  235. chmod 644 objc-sample/Float.m
  236.  
  237. if test -f objc-sample/Makefile
  238. then
  239.     echo Ok to overwrite existing file objc-sample/Makefile\?
  240.     read answer
  241.     case "$answer" in
  242.     [yY]*)    echo Proceeding;;
  243.     *)    echo Aborting; exit 1;;
  244.     esac
  245.     rm -f objc-sample/Makefile
  246.     if test -f objc-sample/Makefile
  247.     then
  248.         echo Error: could not remove objc-sample/Makefile, aborting
  249.         exit 1
  250.     fi
  251. fi
  252. echo x - objc-sample/Makefile
  253. cat >objc-sample/Makefile <<'__EOF__'
  254. # This Makefile assumes you have GNU gcc 2.3 or better and a suitable
  255. # runtime library with object support.  It also works on a NeXT.
  256. # Don't know about Stepstone.
  257.  
  258. .SUFFIXES: .o .m
  259. .m.o:
  260.     $(CC) -c $(CFLAGS) $<
  261.  
  262. # Use this on a NeXT
  263. #CC=        cc
  264. #LIBS=        
  265. # Use this with GNU CC on a non-NeXT,
  266. # and avoid the GCC moaning on using #import.
  267. CC=        gcc -Wno-import
  268. LIBS=        -lobjc
  269. LDFLAGS=    -L/usr/local/lib -L/usr/gnu/lib
  270.  
  271. CFLAGS=        -Wall -g
  272. OFILES=        main.o Node.o Queue.o Stack.o Float.o Char.o
  273.  
  274. demo: $(OFILES)
  275.     $(CC) $(CFLAGS) $(LDFLAGS) -o demo $(OFILES) $(LIBS)
  276.  
  277. clean:
  278.     rm -f $(OFILES) demo
  279.     
  280. Char.o : Char.m Char.h 
  281.  
  282. Float.o : Float.m Float.h 
  283.  
  284. Node.o : Node.m Node.h 
  285.  
  286. Queue.o : Queue.m Queue.h Node.h 
  287.  
  288. Stack.o : Stack.m Stack.h Node.h 
  289.  
  290. main.o : main.m Queue.h Node.h Stack.h Float.h
  291. __EOF__
  292. set `wc -lwc <objc-sample/Makefile`
  293. if test $1$2$3 != 37127783
  294. then
  295.     echo ERROR: wc results of objc-sample/Makefile are $* should be 37 127 783
  296. fi
  297.  
  298. chmod 644 objc-sample/Makefile
  299.  
  300. if test -f objc-sample/Node.h
  301. then
  302.     echo Ok to overwrite existing file objc-sample/Node.h\?
  303.     read answer
  304.     case "$answer" in
  305.     [yY]*)    echo Proceeding;;
  306.     *)    echo Aborting; exit 1;;
  307.     esac
  308.     rm -f objc-sample/Node.h
  309.     if test -f objc-sample/Node.h
  310.     then
  311.         echo Error: could not remove objc-sample/Node.h, aborting
  312.         exit 1
  313.     fi
  314. fi
  315. echo x - objc-sample/Node.h
  316. cat >objc-sample/Node.h <<'__EOF__'
  317. #import <objc/Object.h>
  318.  
  319. @interface Node : Object
  320. {
  321.   id next;
  322.   id data;
  323. }
  324.  
  325. -init: anItem;        // create a Node and store anItem in it
  326. -free;            // free a Node and return the item in it
  327. -next;            // report the id of the next node after this one
  328. -setNext: aNode;    // make the next node be aNode
  329.  
  330. @end
  331. __EOF__
  332. set `wc -lwc <objc-sample/Node.h`
  333. if test $1$2$3 != 1456295
  334. then
  335.     echo ERROR: wc results of objc-sample/Node.h are $* should be 14 56 295
  336. fi
  337.  
  338. chmod 644 objc-sample/Node.h
  339.  
  340. if test -f objc-sample/Node.m
  341. then
  342.     echo Ok to overwrite existing file objc-sample/Node.m\?
  343.     read answer
  344.     case "$answer" in
  345.     [yY]*)    echo Proceeding;;
  346.     *)    echo Aborting; exit 1;;
  347.     esac
  348.     rm -f objc-sample/Node.m
  349.     if test -f objc-sample/Node.m
  350.     then
  351.         echo Error: could not remove objc-sample/Node.m, aborting
  352.         exit 1
  353.     fi
  354. fi
  355. echo x - objc-sample/Node.m
  356. cat >objc-sample/Node.m <<'__EOF__'
  357. #import <objc/Object.h>
  358. #import "Node.h"
  359.  
  360. @implementation    Node: Object
  361.  
  362. -init: anItem
  363. {
  364.   self = [super init];
  365.   next = 0;
  366.   data = anItem;
  367.   return self;
  368. }
  369.  
  370. -free
  371. {
  372.   id tmp = data;
  373.   [super free];
  374.   return tmp;
  375. }
  376.  
  377. -next
  378. {
  379.   return next;
  380. }
  381.  
  382. -setNext: aNode
  383. {
  384.   next = aNode;
  385.   return self;
  386. }
  387.  
  388. @end
  389. __EOF__
  390. set `wc -lwc <objc-sample/Node.m`
  391. if test $1$2$3 != 3249299
  392. then
  393.     echo ERROR: wc results of objc-sample/Node.m are $* should be 32 49 299
  394. fi
  395.  
  396. chmod 644 objc-sample/Node.m
  397.  
  398. if test -f objc-sample/Queue.h
  399. then
  400.     echo Ok to overwrite existing file objc-sample/Queue.h\?
  401.     read answer
  402.     case "$answer" in
  403.     [yY]*)    echo Proceeding;;
  404.     *)    echo Aborting; exit 1;;
  405.     esac
  406.     rm -f objc-sample/Queue.h
  407.     if test -f objc-sample/Queue.h
  408.     then
  409.         echo Error: could not remove objc-sample/Queue.h, aborting
  410.         exit 1
  411.     fi
  412. fi
  413. echo x - objc-sample/Queue.h
  414. cat >objc-sample/Queue.h <<'__EOF__'
  415. #import <objc/Object.h>
  416. #import "Node.h"
  417.  
  418. @interface Queue: Object
  419. {
  420.   id head;
  421.   id tail;
  422.   unsigned qsize;
  423. }
  424.  
  425. -empty;            // clear out all contents of the Queue
  426. -put: anItem;        // put anItem on the Queue
  427. -get;            // return the item on top of the Queue
  428. -(unsigned int) size;    // tell us the current size of the Queue
  429.  
  430. @end
  431. __EOF__
  432. set `wc -lwc <objc-sample/Queue.h`
  433. if test $1$2$3 != 1655319
  434. then
  435.     echo ERROR: wc results of objc-sample/Queue.h are $* should be 16 55 319
  436. fi
  437.  
  438. chmod 644 objc-sample/Queue.h
  439.  
  440. if test -f objc-sample/Queue.m
  441. then
  442.     echo Ok to overwrite existing file objc-sample/Queue.m\?
  443.     read answer
  444.     case "$answer" in
  445.     [yY]*)    echo Proceeding;;
  446.     *)    echo Aborting; exit 1;;
  447.     esac
  448.     rm -f objc-sample/Queue.m
  449.     if test -f objc-sample/Queue.m
  450.     then
  451.         echo Error: could not remove objc-sample/Queue.m, aborting
  452.         exit 1
  453.     fi
  454. fi
  455. echo x - objc-sample/Queue.m
  456. cat >objc-sample/Queue.m <<'__EOF__'
  457. #import "Queue.h"
  458.  
  459. @implementation    Queue
  460.  
  461. -empty
  462. {
  463.   while([self size])
  464.     [[self get] free];
  465.   return self;
  466. }
  467.  
  468. -put: anItem
  469. {
  470.   if (tail)
  471.     tail = [[tail setNext : [[Node alloc] init: anItem]] next];
  472.   else
  473.     head = tail = [[Node alloc] init: anItem];
  474.   ++qsize;
  475.   return self;
  476. }
  477.  
  478. -get
  479. {
  480.   id contents;
  481.   id old_head = head;
  482.  
  483.   head = [head next];
  484.   contents = [old_head free];
  485.   if (--qsize == 0)
  486.     tail = head;
  487.   return contents;
  488. }
  489.  
  490. -(unsigned) size
  491. {
  492.   return qsize;
  493. }
  494.  
  495. @end
  496. __EOF__
  497. set `wc -lwc <objc-sample/Queue.m`
  498. if test $1$2$3 != 3975486
  499. then
  500.     echo ERROR: wc results of objc-sample/Queue.m are $* should be 39 75 486
  501. fi
  502.  
  503. chmod 644 objc-sample/Queue.m
  504.  
  505. if test -f objc-sample/README
  506. then
  507.     echo Ok to overwrite existing file objc-sample/README\?
  508.     read answer
  509.     case "$answer" in
  510.     [yY]*)    echo Proceeding;;
  511.     *)    echo Aborting; exit 1;;
  512.     esac
  513.     rm -f objc-sample/README
  514.     if test -f objc-sample/README
  515.     then
  516.         echo Error: could not remove objc-sample/README, aborting
  517.         exit 1
  518.     fi
  519. fi
  520. echo x - objc-sample/README
  521. cat >objc-sample/README <<'__EOF__'
  522. This directory contains the complete code for the "Simple Sample Objective-C
  523. program" described in the comp.lang.objective-c FAQ.  If you have a suitable
  524. compiler, use the supplied Makefile.  Otherwise, program output can be found
  525. in the file "output".
  526.  
  527. You should probably read "main.m" first.  It is very heavily annotated.
  528.  
  529. Also note and read the file COPYRIGHT.
  530. __EOF__
  531. set `wc -lwc <objc-sample/README`
  532. if test $1$2$3 != 855366
  533. then
  534.     echo ERROR: wc results of objc-sample/README are $* should be 8 55 366
  535. fi
  536.  
  537. chmod 644 objc-sample/README
  538.  
  539. if test -f objc-sample/Stack.h
  540. then
  541.     echo Ok to overwrite existing file objc-sample/Stack.h\?
  542.     read answer
  543.     case "$answer" in
  544.     [yY]*)    echo Proceeding;;
  545.     *)    echo Aborting; exit 1;;
  546.     esac
  547.     rm -f objc-sample/Stack.h
  548.     if test -f objc-sample/Stack.h
  549.     then
  550.         echo Error: could not remove objc-sample/Stack.h, aborting
  551.         exit 1
  552.     fi
  553. fi
  554. echo x - objc-sample/Stack.h
  555. cat >objc-sample/Stack.h <<'__EOF__'
  556. #import <objc/Object.h>
  557. #import "Node.h"
  558.  
  559. @interface Stack: Object
  560. {
  561.   id stack;
  562.   unsigned int stack_size;
  563. }
  564.  
  565. -empty;                // clear out all contents of the Stack
  566. -put: anItem;            // put anItem on the Stack
  567. -get;                // return the item on top of the Stack
  568. -(unsigned) size;        // tell us the current size of the Stack
  569.  
  570. @end
  571. __EOF__
  572. set `wc -lwc <objc-sample/Stack.h`
  573. if test $1$2$3 != 1553318
  574. then
  575.     echo ERROR: wc results of objc-sample/Stack.h are $* should be 15 53 318
  576. fi
  577.  
  578. chmod 644 objc-sample/Stack.h
  579.  
  580. if test -f objc-sample/Stack.m
  581. then
  582.     echo Ok to overwrite existing file objc-sample/Stack.m\?
  583.     read answer
  584.     case "$answer" in
  585.     [yY]*)    echo Proceeding;;
  586.     *)    echo Aborting; exit 1;;
  587.     esac
  588.     rm -f objc-sample/Stack.m
  589.     if test -f objc-sample/Stack.m
  590.     then
  591.         echo Error: could not remove objc-sample/Stack.m, aborting
  592.         exit 1
  593.     fi
  594. fi
  595. echo x - objc-sample/Stack.m
  596. cat >objc-sample/Stack.m <<'__EOF__'
  597. #import "Stack.h"
  598.  
  599. @implementation    Stack
  600.  
  601. -empty
  602. {
  603.   while([self size])
  604.     [[self get] free];
  605.   return self;
  606. }
  607.  
  608. -put: anItem
  609. {
  610.   stack = [[[Node alloc] init: anItem] setNext : stack];
  611.   ++stack_size;
  612.   return self;
  613. }
  614.  
  615. -get
  616. {
  617.   id contents;
  618.   id old_stack = stack;
  619.  
  620.   stack = [stack next];
  621.   contents = [old_stack free];
  622.   --stack_size;
  623.   return contents;
  624. }
  625.  
  626. -(unsigned) size
  627. {
  628.   return stack_size;
  629. }
  630.  
  631. @end
  632. __EOF__
  633. set `wc -lwc <objc-sample/Stack.m`
  634. if test $1$2$3 != 3557407
  635. then
  636.     echo ERROR: wc results of objc-sample/Stack.m are $* should be 35 57 407
  637. fi
  638.  
  639. chmod 644 objc-sample/Stack.m
  640.  
  641. if test -f objc-sample/main.m
  642. then
  643.     echo Ok to overwrite existing file objc-sample/main.m\?
  644.     read answer
  645.     case "$answer" in
  646.     [yY]*)    echo Proceeding;;
  647.     *)    echo Aborting; exit 1;;
  648.     esac
  649.     rm -f objc-sample/main.m
  650.     if test -f objc-sample/main.m
  651.     then
  652.         echo Error: could not remove objc-sample/main.m, aborting
  653.         exit 1
  654.     fi
  655. fi
  656. echo x - objc-sample/main.m
  657. cat >objc-sample/main.m <<'__EOF__'
  658. /* main.m - comp.lang.objective-c simple sample Objective-C program.  */
  659.  
  660. // This is a comment, just like the previous line.  Everything to the right
  661. // of a double slash is ignored.
  662.  
  663. /* Classes are the one real extension which Objective-C adds to C.  A class
  664.    is a description of a collection of data, like a C structure, and the
  665.    methods by which that data may be accessed or manipulated.  Instances of
  666.    a class are called objects, and methods are invoked by sending messages
  667.    to either the class itself, to produce objects, or to those objects.  The
  668.    recipient of a message is called a "receiver".  The form of a message is:
  669.  
  670.     [receiver method andMaybeSomeArguments]
  671.  
  672.    the receiver and method components are mandatory, as are the square
  673.    brackets surrounding the message.  Additional arguments may or may not be
  674.    present, depending upon the method definition.  Messages may appear
  675.    anywhere a statement is allowed in C.
  676.  
  677.    The first thing we do is bring in some include files, as in C.  On the
  678.    NeXT, it is customary to use the "import" statement which guarantees that
  679.    the file isn't included more than once.  Using GNU CC this is not all
  680.    that nice sinds it generates a huge warning for every file being
  681.    compiled.  So, since it does not really matter, we'll stick to
  682.    `#include'.  */
  683.  
  684. #import <stdio.h>
  685. #import <objc/Object.h>
  686. #import "Queue.h"
  687. #import "Stack.h"
  688.  
  689. /* That brought in class definitions for Objects, Queues, and Stacks.  The
  690.    Object class is the basis for all other classes, which is why it gets
  691.    brought in first.  It provides basic functional behavior which is
  692.    inherited by all derived classes.  All user created classes normally have
  693.    Object somewhere in their ancestry.
  694.  
  695.    Queue and Stack are classes of our own construction, and provide FIFO and
  696.    LIFO storage capabilities, respectively.  I'm not going to go into
  697.    implementation details here.  It's irrelevant how they work, all that is
  698.    important is that they both respond to 'put:' and 'get'.  If you want to
  699.    inspect them, look into the Queue.m, Stack.m, Queue.h and Stack.h files.
  700.  
  701.    A simple Class definition follows.  It inherits directly from the base
  702.    class "Object".  This gives it lots of nice properties, not the least of
  703.    which is the ability to be referenced by any pointer of the generic
  704.    object type "id".  All objects can be pointed to by any id variable, and
  705.    the default return type from methods is id.  This allows messages to be
  706.    embedded in other messages, either as receivers or arguments.
  707.  
  708.    An Int object allocates space for a single integer.  The "report" message
  709.    causes it to report its value.  Everything between the @implementation
  710.    and the @end is part of the class definition.
  711.  
  712.    Note - It is *highly* unusual to have a class implementation in your main
  713.    program.  Since the object is fully defined before it gets used, no
  714.    interface description is required.  There is nothing illegal about doing
  715.    things this way, but it is so unusual that the compiler will produce a
  716.    warning for this class.  The Int class implementation is here solely for
  717.    expository purposes.  */
  718.  
  719. @implementation Int: Object    // Int is derived from Object
  720. {
  721.     int value;        // This is the data portion.  Like a struct.
  722. }
  723.  
  724. /* The following are the method definitions.  A `+' prefix means it is a
  725.    factory method, i.e., how to manufacture instances of the class.  The
  726.    body of the method is between braces, like a C function.
  727.  
  728.    This class doesn't define any factory methods.  It relies on the +alloc
  729.    method defined in class Object.  For examples of factory methods, look at
  730.    the +new method defined in the Stack or Queue implementations.
  731.  
  732.    Self is a special variable, which refers to the object currently being
  733.    manipulated.  Super refers to the parent class of self.  The following
  734.    method asks the parent class (Object) to hand us a new instance, which
  735.    becomes self.  Then we update the instance variables and return a pointer
  736.    to the new object.
  737.  
  738.    It is standard for methods that do not need to return any special value
  739.    to instead return self.  This allows for a nested syntax of method calls.
  740.  
  741.    The "-" in front of init means that it's an instance method, i.e.,
  742.    something a particular object should respond to.  */
  743.  
  744. -init: (int) i
  745. {
  746.   /* Have our superclass initialize its part of us.  After that,
  747.      initialize the part of us introduced by this class (Int).  */
  748.   [super init];
  749.   value = i;
  750.   return self;
  751. }
  752.  
  753. -report
  754. {
  755.   printf ("%4d", value);
  756.   return self;
  757. }
  758.  
  759. @end
  760.  
  761. /* We have implemented Float and Char classes more traditionally, using
  762.    separate files for the interface (.h) and implementation (.m).  The Float
  763.    and Char objects are like the Int object, but with the obvious difference
  764.    that they work with floats and characters.  We include the interface
  765.    definitions at this point.  */
  766.  
  767. #import "Float.h"
  768. #import "Char.h"
  769.  
  770. /* If you inspect those files, note polymorphism -- methods have same
  771.    names as in the Int class.  */
  772.  
  773. int main (void)
  774. {
  775.     /* First create instances of "Stack" and "Queue" data structures.  */
  776.     id queue = [[Queue alloc] init];
  777.     id stack = [[Stack alloc] init];
  778.     int i, reply;
  779.     
  780.     fprintf (stderr, "Include the Char class in the demo? (y/n): ");
  781.  
  782.     /* Anything not matching `y.*' means no.  */
  783.     reply = getchar ();
  784.  
  785.     for (i = 5; i > -6; --i)
  786.       {
  787.     /* Depending on which version of the demo we're running, we
  788.        alternately put Ints and Floats onto the queue and stack, or
  789.        Ints, Floats, and Chars.  */
  790.     if (reply == 'y')
  791.       {
  792.         /* If I is odd we put an Int on the queue and a Char on the
  793.            stack.  If I is even we put an Char on the queue and a Float
  794.            on the stack.
  795.  
  796.            Since there is more than one method `-init:' and since
  797.            `+alloc' returns a plain, typeless, `id', the compiler
  798.            doesn't know the type of the object returned by alloc.  An
  799.            explicit cast (i.e. static type indication) ensures that the
  800.            compiler knows which `init:' is invoked---the one accepting a
  801.            char or the other one accepting an int.
  802.  
  803.            Another solution, which avoids the static type indication, is
  804.            to put typing information on the method in the method's name.
  805.            This is done for the Float class.  */
  806.         id my_char = [(Char *) [Char alloc] init: 'm' + i];
  807.  
  808.         if (i & 1)
  809.           {
  810.         [queue put: [(Int *) [Int alloc] init: i]];
  811.         [stack put: my_char];
  812.           }
  813.         else
  814.           {
  815.         [queue put: my_char];
  816.         [stack put: [[Float alloc] initFloatValue: i]];
  817.           }
  818.           }
  819.     else
  820.       {
  821.         /* If I is odd we put an Int on the queue and a Float on the
  822.            stack.  If I is even we put a Float on the queue and an Int
  823.            on the stack.  */
  824.             [queue put: ((i & 1)
  825.              ? [(Int *) [Int alloc] init: i]
  826.              : [[Float alloc] initFloatValue: i])];
  827.             [stack put: ((i & 1)
  828.              ? [[Float alloc] initFloatValue: i]
  829.              : [(Int*) [Int alloc] init: i])];
  830.     }
  831.     }
  832.  
  833.     while ([queue size] && [stack size])
  834.       {
  835.     /* The following illustrates run-time binding.  Will report be
  836.        invoked for a Float object or an Int object?  Did the user elect
  837.        for Char objects at run time?  We don't know ahead of time, but
  838.        with run-time binding and polymorphism it works properly.  The
  839.        burden is on the class implementer rather than the class user.
  840.  
  841.        Note that the following lines remain unchanged, whether we are
  842.        using the Char class or not.  The queue and stack hand us the
  843.        next object, it reports itself regardless of its type, and then
  844.        it frees itself.  */
  845.  
  846.     printf ("queue:");
  847.     [[[queue get] report] free];
  848.     printf (", stack:");
  849.     [[[stack get] report] free];
  850.     putchar('\n');
  851.       }
  852.   return 0;
  853. }
  854. __EOF__
  855. set `wc -lwc <objc-sample/main.m`
  856. if test $1$2$3 != 19612587741
  857. then
  858.     echo ERROR: wc results of objc-sample/main.m are $* should be 196 1258 7741
  859. fi
  860.  
  861. chmod 644 objc-sample/main.m
  862.  
  863. if test -f objc-sample/output
  864. then
  865.     echo Ok to overwrite existing file objc-sample/output\?
  866.     read answer
  867.     case "$answer" in
  868.     [yY]*)    echo Proceeding;;
  869.     *)    echo Aborting; exit 1;;
  870.     esac
  871.     rm -f objc-sample/output
  872.     if test -f objc-sample/output
  873.     then
  874.         echo Error: could not remove objc-sample/output, aborting
  875.         exit 1
  876.     fi
  877. fi
  878. echo x - objc-sample/output
  879. cat >objc-sample/output <<'__EOF__'
  880. Output from demo, excluding Char class:
  881.  
  882. Include the Char class in the demo? (y/n): n
  883. queue:   5, stack:-5.0
  884. queue: 4.0, stack:  -4
  885. queue:   3, stack:-3.0
  886. queue: 2.0, stack:  -2
  887. queue:   1, stack:-1.0
  888. queue: 0.0, stack:   0
  889. queue:  -1, stack: 1.0
  890. queue:-2.0, stack:   2
  891. queue:  -3, stack: 3.0
  892. queue:-4.0, stack:   4
  893. queue:  -5, stack: 5.0
  894.  
  895. Output from demo, including Char class:
  896.  
  897. Include the Char class in the demo? (y/n): y
  898. queue:   5, stack:   h
  899. queue:   q, stack:-4.0
  900. queue:   3, stack:   j
  901. queue:   o, stack:-2.0
  902. queue:   1, stack:   l
  903. queue:   m, stack: 0.0
  904. queue:  -1, stack:   n
  905. queue:   k, stack: 2.0
  906. queue:  -3, stack:   p
  907. queue:   i, stack: 4.0
  908. queue:  -5, stack:   r
  909. __EOF__
  910. set `wc -lwc <objc-sample/output`
  911. if test $1$2$3 != 29111679
  912. then
  913.     echo ERROR: wc results of objc-sample/output are $* should be 29 111 679
  914. fi
  915.  
  916. chmod 644 objc-sample/output
  917.  
  918. if test -f objc-sample/COPYRIGHT
  919. then
  920.     echo Ok to overwrite existing file objc-sample/COPYRIGHT\?
  921.     read answer
  922.     case "$answer" in
  923.     [yY]*)    echo Proceeding;;
  924.     *)    echo Aborting; exit 1;;
  925.     esac
  926.     rm -f objc-sample/COPYRIGHT
  927.     if test -f objc-sample/COPYRIGHT
  928.     then
  929.         echo Error: could not remove objc-sample/COPYRIGHT, aborting
  930.         exit 1
  931.     fi
  932. fi
  933. echo x - objc-sample/COPYRIGHT
  934. cat >objc-sample/COPYRIGHT <<'__EOF__'
  935. This copyright notice applies to all source files distributed in the
  936. comp.lang.objective-c FAQ: `A Simple Sample Objective-C program'.
  937.  
  938. Copyright (C) 1993 Paul J. Sanchez and Bill Shirley
  939. Copyright (C) 1994, 1996 Pieter J. Schoenmakers
  940.  
  941. The `simple sample Objective-C program' is free software; you can
  942. redistribute it and/or modify it under the terms of the GNU General Public
  943. License as published by the Free Software Foundation; either version 2, or
  944. (at your option) any later version.
  945.  
  946. The `simple sample Objective-C program' is distributed in the hope that it
  947. will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty
  948. of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General
  949. Public License for more details.
  950.  
  951. You should have received a copy of the GNU General Public License along
  952. with GNU Emacs; see the file COPYING.  If not, write to the Free Software
  953. Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
  954. __EOF__
  955. set `wc -lwc <objc-sample/COPYRIGHT`
  956. if test $1$2$3 != 19155973
  957. then
  958.     echo ERROR: wc results of objc-sample/COPYRIGHT are $* should be 19 155 973
  959. fi
  960.  
  961. chmod 644 objc-sample/COPYRIGHT
  962.  
  963. chmod 755 objc-sample
  964.  
  965. exit 0
  966.