This commit is contained in:
tovjemam 2024-12-23 13:38:15 +01:00
parent a5d9e88f77
commit c50551dca8
4 changed files with 82 additions and 22 deletions

2
lex.c
View File

@ -141,7 +141,7 @@ void lex_next(struct lexer *lex) {
if (try_constant(lex, "pi", CONST_PI)) return;
if (try_constant(lex, "e", CONST_E)) return;
if (try_constant(lex, "skibidi", CONST_S)) return;
if (try_constant(lex, "skibidi", CONST_S)) return; /* easter egg */
if (try_advance_identifier(lex, lex->variable_name)) {
lex->tok.type = TOK_VARIABLE;

95
main.c
View File

@ -3,17 +3,83 @@
#include "lex.h"
#include "parser.h"
#include "ps_graph.h"
#include "error_buffer.h"
static void print_usage(FILE *f, const char *name) {
fprintf(f, "Usage: %s <function> <output file> [<range>]\n", name);
fprintf(f, " <function> ..... The function to plot the graph of.\n");
fprintf(f, " <output file> .. Name of the output PostScript file.\n");
fprintf(f, " <range> ........ Ranges of the graph in the format of \"xMin:xMax:yMin:yMax\". Optional.\n");
}
static int read_double(const char **str, double *out) {
char *end;
*out = strtod(*str, &end);
if (*str == end)
return 0;
*str = end;
return 1;
}
#define EXPECT_DOUBLE(str, out) \
if (!read_double(&str, out)) \
return 0;
#define EXPECT_CHAR(str, c) \
if (*str++ != c) \
return 0;
static int parse_range(const char *str, struct graph_range *range) {
EXPECT_DOUBLE(str, &range->xmin);
EXPECT_CHAR(str, ':');
EXPECT_DOUBLE(str, &range->xmax);
EXPECT_CHAR(str, ':');
EXPECT_DOUBLE(str, &range->ymin);
EXPECT_CHAR(str, ':');
EXPECT_DOUBLE(str, &range->ymax);
EXPECT_CHAR(str, '\0');
return 1;
}
static enum error_code export_to_file(const struct expr_node *node, const struct graph_range *range, const char *out_name) {
FILE *file;
if (!(file = fopen(out_name, "w"))) {
fprintf(stderr, "Cannot open \"%s\" for writing!\n", out_name);
return ERR_INVALID_FILENAME;
}
ps_export_graph(file, node, range);
fclose(file);
return ERR_NO_ERR;
}
int main(int argc, char *argv[]) {
enum error_code err;
struct parser parser;
struct expr_node *node;
FILE *file;
struct graph_range graph;
struct graph_range range;
if (argc < 2) {
printf("Usage: %s <expression>\n", argv[0]);
return 1;
if (argc < 3) {
print_usage(stderr, argv[0]);
return ERR_INVALID_ARGS;
}
if (argc > 3) {
if (!parse_range(argv[3], &range)) {
fprintf(stderr, "Invalid format of ranges! The correct format is \"xMin:xMax:yMin:yMax\".\n");
return ERR_INVALID_ARGS;
}
}
else {
range.xmin = -10.0;
range.xmax = 10.0;
range.ymin = -10.0;
range.ymax = 10.0;
}
node = parser_parse(&parser, argv[1], "x");
@ -23,22 +89,13 @@ int main(int argc, char *argv[]) {
return parser_get_error(&parser);
}
graph.xmin = -10.0;
graph.xmax = 10.0;
graph.ymin = -10.0;
graph.ymax = 10.0;
graph.step = 0.01;
err = export_to_file(node, &range, argv[2]);
file = fopen("out.ps", "w");
ps_export_graph(file, node, &graph);
fclose(file);
file = fopen("graph.dot", "w");
/* file = fopen("graph.dot", "w");
node_debug_print_gv(node, file);
fclose(file);
fclose(file); */
node_free(node);
return 0;
return err;
}

View File

@ -69,6 +69,10 @@ static double mf_mod(double *y, const double *args) {
const struct math_function *fns_get(void) {
static const struct math_function fns[] = {
/* +--- název
| +--- počet argumentů
| | +--- vyhodnocovač
| | | */
{ "abs", 1, mf_fabs },
{ "exp", 1, mf_exp },
{ "ln", 1, mf_log },

View File

@ -7,7 +7,6 @@
struct graph_range {
double xmin, xmax;
double ymin, ymax;
double step;
};
extern void ps_export_graph(FILE *file, const struct expr_node *node, const struct graph_range *range);