step: add unary operations
This commit is contained in:
parent
495418dadc
commit
dcfa3c1c99
41
src/mumble.c
41
src/mumble.c
|
@ -7,6 +7,15 @@
|
||||||
#include "mpc/mpc.h"
|
#include "mpc/mpc.h"
|
||||||
#define VERBOSE 1
|
#define VERBOSE 1
|
||||||
|
|
||||||
|
long evaluate_unary_operation(char* op, long x)
|
||||||
|
{
|
||||||
|
if (!strcmp(op, "+")) {
|
||||||
|
return x;
|
||||||
|
} else if (!strcmp(op, "-")) {
|
||||||
|
return -x;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
long evaluate_operation(char* op, long x, long y)
|
long evaluate_operation(char* op, long x, long y)
|
||||||
{
|
{
|
||||||
if (!strcmp(op, "+")) {
|
if (!strcmp(op, "+")) {
|
||||||
|
@ -17,8 +26,6 @@ long evaluate_operation(char* op, long x, long y)
|
||||||
return x * y;
|
return x * y;
|
||||||
} else if (!strcmp(op, "/")) {
|
} else if (!strcmp(op, "/")) {
|
||||||
return x / y;
|
return x / y;
|
||||||
} else if (!strcmp(op, "^")) {
|
|
||||||
return 42; // to take care of later
|
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -31,8 +38,6 @@ int is_ignorable(mpc_ast_t* t){
|
||||||
long evaluate_ast(mpc_ast_t* t)
|
long evaluate_ast(mpc_ast_t* t)
|
||||||
{
|
{
|
||||||
// Base case #1: It's a number
|
// Base case #1: It's a number
|
||||||
if (VERBOSE)
|
|
||||||
printf("\n\nEvaluating the ast");
|
|
||||||
if (strstr(t->tag, "number")) {
|
if (strstr(t->tag, "number")) {
|
||||||
if (VERBOSE)
|
if (VERBOSE)
|
||||||
printf("\nCase #1, %s", t->contents);
|
printf("\nCase #1, %s", t->contents);
|
||||||
|
@ -46,6 +51,7 @@ long evaluate_ast(mpc_ast_t* t)
|
||||||
printf("\nCase #2, %s", t->children[0]->contents);
|
printf("\nCase #2, %s", t->children[0]->contents);
|
||||||
return atoi(t->children[0]->contents);
|
return atoi(t->children[0]->contents);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Base case #3: Top level parenthesis
|
// Base case #3: Top level parenthesis
|
||||||
if (t->children_num == 2 && strstr(t->children[0]->tag, "expr|>") && !strcmp(t->children[1]->tag, "regex")) {
|
if (t->children_num == 2 && strstr(t->children[0]->tag, "expr|>") && !strcmp(t->children[1]->tag, "regex")) {
|
||||||
if (VERBOSE)
|
if (VERBOSE)
|
||||||
|
@ -53,10 +59,20 @@ long evaluate_ast(mpc_ast_t* t)
|
||||||
return evaluate_ast(t->children[0]);
|
return evaluate_ast(t->children[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Case #4: Unary operations case
|
// "Real" cases
|
||||||
// Case #5: Binary (or more) operations case
|
|
||||||
long x;
|
long x;
|
||||||
char* operation;
|
char* operation;
|
||||||
|
|
||||||
|
// Case #4: Unary operations case
|
||||||
|
if (t->children_num == 3 && is_ignorable(t->children[0]) && strstr(t->children[1]->tag, "operator")) {
|
||||||
|
operation = t->children[1]->contents;
|
||||||
|
if (VERBOSE)
|
||||||
|
printf("\nCase #4, unary operation %s", operation);
|
||||||
|
x = evaluate_ast(t->children[2]);
|
||||||
|
x = evaluate_unary_operation(operation, x);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Case #5: Binary (or more) operations case
|
||||||
if (t->children_num > 3 && is_ignorable(t->children[0]) && strstr(t->children[1]->tag, "operator")) {
|
if (t->children_num > 3 && is_ignorable(t->children[0]) && strstr(t->children[1]->tag, "operator")) {
|
||||||
operation = t->children[1]->contents;
|
operation = t->children[1]->contents;
|
||||||
if (VERBOSE)
|
if (VERBOSE)
|
||||||
|
@ -80,13 +96,13 @@ void print_ast(mpc_ast_t* ast, int num_tabs)
|
||||||
for(int i=0; i<num_tabs;i++){
|
for(int i=0; i<num_tabs;i++){
|
||||||
strcat(tabs, " ");
|
strcat(tabs, " ");
|
||||||
}
|
}
|
||||||
printf("%sTag: %s\n", tabs, ast->tag);
|
printf("\n%sTag: %s", tabs, ast->tag);
|
||||||
printf("%sContents: %s\n", tabs, strcmp(ast->contents, "") ? ast->contents : "None");
|
printf("\n%sContents: %s", tabs, strcmp(ast->contents, "") ? ast->contents : "None");
|
||||||
printf("%sNumber of children: %i\n", tabs, ast->children_num);
|
printf("\n%sNumber of children: %i", tabs, ast->children_num);
|
||||||
/* Print the children */
|
/* Print the children */
|
||||||
for (int i = 0; i < ast->children_num; i++) {
|
for (int i = 0; i < ast->children_num; i++) {
|
||||||
mpc_ast_t* child_i = ast->children[i];
|
mpc_ast_t* child_i = ast->children[i];
|
||||||
printf("%sChild #%d\n", tabs, i);
|
printf("\n%sChild #%d", tabs, i);
|
||||||
print_ast(child_i, 1);
|
print_ast(child_i, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -128,7 +144,10 @@ int main(int argc, char** argv)
|
||||||
mpc_ast_t* ast = result.output;
|
mpc_ast_t* ast = result.output;
|
||||||
|
|
||||||
// Print AST if VERBOSE
|
// Print AST if VERBOSE
|
||||||
print_ast(ast, 0);
|
if(VERBOSE) print_ast(ast, 0);
|
||||||
|
|
||||||
|
// Evaluate the AST
|
||||||
|
if(VERBOSE) printf("\n\nEvaluating the AST");
|
||||||
long result = evaluate_ast(ast);
|
long result = evaluate_ast(ast);
|
||||||
printf("\nResult: %li\n", result);
|
printf("\nResult: %li\n", result);
|
||||||
} else {
|
} else {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user