diff --git a/lab-5/expr.c b/lab-5/expr.c index 506aa1d..45c7592 100644 --- a/lab-5/expr.c +++ b/lab-5/expr.c @@ -3,6 +3,7 @@ #include #include #include +#include static struct SymbolMap *symbol_table = NULL; @@ -34,12 +35,6 @@ struct stmt *stmt_create(stmt_t kind, struct decl *decl, struct expr *init_expr, struct stmt *body, struct stmt *else_body, struct stmt *next) { struct stmt *s = malloc(sizeof(*s)); - if (kind == STMT_COMPUTE) { - if (decl) { - printf("name: %s\n", decl->name->name); - - } - } s->kind = kind; s->decl = decl; s->init_expr = init_expr; @@ -68,7 +63,7 @@ struct expr *expr_create(expr_t kind, struct expr *left, struct expr *right) { struct expr *expr_create_name(const char *value) { struct expr *e = expr_create(EXPR_NAME, 0, 0); - char *dest = malloc(sizeof(*value)); + char *dest = malloc(strlen(value) + 1); strcpy(dest, value); // copy contents of source to dest e->name = dest; return e; @@ -299,6 +294,9 @@ void stmt_evaluate(struct stmt *s) { break; case STMT_END_EXECUTION: break; + case STMT_COMPUTE: + stmt_evaluate_compute(s); + break; } stmt_evaluate(s->next); @@ -323,13 +321,23 @@ void stmt_evaluate_print(struct expr *e) { stmt_evaluate_print(e->right); } +void stmt_evaluate_compute(struct stmt *s) { + if (!s) + return; + + if (s->kind == STMT_COMPUTE) { + decl_evaluate(s->decl); + } +} + void decl_evaluate(struct decl *d) { if (!d) return; - printf("decl_evaluate\n"); - - + if (!d->value) { + printf("decl_evaluate: no value\n"); + return; + } if (d->name->kind == EXPR_NAME && d->value->kind == EXPR_ARRAY) { struct expr *e = expr_sub_evaluate(d->value); scope_bind(d->name->name, e); @@ -446,6 +454,15 @@ float expr_subscript_evaluate(struct expr *e) { return expr_evaluate(a->left); } +float expr_evaluate_custom_function(struct expr *e) { + if (strcmp(e->left->name, "SQRT") == 0) { + return sqrt(expr_evaluate(e->right)); + } + + printf("runtime error: unknown custom function\n"); + exit(1); +} + float expr_evaluate(struct expr *e) { /* Careful: Return zero on null pointer. */ if (!e) @@ -456,10 +473,14 @@ float expr_evaluate(struct expr *e) { float l = expr_evaluate(e->left); float r = expr_evaluate(e->right); + float result; switch (e->kind) { case EXPR_NAME: // Get the variable expression and then evaluate it. + if (e->negative) { + return -expr_evaluate(scope_lookup(e->name)); + } return expr_evaluate(scope_lookup(e->name)); case EXPR_ARRAY: printf("runtime error: array in expression\n"); @@ -499,9 +520,19 @@ float expr_evaluate(struct expr *e) { case EXPR_STRING_LITERAL: printf("runtime error: string in expression\n"); exit(1); + case EXPR_VALUE: + return e->integer_value; + case EXPR_OCCURS: + return e->integer_value; + case EXPR_EXPONENTIAL: + return pow(l, r); + case EXPR_CUSTOM_FUNCTION: + result = expr_evaluate_custom_function(e); + return result; } return 0; } + void close_parser() { destroySymbolMap(symbol_table); } diff --git a/lab-5/expr.h b/lab-5/expr.h index f7148cf..d7b5442 100644 --- a/lab-5/expr.h +++ b/lab-5/expr.h @@ -71,6 +71,7 @@ struct decl { struct expr *name; struct type *type; struct expr *value; + struct expr *occurs; struct stmt *code; struct decl *next; }; @@ -122,6 +123,7 @@ void expr_print(struct expr *e); void ast_print(struct stmt *e); void stmt_evaluate(struct stmt *e); +void stmt_evaluate_compute(struct stmt *e); void decl_evaluate(struct decl *e); void stmt_evaluate_print(struct expr *e); void decl_subscript_evaluate(struct expr *e, float value); @@ -129,6 +131,7 @@ float expr_evaluate(struct expr *e); struct expr *expr_sub_evaluate(struct expr *e); float expr_subscript_evaluate(struct expr *e); const char *expr_string_evaluate(struct expr *e); +float expr_evaluate_custom_function(struct expr *e); void expr_delete(struct expr *e); void close_parser(); diff --git a/lab-5/main.c b/lab-5/main.c index 2169a20..e9f956a 100644 --- a/lab-5/main.c +++ b/lab-5/main.c @@ -28,7 +28,7 @@ int main(int argc, char *argv[]) { if (parser_result != NULL) { stmt_print(parser_result); printf("\n"); - printf("Running the program, results in: "); + printf("Running the program, results in: \n"); stmt_evaluate(parser_result); printf("\n"); } diff --git a/lab-5/parser.bison b/lab-5/parser.bison index b08bf80..ea9889f 100644 --- a/lab-5/parser.bison +++ b/lab-5/parser.bison @@ -262,9 +262,9 @@ data_clause : TOKEN_COMPUTATION_LEVEL_0 | ; category_value : TOKEN_KEYWORD_VALUE TOKEN_INTEGER - {$$ = expr_create_integer_literal(atoi(yytext));} + {$$ = expr_create_integer_literal(atoi(yytext)); $$->kind = EXPR_VALUE;} | TOKEN_KEYWORD_OCCURS TOKEN_INTEGER - {$$ = expr_create_integer_literal(atoi(yytext));} + {$$ = expr_create_integer_literal(atoi(yytext)); $$->kind = EXPR_OCCURS;} | {$$ = expr_create(EXPR_NULL, NULL, NULL);} ; @@ -275,7 +275,7 @@ category_spec : complete_category ; //TODO: implement levels simple_decl : TOKEN_INTEGER ident TOKEN_DOT - {$$ = decl_create($2, NULL, NULL, NULL, NULL);} + {$$ = decl_create($2, NULL, expr_create(EXPR_NULL, NULL, NULL), NULL, NULL);} ; complex_decl : TOKEN_INTEGER ident TOKEN_PICTURE category_spec TOKEN_DOT {$$ = decl_create($2, $4->type, $4->value, NULL, NULL);} diff --git a/lab-5/samples/quadratic-snippet.cbl b/lab-5/samples/quadratic-snippet.cbl index 00eb26f..9b0cbe3 100644 --- a/lab-5/samples/quadratic-snippet.cbl +++ b/lab-5/samples/quadratic-snippet.cbl @@ -16,7 +16,6 @@ PROCEDURE DIVISION. *> program begins here DISPLAY "EQUATION: (1x^2) + 5x + 6 = 0" COMPUTE discriminant = (b ** 2) - (4 * a * c) - IF discriminant > 0 COMPUTE square-root-discriminant = FUNCTION SQRT(discriminant) COMPUTE root1 = (-b + square-root-discriminant) / (2 * a)