summaryrefslogtreecommitdiff
path: root/four
diff options
context:
space:
mode:
Diffstat (limited to 'four')
-rw-r--r--four/atof.c59
-rw-r--r--four/calc.c99
-rw-r--r--four/getch.c38
-rw-r--r--four/getop.c35
-rw-r--r--four/grep.c58
-rw-r--r--four/op.c42
6 files changed, 331 insertions, 0 deletions
diff --git a/four/atof.c b/four/atof.c
new file mode 100644
index 0000000..86bd651
--- /dev/null
+++ b/four/atof.c
@@ -0,0 +1,59 @@
+#include <stdio.h>
+#include <ctype.h>
+#include <math.h>
+
+#define MAXLINE 128
+
+int
+get_line(char s[], int lim)
+{
+ int c, i;
+ i = 0;
+ while (--lim > 0 && (c = getchar()) != EOF && c != '\n') {
+ s[i++] = c;
+ }
+ if (c == '\n') {
+ s[i++] = c;
+ }
+ s[i] = '\0';
+ return i;
+}
+
+/* convert string to double-precision floating point */
+double
+atof(char s[])
+{
+ double val, power;
+ int i, sign;
+ for (i = 0; isspace(s[i]); ++i);
+ sign = (s[i] == '-') ? -1 : 1;
+ if (s[i] == '+' || s[i] == '-') {
+ ++i;
+ }
+ for (val = 0.0; isdigit(s[i]); ++i) {
+ val = 10.0 * val + (s[i] - '0');
+ }
+ if (s[i] == '.') {
+ ++i;
+ }
+ for (power = 1.0; isdigit(s[i]); ++i) {
+ val = 10.0 * val + (s[i] - '0');
+ power *= 10.0;
+ }
+ if (s[i] == 'e' || s[i] == 'E') {
+ return sign * val / power * pow(10, s[++i] - '0');
+ }
+ return sign * val / power;
+}
+
+int
+main()
+{
+ double sum;
+ char line[MAXLINE];
+ sum = 0;
+ while (get_line(line, MAXLINE) > 0) {
+ printf("\t%g\n", sum += atof(line));
+ }
+ return 0;
+}
diff --git a/four/calc.c b/four/calc.c
new file mode 100644
index 0000000..cb484ad
--- /dev/null
+++ b/four/calc.c
@@ -0,0 +1,99 @@
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#define MAXOP 100
+#define NUMBER '0'
+
+int getop(char[]);
+void push(double);
+double pop(void);
+double peek();
+void ungets();
+
+int
+main()
+{
+ int type, var;
+ double op1, op2, r;
+ char s[MAXOP];
+ char v[26];
+
+ /* reverse Polish calculator */
+ while ((type = getop(s)) != EOF) {
+ switch (type) {
+ case NUMBER:
+ push(atof(s));
+ break;
+ case '+':
+ push(pop() + pop());
+ break;
+ case '*':
+ push(pop() * pop());
+ break;
+ /* to guarantee the right order, the first value must be stored */
+ case '-':
+ op2 = pop();
+ push(pop() - op2);
+ break;
+ case '/':
+ op2 = pop();
+ if (op2 != 0.0) {
+ push(pop() / op2);
+ } else {
+ printf("error: zero divisor\n");
+ }
+ break;
+ case '%':
+ op2 = pop();
+ op1 = pop();
+ if (op1 >= 0.0 && op2 >= 0.0) {
+ push((int)op1 % (int)op2);
+ } else if (op1 < 0.0 || op2 < 0.0) {
+ push(0);
+ } else {
+ printf("error: zero divisor\n");
+ }
+ break;
+ /* print without popping */
+ case 'p':
+ printf("%f\n", peek());
+ break;
+ /* duplicate */
+ case 'd':
+ op2 = peek();
+ push(op2);
+ break;
+ /* swap top two elements */
+ case 's':
+ op2 = pop();
+ op1 = pop();
+ push(op2);
+ push(op1);
+ break;
+ case '=':
+ pop();
+ if (var > 'a' && var < 'z') {
+ v[var - 'a'] = pop();
+ }
+ case '\n':
+ r = pop();
+ printf("\t%.8g\n", r);
+ break;
+ case 'u':
+ ungets();
+ break;
+ default:
+ if (type == 'R') {
+ push(r);
+ } else if (type >= 'a' && type <= 'z') {
+ push(v[type - 'a']);
+ } else {
+ printf("error: unknown command %s\n", s);
+ }
+ break;
+ }
+ var = type;
+ }
+ return 0;
+}
diff --git a/four/getch.c b/four/getch.c
new file mode 100644
index 0000000..84582ce
--- /dev/null
+++ b/four/getch.c
@@ -0,0 +1,38 @@
+#include <stdio.h>
+#include <string.h>
+
+#define BUFSIZE 101
+
+char buf[BUFSIZE];
+int bufp = 0;
+
+/*
+ * deliver the next character to be considered
+ * reading from the buffer if it contains a character
+ * and calling getchar if the buffer is empty
+ */
+int
+getch(void)
+{
+ return (bufp > 0) ? buf[--bufp] : getchar();
+}
+
+/* remember the characters put back on the input */
+void
+ungetch(int c)
+{
+ if (bufp >= BUFSIZE) {
+ printf("ungetch: too many characters\n");
+ } else {
+ buf[bufp++] = c;
+ }
+}
+
+void
+ungets(char s[])
+{
+ int l = strlen(s);
+ while (l) {
+ ungetch(s[--l]);
+ }
+}
diff --git a/four/getop.c b/four/getop.c
new file mode 100644
index 0000000..8870895
--- /dev/null
+++ b/four/getop.c
@@ -0,0 +1,35 @@
+#include <stdio.h>
+#include <ctype.h>
+
+#define NUMBER '0'
+
+int getch(void);
+void ungetch(int);
+
+/* get next operator or numeric operand */
+int
+getop(char s[])
+{
+ int i, c;
+
+ while((s[0] = c = getch()) == ' ' || c == '\t');
+ s[1] = '\0';
+ /* not a number */
+ if (!isdigit(c) && c != '.') {
+ return c;
+ }
+ i = 0;
+ /* collect integer part */
+ if (isdigit(c)) {
+ while (isdigit(s[++i] = c = getch()));
+ }
+ /* collect fraction part */
+ if (c == '.') {
+ while (isdigit(s[++i] = c = getch()));
+ }
+ s[i] = '\0';
+ if (c != EOF) {
+ ungetch(c);
+ }
+ return NUMBER;
+}
diff --git a/four/grep.c b/four/grep.c
new file mode 100644
index 0000000..7e6b4db
--- /dev/null
+++ b/four/grep.c
@@ -0,0 +1,58 @@
+#include <stdio.h>
+#include <string.h>
+
+#define MAXLINE 1024
+
+int
+get_line(char s[], int lim)
+{
+ int c, i;
+ i = 0;
+ while (--lim > 0 && (c = getchar()) != EOF && c != '\n') {
+ s[i++] = c;
+ }
+ if (c == '\n') {
+ s[i++] = c;
+ }
+ s[i] = '\0';
+ return i;
+}
+
+int strindex(char s[], char t[])
+{
+ int i, j, k;
+ for (i = 0; s[i] != '\0'; ++i) {
+ for (j = i, k = 0; t[k] != '\0' && s[j] == t[k]; ++j, ++k);
+ if (k > 0 && t[k] == '\0') {
+ return i;
+ }
+ }
+ return -1;
+}
+
+int strrindex(char s[], char t[])
+{
+ int i, j, k;
+ for (i = strlen(s) - 1; i > 0; --i) {
+ for (j = i, k = strlen(t) - 1; k > 0 && s[j] == t[k]; --j, --k);
+ if (t[k] == t[0]) {
+ return i;
+ }
+ }
+ return -1;
+}
+
+int
+main()
+{
+ char line[MAXLINE];
+ char pattern[] = "ould";
+ int found = 0;
+ while (get_line(line, MAXLINE)) {
+ if (strrindex(line, pattern) >= 0) {
+ printf("%s", line);
+ ++found;
+ }
+ }
+ return found;
+}
diff --git a/four/op.c b/four/op.c
new file mode 100644
index 0000000..f8e96ed
--- /dev/null
+++ b/four/op.c
@@ -0,0 +1,42 @@
+#include <stdio.h>
+
+#define MAXVAL 100
+#define NUMBER '0'
+
+int sp = 0;
+double val[MAXVAL];
+
+void
+push(double f)
+{
+ if (sp < MAXVAL) {
+ val[sp++] = f;
+ } else {
+ printf("error: stack full, can't push %g\n", f);
+ }
+}
+
+double
+pop(void)
+{
+ if (sp > 0) {
+ return val[--sp];
+ } else {
+ printf("error: stack empty\n");
+ return 0.0;
+ }
+}
+
+double
+peek()
+{
+ return val[sp - 1];
+}
+
+void
+clear()
+{
+ while (sp) {
+ val[sp--] = 0;
+ }
+}