init taschenrechner and calendar
This commit is contained in:
@@ -0,0 +1,316 @@
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <windows.h>
|
||||
//#include "math_graphics.h"
|
||||
#include <math.h>
|
||||
#include <setjmp.h>
|
||||
#include "m_string.h"
|
||||
|
||||
|
||||
enum TokenKind {
|
||||
ENDOFINPUT, INTEGER, KOMMA, PLUS, MINUS, MUL, DIV, MODULO, LPAREN, RPAREN, POW, SQRT, SIN, COS, TAN, ATAN, ATAN2, ANS
|
||||
};
|
||||
|
||||
|
||||
//Definition Token
|
||||
struct Token {
|
||||
TokenKind kind = ENDOFINPUT;
|
||||
double floatValue;
|
||||
long intValue;
|
||||
};
|
||||
|
||||
//Erkennen ob Leerzeichen, Zeilenumbruch, Tabulator etc.
|
||||
bool isWhitespace(char c) {
|
||||
if (c == ' ' || c == '\n' || c == '\t' || c == '\r') {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
//Wenn Whitsepace weitergehen
|
||||
void eatWhitespace(String &s) {
|
||||
while (isWhitespace(s[0])) {
|
||||
advance(s);
|
||||
}
|
||||
}
|
||||
|
||||
bool isNumber(char c) {
|
||||
if ('0' <= c && c <= '9') {
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
long parseInteger(String inputString) {
|
||||
long integerValue = 0;
|
||||
for (int currentPosition = 0; currentPosition < inputString.length; currentPosition++) {
|
||||
integerValue = integerValue * 10 + inputString[currentPosition] - '0';
|
||||
}
|
||||
return integerValue;
|
||||
}
|
||||
|
||||
double parseFloat(String inputString) {
|
||||
double floatValue = 0.0;
|
||||
int currentPosition = 0;
|
||||
for (; currentPosition < inputString.length; currentPosition++) {
|
||||
if (inputString[currentPosition] == '.') {
|
||||
currentPosition++;
|
||||
break;
|
||||
}
|
||||
|
||||
floatValue = floatValue * 10.0 + (inputString[currentPosition] - '0');
|
||||
}
|
||||
|
||||
double floatValue2 = 0.0;
|
||||
for (int currentPosition2 = inputString.length - 1; currentPosition2 >= currentPosition; currentPosition2--) {
|
||||
floatValue2 = floatValue2 / 10.0 + (inputString[currentPosition2] - '0');
|
||||
}
|
||||
|
||||
return floatValue + (floatValue2 / 10);
|
||||
}
|
||||
|
||||
//Funktion zur Erkennung neuer Token
|
||||
Token getNextToken(String &inputString) {
|
||||
Token token = {};
|
||||
|
||||
eatWhitespace(inputString);
|
||||
if (!inputString.length) {
|
||||
return token;
|
||||
}
|
||||
|
||||
if (isNumber(inputString[0])) {
|
||||
String start = inputString;
|
||||
advance(inputString);
|
||||
|
||||
while (isNumber(inputString[0])) {
|
||||
advance(inputString);
|
||||
}
|
||||
|
||||
if (inputString[0] == '.') {
|
||||
token.kind = KOMMA;
|
||||
advance(inputString);
|
||||
|
||||
while (isNumber(inputString[0])) {
|
||||
advance(inputString);
|
||||
}
|
||||
|
||||
start.length = inputString.data - start.data;
|
||||
token.floatValue = parseFloat(start);
|
||||
|
||||
} else {
|
||||
start.length = inputString.data - start.data;
|
||||
token.kind = INTEGER;
|
||||
token.intValue = parseInteger(start);
|
||||
}
|
||||
//Token für mathematische Operatoren
|
||||
//ergänzt werden müssen: "atan2"
|
||||
} else if (inputString[0] == '+') {
|
||||
token.kind = PLUS;
|
||||
advance(inputString);
|
||||
} else if (inputString[0] == '-') {
|
||||
token.kind = MINUS;
|
||||
advance(inputString);
|
||||
} else if (inputString[0] == '*') {
|
||||
token.kind = MUL;
|
||||
advance(inputString);
|
||||
} else if (inputString[0] == '/') {
|
||||
token.kind = DIV;
|
||||
advance(inputString);
|
||||
} else if (inputString[0] == '%') {
|
||||
token.kind = MODULO;
|
||||
advance(inputString);
|
||||
} else if (inputString[0] == '(') {
|
||||
token.kind = LPAREN;
|
||||
advance(inputString);
|
||||
} else if (inputString[0] == ')') {
|
||||
token.kind = RPAREN;
|
||||
advance(inputString);
|
||||
} else if (inputString[0] == '^') {
|
||||
token.kind = POW;
|
||||
advance(inputString);
|
||||
} else if (starts_with(inputString, "atan2"_str)) {
|
||||
token.kind = ATAN2;
|
||||
advance(inputString, 5);
|
||||
} else if (starts_with(inputString, "atan"_str)) {
|
||||
token.kind = ATAN;
|
||||
advance(inputString, 4);
|
||||
} else if (starts_with(inputString, "sqrt"_str)) {
|
||||
token.kind = SQRT;
|
||||
advance(inputString, 4);
|
||||
} else if (starts_with(inputString, "sin"_str)) {
|
||||
token.kind = SIN;
|
||||
advance(inputString, 3);
|
||||
} else if (starts_with(inputString, "cos"_str)) {
|
||||
token.kind = COS;
|
||||
advance(inputString, 3);
|
||||
} else if (starts_with(inputString, "tan"_str)) {
|
||||
token.kind = TAN;
|
||||
advance(inputString, 3);
|
||||
} else if (starts_with(inputString, "ans"_str)) {
|
||||
token.kind = ANS;
|
||||
advance(inputString, 3);
|
||||
}
|
||||
return token;
|
||||
|
||||
}
|
||||
|
||||
double parseExpression(String &string);
|
||||
Token token = {};
|
||||
double ans = 0;
|
||||
|
||||
jmp_buf Rechner;
|
||||
|
||||
#define expect(k) if(token.kind != (k)) { printf("Unexpected Token"); exit(0); } token = getNextToken(input);
|
||||
|
||||
double parseExpressionOperand(String& input) {
|
||||
if (token.kind == INTEGER) {
|
||||
long value = token.intValue;
|
||||
token = getNextToken(input);
|
||||
return value;
|
||||
} else if (token.kind == KOMMA) {
|
||||
double value = token.floatValue;
|
||||
token = getNextToken(input);
|
||||
return value;
|
||||
} else if (token.kind == LPAREN) {
|
||||
token = getNextToken(input);
|
||||
double expression = parseExpression(input);
|
||||
expect(RPAREN);
|
||||
return expression;
|
||||
} else if (token.kind == SQRT) {
|
||||
token = getNextToken(input);
|
||||
return sqrt(parseExpressionOperand(input));
|
||||
} else if (token.kind == SIN) {
|
||||
token = getNextToken(input);
|
||||
return sin(parseExpressionOperand(input));
|
||||
} else if (token.kind == COS) {
|
||||
token = getNextToken(input);
|
||||
return cos(parseExpressionOperand(input));
|
||||
} else if (token.kind == TAN) {
|
||||
token = getNextToken(input);
|
||||
return tan(parseExpressionOperand(input));
|
||||
} else if (token.kind == ATAN) {
|
||||
token = getNextToken(input);
|
||||
return atan(parseExpressionOperand(input));
|
||||
} else if (token.kind == ATAN2) {
|
||||
printf("Coming soon!");
|
||||
return 0;
|
||||
} else if (token.kind == ANS) {
|
||||
token = getNextToken(input);
|
||||
return ans;
|
||||
}
|
||||
printf("Unexpected Token.\n");
|
||||
longjmp(Rechner, 0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
double parseExpressionUnary(String& input) {
|
||||
if (token.kind == MINUS) {
|
||||
token = getNextToken(input);
|
||||
return -parseExpressionUnary(input);
|
||||
}
|
||||
return parseExpressionOperand(input);
|
||||
}
|
||||
|
||||
double parseExpressionPower(String& input) {
|
||||
double expression = parseExpressionUnary(input);
|
||||
|
||||
while (token.kind == POW) {
|
||||
token = getNextToken(input);
|
||||
expression = pow(expression, parseExpressionUnary(input));
|
||||
}
|
||||
return expression;
|
||||
}
|
||||
|
||||
double parseExpressionMultiplicative(String& input) {
|
||||
double expression = parseExpressionPower(input);
|
||||
|
||||
while (token.kind == MUL || token.kind == DIV) {
|
||||
if (token.kind == MUL) {
|
||||
token = getNextToken(input);
|
||||
expression = expression * parseExpressionPower(input);
|
||||
} else if (token.kind == DIV) {
|
||||
token = getNextToken(input);
|
||||
expression = expression / parseExpressionPower(input);
|
||||
}
|
||||
}
|
||||
return expression;
|
||||
}
|
||||
double parseExpressionAdditive(String& input) {
|
||||
double expression = parseExpressionMultiplicative(input);
|
||||
|
||||
while (token.kind == PLUS || token.kind == MINUS) {
|
||||
if (token.kind == PLUS) {
|
||||
token = getNextToken(input);
|
||||
expression = expression + parseExpressionMultiplicative(input);
|
||||
} else if (token.kind == MINUS) {
|
||||
token = getNextToken(input);
|
||||
expression = expression - parseExpressionMultiplicative(input);
|
||||
}
|
||||
}
|
||||
return expression;
|
||||
}
|
||||
|
||||
double parseExpression(String &input) {
|
||||
return parseExpressionAdditive(input);
|
||||
}
|
||||
|
||||
void write_entire_file(const char* filename, String s){
|
||||
|
||||
FILE* file = fopen(filename, "w");
|
||||
fwrite(s.data, s.length, 1, file);
|
||||
fclose(file);
|
||||
}
|
||||
|
||||
String helpstring = R"(
|
||||
Taschenrechner --- Help
|
||||
|
||||
Operator:
|
||||
- Addition 'Ausdruck' + 'Ausdruck'
|
||||
- Subtraktion 'Ausdruck' - 'Ausdruck'
|
||||
- Multiplikation 'Ausdruck' * 'Ausdruck'
|
||||
- Division 'Ausdruck' / 'Ausdruck'
|
||||
- Potenzen 'Ausdruck' ^ 'Ausdruck'
|
||||
|
||||
Klammern:
|
||||
('Ausdruck' + 'Ausdruck') * 'Ausdruck'
|
||||
('Ausdruck' + 'Ausdruck') * ('Ausdruck' - 'Ausdruck')
|
||||
'Ausdruck' - (('Ausdruck' + 'Ausdruck') * 'Ausdruck') / 'Ausdruck'
|
||||
|
||||
Trigonometrie:
|
||||
- Wurzel sqrt 'Ausdruck' ODER sqrt('Ausdruck')
|
||||
- Sinus/Cosinus/Tangens sin/cos/tan 'Ausdruck' ODER sin('Ausdruck')
|
||||
|
||||
Letzte Antwort kann mittels 'ans' genutzt werden. Beispiel:
|
||||
- 4 + 5
|
||||
9
|
||||
- ans * 2
|
||||
18
|
||||
|
||||
)"_str;
|
||||
|
||||
int main() {
|
||||
SetConsoleOutputCP(65001);
|
||||
write_entire_file("Help.txt", helpstring);
|
||||
|
||||
|
||||
while (true) {
|
||||
setjmp(Rechner);
|
||||
printf("Was möchten Sie berechnen? Für Hilfe 'help' eingeben!\n");
|
||||
|
||||
char buffer[1024];
|
||||
String input = { 1024, buffer };
|
||||
fgets(buffer, 1024, stdin);
|
||||
input.length = strlen(buffer);
|
||||
|
||||
if (starts_with(input, "help"_str) || starts_with(input, "Help"_str)) {
|
||||
printf("%s", helpstring.data);
|
||||
continue;
|
||||
}
|
||||
|
||||
token = getNextToken(input);
|
||||
ans = parseExpression(input);
|
||||
printf("%g\n", ans);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
Reference in New Issue
Block a user