refresh
This commit is contained in:
parent
02b2f1146c
commit
71e589eb70
139
sk2/calculator.c
139
sk2/calculator.c
@ -5,20 +5,20 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
|
|
||||||
static const char *ptr;
|
static const char *cur;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
static void skip_spaces(void) {
|
static void skip_ws(void) {
|
||||||
while (*ptr && isspace(*ptr)) {
|
while (*cur && isspace(*cur)) {
|
||||||
ptr++;
|
cur++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int match(const char *s) {
|
static int starts_with(const char *name) {
|
||||||
int len = strlen(s);
|
int len = strlen(name);
|
||||||
if (strncmp(ptr, s, len) == 0) {
|
if (strncmp(cur, name, len) == 0) {
|
||||||
ptr += len;
|
cur += len;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
@ -26,104 +26,101 @@ static int match(const char *s) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
static double parse_expression(void);
|
static double read_expr(void);
|
||||||
|
|
||||||
static double parse_number(void) {
|
static double read_number(void) {
|
||||||
skip_spaces();
|
skip_ws();
|
||||||
char *end;
|
char *end;
|
||||||
double val = strtod(ptr, &end);
|
double res = strtod(cur, &end);
|
||||||
ptr = end;
|
cur = end;
|
||||||
return val;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static double parse_factor(void) {
|
static double read_factor(void) {
|
||||||
skip_spaces();
|
skip_ws();
|
||||||
|
|
||||||
|
if (*cur == '(') {
|
||||||
if (*ptr == '(') {
|
cur++;
|
||||||
ptr++;
|
double res = read_expr();
|
||||||
double val = parse_expression();
|
skip_ws();
|
||||||
skip_spaces();
|
if (*cur == ')') {
|
||||||
if (*ptr == ')') {
|
cur++;
|
||||||
ptr++;
|
|
||||||
}
|
}
|
||||||
return val;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (starts_with("sin")) {
|
||||||
if (match("sin")) {
|
skip_ws();
|
||||||
skip_spaces();
|
return sin(read_factor());
|
||||||
return sin(parse_factor());
|
|
||||||
}
|
}
|
||||||
if (match("cos")) {
|
if (starts_with("cos")) {
|
||||||
skip_spaces();
|
skip_ws();
|
||||||
return cos(parse_factor());
|
return cos(read_factor());
|
||||||
}
|
}
|
||||||
if (match("sqrt")) {
|
if (starts_with("sqrt")) {
|
||||||
skip_spaces();
|
skip_ws();
|
||||||
return sqrt(parse_factor());
|
return sqrt(read_factor());
|
||||||
}
|
}
|
||||||
if (match("log")) {
|
if (starts_with("log")) {
|
||||||
skip_spaces();
|
skip_ws();
|
||||||
return log(parse_factor());
|
return log(read_factor());
|
||||||
}
|
}
|
||||||
if (match("pow")) {
|
if (starts_with("pow")) {
|
||||||
skip_spaces();
|
skip_ws();
|
||||||
if (*ptr == '(') ptr++;
|
if (*cur == '(') cur++;
|
||||||
double a = parse_expression();
|
double left = read_expr();
|
||||||
skip_spaces();
|
skip_ws();
|
||||||
if (*ptr == ',') ptr++;
|
if (*cur == ',') cur++;
|
||||||
double b = parse_expression();
|
double right = read_expr();
|
||||||
skip_spaces();
|
skip_ws();
|
||||||
if (*ptr == ')') ptr++;
|
if (*cur == ')') cur++;
|
||||||
return pow(a, b);
|
return pow(left, right);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return read_number();
|
||||||
return parse_number();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static double parse_term(void) {
|
static double read_term(void) {
|
||||||
double val = parse_factor();
|
double res = read_factor();
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
skip_spaces();
|
skip_ws();
|
||||||
if (*ptr == '*') {
|
if (*cur == '*') {
|
||||||
ptr++;
|
cur++;
|
||||||
val *= parse_factor();
|
res *= read_factor();
|
||||||
} else if (*ptr == '/') {
|
} else if (*cur == '/') {
|
||||||
ptr++;
|
cur++;
|
||||||
val /= parse_factor();
|
res /= read_factor();
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return val;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
static double parse_expression(void) {
|
static double read_expr(void) {
|
||||||
double val = parse_term();
|
double res = read_term();
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
skip_spaces();
|
skip_ws();
|
||||||
if (*ptr == '+') {
|
if (*cur == '+') {
|
||||||
ptr++;
|
cur++;
|
||||||
val += parse_term();
|
res += read_term();
|
||||||
} else if (*ptr == '-') {
|
} else if (*cur == '-') {
|
||||||
ptr++;
|
cur++;
|
||||||
val -= parse_term();
|
res -= read_term();
|
||||||
} else {
|
} else {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return val;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
double evaluate_expression(const char *expr) {
|
double evaluate_expression(const char *expr) {
|
||||||
ptr = expr;
|
cur = expr;
|
||||||
return parse_expression();
|
return read_expr();
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user