Skip to content

Commit

Permalink
Exerc 4_10.
Browse files Browse the repository at this point in the history
  • Loading branch information
rsm-lisper committed May 23, 2024
1 parent 8158578 commit 594ddb9
Show file tree
Hide file tree
Showing 56 changed files with 415 additions and 0 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
BINARY=calc__getline

LFLAGS=-lm

include ../../Makefile.exerc
20 changes: 20 additions & 0 deletions chapter_4.functions_progr_structure/4_10.calc__getline/get_line.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
# include <stdio.h>

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';
if (i == 0 && c == EOF) {
i = EOF;
}

return i;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# ifndef GET_LINE_H
# define GET_LINE_H

int get_line (char s[], int lim);

# endif
85 changes: 85 additions & 0 deletions chapter_4.functions_progr_structure/4_10.calc__getline/getop.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
# include <stdio.h>
# include <ctype.h>
# include <stdbool.h>

# include "getop.h"
# include "get_line.h"

# define GETOP_MAXLINE 256

char line[GETOP_MAXLINE];
int lsize, lpos, first_run = true;


/* getop: get next character, numeric operand or function/command */
int getop (char s[])
{
int c, i;

if (first_run || line[lpos] == '\0') {
first_run = false;
if ((lsize = get_line(line, GETOP_MAXLINE)) == EOF) {
return EOF;
} else {
lpos = 0;
}
}

/* skip leading white space. c and s[0] will contain first character */
while ((s[0] = c = line[lpos++]) == ' ' || c == '\t') {
}

if (c == '\n') {
return c;
}
/* operator, single digit number or single letter symbol */
if ((s[1] = c = line[lpos++]) == ' ' || c == '\t' || c == '\n') {
lpos--;
s[1] = '\0';
c = s[0];
/* single digit number */
if (isdigit(c)) {
return GETOP_NUMBER;
}
/* one letter symbol [a-zA-Z] */
else if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z')) {
return GETOP_SYMBOL;
}
/* operator */
else {
return c;
}
}
/* number or symbol */
else {
lpos--;
c = s[0];
/* number */
if (isdigit(c) || c == '-' || c == '.') {
i = 0;
if (c == '-') { /* move by a minus (-) sign */
s[++i] = c = line[lpos++];
}
if (isdigit(c)) { /* collect integer part */
while (isdigit(s[++i] = c = line[lpos++])) {
}
}
if (c == '.') { /* collect fraction part */
while (isdigit(s[++i] = c = line[lpos++])) {
}
}
s[i] = '\0';
lpos--;
return GETOP_NUMBER;
}
/* symbol */
else {
i = 0;
while ((s[++i] = c = line[lpos++]) != ' ' && c != '\t' && c != '\n') {
}
s[i] = '\0';
lpos--;
return GETOP_SYMBOL;
}
}
}
10 changes: 10 additions & 0 deletions chapter_4.functions_progr_structure/4_10.calc__getline/getop.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
# ifndef GETOP_H
# define GETOP_H

# define GETOP_NUMBER '0' /* signal that a number was found */
# define GETOP_SYMBOL 'a' /* signal that a symbol was found */

/* getop: get next character, numeric operand or function/command */
int getop (char s[]);

# endif
121 changes: 121 additions & 0 deletions chapter_4.functions_progr_structure/4_10.calc__getline/main.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
# include <stdio.h>
# include <stdlib.h> /* for atof */
# include <string.h> /* strcmp */
# include <math.h>

# include "stack.h"
# include "getop.h"
# include "vars.h"

# define MAXOP 128 /* max size of operand or operator */


