This is Calculator.m in view mode; [Download] [Up]
/* ** Solution to Calculator exercise, lab #1. ** Authors: Bruce Blumberg and Doug Keislar, NeXT Technical Support */ #import "Calculator.h" #import <string.h> #import <math.h> /* for extensions to existing functionality */ #import <appkit/Application.h> #import <appkit/TextField.h> @implementation Calculator +new; { self = [super new]; /* create new instance of calculator */ strcpy(viewerStr,""); /* initialize string for viewer */ topOfStack = -1; /* initialize stack */ frozen = NO; return self; } -(double)pop { if(topOfStack>-1) return(stack[topOfStack--]); else { [self stackError:"stack underflow"]; return(0); } } -push:(double)aNum { if(topOfStack<STACKSIZE-1) stack[++topOfStack] = aNum; else [self stackError:"stack overflow"]; return self; } -(double)getOperand { if (frozen) return (0.0); if (viewerStr[0]) [self enter:self]; /* push displayed value to stack, if it hasn't already been done */ return ([self pop]); } -displayValue:(double)aNum { if (frozen) return self; [viewer setFloatValue:aNum]; /* display current value */ strcpy(viewerStr,""); /* and empty out string for next */ return self; } -pushAndDisplay:(double)aNum { if (frozen) return self; [self push:aNum]; [self displayValue:aNum]; return self; } -enter:(id)sender { if (frozen) return self; [self push:[viewer floatValue]]; strcpy(viewerStr,""); return self; } -clearDisplay:(id)sender { if (frozen) frozen = NO; strcpy(viewerStr,""); [self displayValue:0.0]; return self; } -digit:(id)sender { char digitBuf[2]; if (frozen) return self; /* get the new digit from the button's tag and append it to the displayed string */ sprintf(digitBuf,"%d",[sender selectedTag]); /* we use selectedTag instead of tag, in case the button is part of a matrix */ strcat(viewerStr,digitBuf); [viewer setStringValue:viewerStr]; return self; } -period:(id)sender { if (!frozen) { strcat(viewerStr,"."); [viewer setStringValue:viewerStr]; } return self; } -add:(id)sender { if (!frozen) [self pushAndDisplay:[self getOperand] + [self getOperand]]; return self; } -subtract:(id)sender { if (!frozen) [self pushAndDisplay:-[self getOperand] + [self getOperand]]; return self; } -multiply:(id)sender { if (!frozen) [self pushAndDisplay:[self getOperand] * [self getOperand]]; return self; } -divide:(id)sender { double firstOp; if (!frozen) { firstOp = [self getOperand]; [self pushAndDisplay:[self getOperand]/firstOp]; } return self; } -changeSign:(id)sender /* we don't push to stack here, so digits can be appended after sign is changed */ { if (!frozen) { [viewer setFloatValue:(-[viewer floatValue])]; strcpy (viewerStr,[viewer stringValue]); } return self; } -stackError:(STR)errorMsg; { [viewer setStringValue:errorMsg]; frozen = YES; topOfStack = -1; /* stack errors re-initialize stack */ return self; } - setAWindow:anObject /* associate the outlet "aWindow" with the user-interface window, "anObject" */ { aWindow = anObject; [aWindow setDelegate:self]; /* needed for windowWillClose: */ return self; } - setViewer:anObject /* initialize the other outlet, viewer */ { viewer = anObject; return self; } - windowWillClose:sender /* needed only if calculator has a close button that will be used for quitting the application, as a supplement to the "Quit" menu item. This is not recommended; normally only the "Quit" menu item should cause an application to quit. */ { [NXApp terminate:self]; return self; } @end
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.