home *** CD-ROM | disk | FTP | other *** search
/ Nebula 1995 August / NEBULA.mdf / Documents / FAQ / Objective-C-faq / sample < prev    next >
Encoding:
Text File  |  1993-08-17  |  24.0 KB  |  983 lines

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