/* reverse Polish calculator */
int main ()
{
int type;
double op2, op_r;
char s[MAXOP];

while ((type = getop(s)) != EOF) {
switch (type) {
case GETOP_SYMBOL:
if (strcmp("sin", s) == 0) { /* math sin */
push(sin(pop()));
} else if (strcmp("cos", s) == 0) { /* math cos */
push(cos(pop()));
} else if (strcmp("tan", s) == 0) { /* math tan */
push(tan(pop()));
} else if (strcmp("asin", s) == 0) { /* math asin */
push(asin(pop()));
} else if (strcmp("acos", s) == 0) { /* math acos */
push(acos(pop()));
} else if (strcmp("atan", s) == 0) { /* math atan */
push(atan(pop()));
} else if (strcmp("atan2", s) == 0) { /* math atan2 */
push(atan2(pop(), pop()));
} else if (strcmp("sinh", s) == 0) { /* math sinh */
push(sinh(pop()));
} else if (strcmp("cosh", s) == 0) { /* math cosh */
push(cosh(pop()));
} else if (strcmp("tanh", s) == 0) { /* math tanh */
push(tanh(pop()));
} else if (strcmp("exp", s) == 0) { /* math exp */
push(exp(pop()));
} else if (strcmp("log", s) == 0) { /* math log */
push(log(pop()));
} else if (strcmp("log10", s) == 0) { /* math log10 */
push(log10(pop()));
} else if (strcmp("pow", s) == 0) { /* math pow */
op2 = pop();
push(pow(pop(), op2));
} else if (strcmp("sqrt", s) == 0) { /* math sqrt */
push(sqrt(pop()));
} else if (strcmp("ceil", s) == 0) { /* math ceil */
push(ceil(pop()));
} else if (strcmp("floor", s) == 0) { /* math floor */
push(floor(pop()));
} else if (strcmp("abs", s) == 0) { /* math fabs */
push(fabs(pop()));
} else if (strcmp("clear", s) == 0) { /* clear the stack */
clear();
} else if (strcmp("peek", s) == 0) { /* peek top stack element */
printf("\t%.8g\n", peek());
} else if (strcmp("swap", s) == 0) { /* swap top two stack elements */
op_r = pop();
op2 = pop();
push(op_r);
push(op2);
} else if (strlen(s)==2 &&
((s[0]==':' && ((s[1]>='A' && s[1]<='Z') || (s[1]=='?'))) ||
(s[1]=='=' && s[0]>='A' && s[0]<='Z'))) { /* variables */
if (s[1]=='=') { /* variable set */
set_var(s[0], pop());
} else if (s[1]=='?') { /* last return */
push(get_last());
} else { /* variable get */
push(get_var(s[1]));
}
} else {
printf("error: unknown symbol %s\n", s);
}
break;
case GETOP_NUMBER:
push(atof(s));
break;
case '+':
push(pop() + pop());
break;
case '*':
push(pop() * pop());
break;
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();
if (op2 != 0.0) {
push((long int) pop() % (long int) op2);
} else {
printf("error: zero modulus\n");
}
break;
case '\n':
printf("\t%.8g\n", set_last(pop()));
break;
default:
printf("error: unknown command %s\n", s);
break;
}
}
return 0;
}
48 changes: 48 additions & 0 deletions chapter_4.functions_progr_structure/4_10.calc__getline/stack.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
# include <stdio.h>

# define MAXVAL 128 /* max depth of val stack */

int sp = 0; /* next free stack position */
double val[MAXVAL]; /* value stack */


/* push: push f onto stack */
void push (double f)
{
if (sp < MAXVAL) {
val[sp++] = f;
} else {
printf("error: stack full, can't push %g\n", f);
}
}


/* pop: pop and return top value from stack */
double pop (void)
{
if (sp > 0) {
return val[--sp];
} else {
printf("error: stack empty\n");
return 0.0;
}
}


/* peek: return top value from stack without popping */
double peek (void)
{
if (sp > 0) {
return val[sp - 1];
} else {
printf("error: stack empty\n");
return 0.0;
}
}


/* clear: clear the stack */
void clear (void)
{
sp = 0;
}
16 changes: 16 additions & 0 deletions chapter_4.functions_progr_structure/4_10.calc__getline/stack.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# ifndef STACK_H
# define STACK_H

/* push: push f onto stack */
void push (double f);

/* pop: pop and return top value from stack */
double pop (void);

/* peek: return top value from stack without popping */
double peek (void);

/* clear: clear the stack */
void clear (void);

# endif
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@

Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
error: stack empty
0
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1 ( )
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
error: unknown command (
error: unknown command )
1
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
5 0 /
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
error: zero divisor
5
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
5 0 %
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
error: zero modulus
5
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
peek
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
error: stack empty
0
error: stack empty
0
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
123 Z=
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
error: stack empty
0
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1024 1024 +
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2048
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1024 2048 -
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-1024
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-10 -55 -
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
45
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-2 100 -5 * *
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1000
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
125 -5 / 5 / -0.2 /
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
25
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
20 100 21 % %
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
4
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-1 1 - 100 * 5 / 25 / 1 +
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
-0.6
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1.01 peek 999
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
1.01
999
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1 2 3 swap
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
2
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
1 22 300 clear
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
error: stack empty
0
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
256 2 8 pow +
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
512
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
.5 -1.1 + floor
Loading

0 comments on commit 594ddb9

Please sign in to comment.