From 081005c5fc8b0525398de537a0469d3d08f23760 Mon Sep 17 00:00:00 2001 From: Riley Smith Date: Thu, 14 Nov 2024 13:52:26 -0800 Subject: [PATCH] allow variadic arguments for print --- lab-5/Makefile | 2 +- lab-5/expr.c | 30 ++++++++++++++------- lab-5/expr.h | 1 + lab-5/main.c | 2 +- lab-5/parser.bison | 26 +++++++++++++++--- lab-5/samples/hello-world-multiple-args.cbl | 5 ++++ 6 files changed, 50 insertions(+), 16 deletions(-) create mode 100644 lab-5/samples/hello-world-multiple-args.cbl diff --git a/lab-5/Makefile b/lab-5/Makefile index 8b3e50d..fe7e657 100644 --- a/lab-5/Makefile +++ b/lab-5/Makefile @@ -2,7 +2,7 @@ # The top level rule indicates how to link everything together into main main: main.o symbol_map.o expr.o scanner.o parser.o - gcc -g3 main.o symbol_map.o expr.o scanner.o parser.o -o interpreter.out -lm + gcc main.o symbol_map.o expr.o scanner.o parser.o -o interpreter.out -lm test: main_test.o symbol_map.o expr.o scanner.o parser.o gcc main_test.o symbol_map.o expr.o scanner.o parser.o -o interpreter_test.out -lm diff --git a/lab-5/expr.c b/lab-5/expr.c index 1bbd990..2bbc583 100644 --- a/lab-5/expr.c +++ b/lab-5/expr.c @@ -264,16 +264,7 @@ void stmt_evaluate(struct stmt *s) { } break; case STMT_PRINT: - if (s->expr->kind == EXPR_STRING_LITERAL) { - printf("%s", expr_string_evaluate(s->expr)); - } else if (s->expr->kind == EXPR_FLOAT_LITERAL) { - printf("%f", expr_evaluate(s->expr)); - } else if (s->expr->kind == EXPR_INTEGER_LITERAL || - s->expr->kind == EXPR_NAME || s->expr->kind == EXPR_SUBSCRIPT) { - printf("%.0f", expr_evaluate(s->expr)); - } else { - printf("runtime error: print expression is not literal\n"); - } + stmt_evaluate_print(s->expr); break; case STMT_BLOCK: stmt_evaluate(s->body); @@ -285,6 +276,25 @@ void stmt_evaluate(struct stmt *s) { stmt_evaluate(s->next); } +void stmt_evaluate_print(struct expr *e) { + if (!e) + return; + + + if (e->kind == EXPR_STRING_LITERAL) { + printf("%s", expr_string_evaluate(e)); + } else if (e->kind == EXPR_FLOAT_LITERAL) { + printf("%f", expr_evaluate(e)); + } else if (e->kind == EXPR_INTEGER_LITERAL || + e->kind == EXPR_NAME || e->kind == EXPR_SUBSCRIPT) { + printf("%.0f", expr_evaluate(e)); + } else { + printf("runtime error: print expression is not literal\n"); + } + + stmt_evaluate_print(e->right); +} + void decl_evaluate(struct decl *d) { if (!d) return; diff --git a/lab-5/expr.h b/lab-5/expr.h index bf404b4..260c055 100644 --- a/lab-5/expr.h +++ b/lab-5/expr.h @@ -106,6 +106,7 @@ void expr_print(struct expr *e); void stmt_evaluate(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); float expr_evaluate(struct expr *e); struct expr *expr_sub_evaluate(struct expr *e); diff --git a/lab-5/main.c b/lab-5/main.c index c0ba9d7..404b46d 100644 --- a/lab-5/main.c +++ b/lab-5/main.c @@ -24,7 +24,7 @@ int main(int argc, char *argv[]) { "Enter an infix expression using the operators +-*/() ending with ;\n\n"); if (yyparse() == 0) { - printf("Parse successful: "); + printf("Parse successful: \n"); if (parser_result != NULL) { stmt_print(parser_result); printf("\n"); diff --git a/lab-5/parser.bison b/lab-5/parser.bison index 9a92090..a81823a 100644 --- a/lab-5/parser.bison +++ b/lab-5/parser.bison @@ -12,7 +12,7 @@ YYSTYPE is the lexical value returned by each rule in a bison grammar. By default, it is an integer. In this example, we are returning a pointer to an expression. */ -#define YYSTYPE struct stmt * +// #define YYSTYPE struct stmt * /* Clunky: Manually declare the interface to the scanner generated by flex. @@ -83,6 +83,21 @@ struct stmt *parser_result = 0; %token TOKEN_EXPONENTIAL %token TOKEN_DISPLAY + +%left TOKEN_ADD TOKEN_SUB +%left TOKEN_MULTIPLY TOKEN_DIVIDE +%left TOKEN_EXPONENTIAL + +%union { + struct expr *expr; + struct stmt *stmt; + struct decl *decl; +} + +%type statement_list statement section stop_run sect_data simple_stmt data_declaration cbl_func_stmt cbl_function +%type mathmaticalexpr booleanexpr term op_parm container_expr type_expr op_parms math_op +%type assignment_stmt + %% file : statement_list {parser_result = $1; return 0;} @@ -128,15 +143,18 @@ cbl_func_stmt : cbl_function | cbl_function op_parms {$$ = stmt_create($1->kind, NULL, NULL, $2, NULL, NULL, NULL, NULL);} | cbl_function assignment_stmt + {$$ = stmt_create($1->kind, NULL, NULL, NULL, NULL, $2, NULL, NULL);} | cbl_function op_parm assignment_stmt ; assignment_stmt : TOKEN_EQUAL op_parms + {$$ = decl_create(NULL, NULL, $2, NULL, NULL);} | TOKEN_KEYWORD_TO op_parms + {$$ = decl_create(NULL, NULL, $2, NULL, NULL);} ; op_parms : op_parm {$$ = $1;} | op_parm op_parms - {$$ = $1; $1->next_expr = $2;} + {$$ = $1; $1->right = $2;} ; op_parm : mathmaticalexpr {$$ = $1;} @@ -160,11 +178,11 @@ math_op : TOKEN_ADD mathmaticalexpr : type_expr {$$ = $1;} | mathmaticalexpr math_op term - + {$$ = expr_create($2->kind, $1, $3);} | container_expr {$$ = $1;} | type_expr container_expr - {$$ = $1; $1->next_expr = $2;} + {$$ = $1; $1->right = $2;} ; container_expr : TOKEN_LEFT_PARENTHESIS mathmaticalexpr TOKEN_RIGHT_PARENTHESIS ; diff --git a/lab-5/samples/hello-world-multiple-args.cbl b/lab-5/samples/hello-world-multiple-args.cbl new file mode 100644 index 0000000..6bb7043 --- /dev/null +++ b/lab-5/samples/hello-world-multiple-args.cbl @@ -0,0 +1,5 @@ +IDENTIFICATION DIVISION. +PROGRAM-ID. HELLO-WORLD. +PROCEDURE DIVISION. + DISPLAY 'Hello World!' 'Hello World' 'Lorem Ipsum' +STOP RUN.