diff --git a/lex.c b/lex.c index 80d8d0b..90e23d5 100644 --- a/lex.c +++ b/lex.c @@ -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; diff --git a/main.c b/main.c index 1b2b8ed..faf41c5 100644 --- a/main.c +++ b/main.c @@ -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 []\n", name); + fprintf(f, " ..... The function to plot the graph of.\n"); + fprintf(f, " .. Name of the output PostScript file.\n"); + fprintf(f, " ........ 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 \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"); @@ -22,23 +88,14 @@ int main(int argc, char *argv[]) { fprintf(stderr, "%s", parser_get_error_text(&parser)); return parser_get_error(&parser); } + + err = export_to_file(node, &range, argv[2]); - graph.xmin = -10.0; - graph.xmax = 10.0; - graph.ymin = -10.0; - graph.ymax = 10.0; - graph.step = 0.01; - - 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; } \ No newline at end of file diff --git a/math_functions.c b/math_functions.c index e38d450..a3af5f2 100644 --- a/math_functions.c +++ b/math_functions.c @@ -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 }, diff --git a/ps_graph.h b/ps_graph.h index 2f2ea8f..734b424 100644 --- a/ps_graph.h +++ b/ps_graph.h @@ -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);