usaa25/sk2/calculator.c
2026-01-25 23:20:37 +01:00

130 lines
2.3 KiB
C

#include "calculator.h"
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <math.h>
static const char *ptr;
static void skip_spaces(void) {
while (*ptr && isspace(*ptr)) {
ptr++;
}
}
static int match(const char *s) {
int len = strlen(s);
if (strncmp(ptr, s, len) == 0) {
ptr += len;
return 1;
}
return 0;
}
static double parse_expression(void);
static double parse_number(void) {
skip_spaces();
char *end;
double val = strtod(ptr, &end);
ptr = end;
return val;
}
static double parse_factor(void) {
skip_spaces();
if (*ptr == '(') {
ptr++;
double val = parse_expression();
skip_spaces();
if (*ptr == ')') {
ptr++;
}
return val;
}
if (match("sin")) {
skip_spaces();
return sin(parse_factor());
}
if (match("cos")) {
skip_spaces();
return cos(parse_factor());
}
if (match("sqrt")) {
skip_spaces();
return sqrt(parse_factor());
}
if (match("log")) {
skip_spaces();
return log(parse_factor());
}
if (match("pow")) {
skip_spaces();
if (*ptr == '(') ptr++;
double a = parse_expression();
skip_spaces();
if (*ptr == ',') ptr++;
double b = parse_expression();
skip_spaces();
if (*ptr == ')') ptr++;
return pow(a, b);
}
return parse_number();
}
static double parse_term(void) {
double val = parse_factor();
while (1) {
skip_spaces();
if (*ptr == '*') {
ptr++;
val *= parse_factor();
} else if (*ptr == '/') {
ptr++;
val /= parse_factor();
} else {
break;
}
}
return val;
}
static double parse_expression(void) {
double val = parse_term();
while (1) {
skip_spaces();
if (*ptr == '+') {
ptr++;
val += parse_term();
} else if (*ptr == '-') {
ptr++;
val -= parse_term();
} else {
break;
}
}
return val;
}
double evaluate_expression(const char *expr) {
ptr = expr;
return parse_expression();
}