commit 015ee9595f8a8d52e86825dc6fb5ceab7675c384
parent 67992e364c3527c491a8f8298b8f64f028062d2e
Author: NunoSempere <nuno.sempere@protonmail.com>
Date: Sun, 30 Apr 2023 11:35:20 -0400
feat: create print_ast function!
Diffstat:
| M | mumble | | | 0 | |
| M | src/mumble.c | | | 98 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------- |
2 files changed, 85 insertions(+), 13 deletions(-)
diff --git a/mumble b/mumble
Binary files differ.
diff --git a/src/mumble.c b/src/mumble.c
@@ -2,8 +2,88 @@
#include <editline/readline.h>
#include <stdio.h>
#include <stdlib.h>
+#include <string.h>
#include "mpc/mpc.h"
+#define VERBOSE 1
+
+long evaluate_operation(char* op, long x, long y)
+{
+ if (!strcmp(op, "+")) {
+ return x + y;
+ } else if (!strcmp(op, "-")) {
+ return x - y;
+ } else if (!strcmp(op, "*")) {
+ return x * y;
+ } else if (!strcmp(op, "/")) {
+ return x / y;
+ } else if (!strcmp(op, "^")) {
+ return 42; // to take care of later
+ }
+ return 0;
+}
+
+long evaluate_ast(mpc_ast_t* t)
+{
+ // Base case #1: It's a number
+ if (VERBOSE)
+ printf("\n\nEvaluating the ast");
+ if (strstr(t->tag, "number")) {
+ if (VERBOSE)
+ printf("\nCase #1, %s", t->contents);
+ return atoi(t->contents);
+ }
+
+ // Base case #2: It's a number inputted into the REPL
+ // note: strcmp returns a 0 if both chars* have the same contents.
+ if (t->children_num == 2 && strstr(t->children[0]->tag, "number") && !strcmp(t->children[1]->tag, "regex")) {
+ if (VERBOSE)
+ printf("\nCase #2, %s", t->children[0]->contents);
+ return atoi(t->children[0]->contents);
+ }
+
+ // Case #3: Parenthesis case
+
+ if (t->children_num == 2 && !strcmp(t->children[0]->tag, "expr|>") && strstr(t->children[1]->tag, "regex")) {
+ return evaluate_ast(t->children[0]);
+ }
+ // Case #4: Unary operations case
+
+ // Case #5: Binary (or more) operations case
+ long x;
+ char* operation;
+ if (t->children_num > 3 && !strcmp(t->children[0]->tag, "regex") && strstr(t->children[1]->tag, "operator")) {
+ operation = t->children[1]->contents;
+ if (VERBOSE)
+ printf("\nCase #5, %s", operation);
+ x = evaluate_ast(t->children[2]);
+ int i = 3;
+ while ((i < t->children_num) && strstr(t->children[i]->tag, "expr")) {
+ long y = evaluate_ast(t->children[i]);
+ x = evaluate_operation(operation, x, y);
+ i++;
+ }
+ }
+
+ return x;
+}
+
+void print_ast(mpc_ast_t* ast, int num_tabs)
+{
+ char tabs[100] = "";
+ for(int i=0; i<num_tabs;i++){
+ strcat(tabs, " ");
+ }
+ printf("%sTag: %s\n", tabs, ast->tag);
+ printf("%sContents: %s\n", tabs, strcmp(ast->contents, "") ? ast->contents : "None");
+ printf("%sNumber of children: %i\n", tabs, ast->children_num);
+ /* Print the children */
+ for (int i = 0; i < ast->children_num; i++) {
+ mpc_ast_t* child_i = ast->children[i];
+ printf("%sChild #%d\n", tabs, i);
+ print_ast(child_i, 1);
+ }
+}
int main(int argc, char** argv)
{
@@ -40,19 +120,11 @@ int main(int argc, char** argv)
// mpc_ast_print(result.output);
/* Load AST from output */
mpc_ast_t* ast = result.output;
- char* no_contents = "None";
- printf("\n");
- printf("Tag: %s\n", ast->tag);
- printf("Contents: %s\n", strcmp(ast->contents, "") ? ast->contents : no_contents);
- printf("Number of children: %i\n", ast->children_num);
- /* Print the children */
- for(int i=0; i < ast->children_num; i++){
- mpc_ast_t* child_i = ast->children[i];
- printf("Child #%d\n", i);
- printf("\tTag: %s\n", child_i->tag);
- printf("\tContents: %s\n", strcmp(child_i->contents, "") ? child_i->contents : no_contents);
- printf("\tNumber of children: %i\n", child_i->children_num);
- }
+
+ // Print AST if VERBOSE
+ print_ast(ast, 0);
+ long result = evaluate_ast(ast);
+ printf("\nResult: %li\n", result);
} else {
/* Otherwise Print the Error */
mpc_err_print(result.error);