treba vsecgngo voe

This commit is contained in:
zbyv 2024-11-25 13:26:54 +01:00
parent 5c0b36a419
commit 88c476e052
10 changed files with 132 additions and 43 deletions

8
.gitignore vendored Normal file
View File

@ -0,0 +1,8 @@
.vs/
.vscode/
build/
*.cppcheck
*.dot
*.png
*.svg
*.ps

View File

@ -24,6 +24,9 @@ else()
target_compile_options(Graph PRIVATE -Wall -Wextra -pedantic)
endif()
# link math
target_link_libraries(Graph PRIVATE m)
# Optionally, set the output directory for the executable
# set_target_properties(Graph PROPERTIES
# RUNTIME_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin"

38
lex.c
View File

@ -130,7 +130,7 @@ struct token *lex_token(struct lexer *lex) {
return &lex->tok;
}
void lex_print_position(struct lexer *lex) {
void lex_print_position(const struct lexer *lex) {
int i;
int pos = lex->prev_p - lex->start;
@ -146,7 +146,7 @@ void lex_print_position(struct lexer *lex) {
#ifdef LEX_DEBUG
void lex_debug_print_token(struct token *tok) {
void lex_debug_print_token(const struct token *tok) {
static const char *token_str[] = {
"TOK_EOF",
"TOK_ERROR",
@ -162,28 +162,30 @@ void lex_debug_print_token(struct token *tok) {
"TOK_RIGHT_PAREN"
};
static const char *fn_str[] = {
"FN_ABS",
"FN_EXP",
"FN_LN",
"FN_LOG",
"FN_SIN",
"FN_COS",
"FN_TAN",
"FN_ASIN",
"FN_ACOS",
"FN_ATAN",
"FN_SINH",
"FN_COSH",
"FN_TANH"
};
printf("%-20s ", token_str[tok->type]);
if (tok->type == TOK_NUMBER)
printf("%.2f\n", tok->val.num);
else if (tok->type == TOK_FUNCTION)
else if (tok->type == TOK_FUNCTION) {
static const char *fn_str[] = {
"FN_ABS",
"FN_EXP",
"FN_LN",
"FN_LOG",
"FN_SIN",
"FN_COS",
"FN_TAN",
"FN_ASIN",
"FN_ACOS",
"FN_ATAN",
"FN_SINH",
"FN_COSH",
"FN_TANH"
};
printf("%s\n", fn_str[tok->val.fn]);
}
else
printf("\n");
}

4
lex.h
View File

@ -51,11 +51,11 @@ extern void lex_free(struct lexer *lex);
extern void lex_next(struct lexer *lex);
extern struct token *lex_token(struct lexer *lex);
extern void lex_print_position(struct lexer *lex);
extern void lex_print_position(const struct lexer *lex);
#ifdef LEX_DEBUG
extern void lex_debug_print_token(struct token *tok);
extern void lex_debug_print_token(const struct token *tok);
#endif /* LEX_DEBUG */
#endif /* LEX_H */

7
main.c
View File

@ -32,9 +32,14 @@ int main(int argc, char *argv[]) {
file = fopen("out.ps", "w");
ps_export_graph(file, node, &graph);
fclose(file);
file = fopen("graph.dot", "w");
node_debug_print_gv(node, file);
fclose(file);
node_free(node);
}
node_free(node);
return 0;
}

View File

@ -84,8 +84,8 @@ static struct expr_node* parse_bracketed(struct lexer* lex) {
return node;
}
static struct expr_node* parse_base(struct lexer* lex) {
struct expr_node* inner;
static struct expr_node *parse_base(struct lexer *lex) {
struct expr_node *node, *inner;
if (token_is(lex, TOK_NUMBER)) {
double val = token_num(lex);
@ -104,7 +104,11 @@ static struct expr_node* parse_base(struct lexer* lex) {
if (!(inner = parse_bracketed(lex)))
return NULL;
return node_create_fn(fn, inner);
if (!(node = node_create_fn(fn, inner))) {
node_free(inner);
}
return node;
}
if (token_is(lex, TOK_LEFT_PAREN)) {

View File

@ -4,7 +4,7 @@
#define HALF_GRAPH_SIZE (GRAPH_SIZE / 2)
#define GRID_STEP (GRAPH_SIZE / 10)
void ps_export_graph(FILE *file, struct expr_node *node, struct graph_range *range) {
void ps_export_graph(FILE *file, const struct expr_node *node, const struct graph_range *range) {
int i;
double x;
int first = 1;

View File

@ -10,6 +10,6 @@ struct graph_range {
double step;
};
extern void ps_export_graph(FILE *file, struct expr_node *node, struct graph_range *range);
extern void ps_export_graph(FILE *file, const struct expr_node *node, const struct graph_range *range);
#endif

98
tree.c
View File

@ -112,22 +112,23 @@ static void debug_print_binop(struct expr_node *node, const char* name, int inde
debug_print(node->vals.binop.right, indent + 1);
}
static const char* fn_str[] = {
"FN_ABS",
"FN_EXP",
"FN_LN",
"FN_LOG",
"FN_SIN",
"FN_COS",
"FN_TAN",
"FN_ASIN",
"FN_ACOS",
"FN_ATAN",
"FN_SINH",
"FN_COSH",
"FN_TANH"
};
static void debug_print(struct expr_node *node, int indent) {
static const char* fn_str[] = {
"FN_ABS",
"FN_EXP",
"FN_LN",
"FN_LOG",
"FN_SIN",
"FN_COS",
"FN_TAN",
"FN_ASIN",
"FN_ACOS",
"FN_ATAN",
"FN_SINH",
"FN_COSH",
"FN_TANH"
};
switch (node->type) {
case EXPR_ADD:
@ -181,7 +182,72 @@ void node_debug_print(struct expr_node *node) {
debug_print(node, 0);
}
double node_eval(struct expr_node *node, double x) {
static void debug_print_gv(const struct expr_node *node, FILE *output);
static void debug_print_binop_gv(const struct expr_node *node, FILE *output, const char *name) {
fprintf(output, "node%p [label=\"%s\"]\n", (void*)node, name);
debug_print_gv(node->vals.binop.left, output);
debug_print_gv(node->vals.binop.right, output);
fprintf(output, "node%p -> node%p [label=left]\n", (void*)node, (void*)node->vals.binop.left);
fprintf(output, "node%p -> node%p [label=right]\n", (void*)node, (void*)node->vals.binop.right);
}
static void debug_print_gv(const struct expr_node *node, FILE *output) {
switch (node->type) {
case EXPR_ADD:
debug_print_binop_gv(node, output, "ADD");
break;
case EXPR_SUB:
debug_print_binop_gv(node, output, "SUB");
break;
case EXPR_MULT:
debug_print_binop_gv(node, output, "MULT");
break;
case EXPR_DIV:
debug_print_binop_gv(node, output, "DIV");
break;
case EXPR_POW:
debug_print_binop_gv(node, output, "POW");
break;
case EXPR_NEG:
fprintf(output, "node%p [label=\"NEG\"]\n", (void*)node);
debug_print_gv(node->vals.unop, output);
fprintf(output, "node%p -> node%p [label=unop]\n", (void*)node, (void*)node->vals.unop);
break;
case EXPR_CONST:
fprintf(output, "node%p [label=\"CONST: %.2f\"]\n", (void*)node, node->vals.num);
break;
case EXPR_X:
fprintf(output, "node%p [label=\"X\"]\n", (void*)node);
break;
case EXPR_FN:
fprintf(output, "node%p [label=\"FN: %s\"]\n", (void*)node, fn_str[node->vals.fn.fn]);
debug_print_gv(node->vals.fn.arg, output);
fprintf(output, "node%p -> node%p [label=arg]\n", (void*)node, (void*)node->vals.fn.arg);
break;
default:
break;
}
}
void node_debug_print_gv(const struct expr_node *node, FILE *output) {
fprintf(output, "digraph G {\n");
debug_print_gv(node, output);
fprintf(output, "}\n");
}
double node_eval(const struct expr_node *node, double x) {
switch (node->type) {
case EXPR_CONST:
return node->vals.num;

3
tree.h
View File

@ -42,8 +42,9 @@ extern struct expr_node *node_create_x(void);
extern struct expr_node *node_create_fn(enum math_fn fn, struct expr_node *arg);
extern void node_debug_print(struct expr_node *node);
extern void node_debug_print_gv(const struct expr_node *node, FILE *output);
extern double node_eval(struct expr_node *node, double x);
extern double node_eval(const struct expr_node *node, double x);
extern void node_free(struct expr_node *node);