allow variadic arguments for print

This commit is contained in:
vel 2024-11-14 13:52:26 -08:00
parent 514f10062b
commit 081005c5fc
Signed by: velvox
GPG Key ID: 59D9762F674151DF
6 changed files with 50 additions and 16 deletions

View File

@ -2,7 +2,7 @@
# The top level rule indicates how to link everything together into main # The top level rule indicates how to link everything together into main
main: main.o symbol_map.o expr.o scanner.o parser.o 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 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 gcc main_test.o symbol_map.o expr.o scanner.o parser.o -o interpreter_test.out -lm

View File

@ -264,16 +264,7 @@ void stmt_evaluate(struct stmt *s) {
} }
break; break;
case STMT_PRINT: case STMT_PRINT:
if (s->expr->kind == EXPR_STRING_LITERAL) { stmt_evaluate_print(s->expr);
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");
}
break; break;
case STMT_BLOCK: case STMT_BLOCK:
stmt_evaluate(s->body); stmt_evaluate(s->body);
@ -285,6 +276,25 @@ void stmt_evaluate(struct stmt *s) {
stmt_evaluate(s->next); 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) { void decl_evaluate(struct decl *d) {
if (!d) if (!d)
return; return;

View File

@ -106,6 +106,7 @@ void expr_print(struct expr *e);
void stmt_evaluate(struct stmt *e); void stmt_evaluate(struct stmt *e);
void decl_evaluate(struct decl *e); void decl_evaluate(struct decl *e);
void stmt_evaluate_print(struct expr *e);
void decl_subscript_evaluate(struct expr *e, float value); void decl_subscript_evaluate(struct expr *e, float value);
float expr_evaluate(struct expr *e); float expr_evaluate(struct expr *e);
struct expr *expr_sub_evaluate(struct expr *e); struct expr *expr_sub_evaluate(struct expr *e);

View File

@ -24,7 +24,7 @@ int main(int argc, char *argv[]) {
"Enter an infix expression using the operators +-*/() ending with ;\n\n"); "Enter an infix expression using the operators +-*/() ending with ;\n\n");
if (yyparse() == 0) { if (yyparse() == 0) {
printf("Parse successful: "); printf("Parse successful: \n");
if (parser_result != NULL) { if (parser_result != NULL) {
stmt_print(parser_result); stmt_print(parser_result);
printf("\n"); printf("\n");

View File

@ -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. 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. 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_EXPONENTIAL
%token TOKEN_DISPLAY %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 <stmt> statement_list statement section stop_run sect_data simple_stmt data_declaration cbl_func_stmt cbl_function
%type <expr> mathmaticalexpr booleanexpr term op_parm container_expr type_expr op_parms math_op
%type <decl> assignment_stmt
%% %%
file : statement_list file : statement_list
{parser_result = $1; return 0;} {parser_result = $1; return 0;}
@ -128,15 +143,18 @@ cbl_func_stmt : cbl_function
| cbl_function op_parms | cbl_function op_parms
{$$ = stmt_create($1->kind, NULL, NULL, $2, NULL, NULL, NULL, NULL);} {$$ = stmt_create($1->kind, NULL, NULL, $2, NULL, NULL, NULL, NULL);}
| cbl_function assignment_stmt | cbl_function assignment_stmt
{$$ = stmt_create($1->kind, NULL, NULL, NULL, NULL, $2, NULL, NULL);}
| cbl_function op_parm assignment_stmt | cbl_function op_parm assignment_stmt
; ;
assignment_stmt : TOKEN_EQUAL op_parms assignment_stmt : TOKEN_EQUAL op_parms
{$$ = decl_create(NULL, NULL, $2, NULL, NULL);}
| TOKEN_KEYWORD_TO op_parms | TOKEN_KEYWORD_TO op_parms
{$$ = decl_create(NULL, NULL, $2, NULL, NULL);}
; ;
op_parms : op_parm op_parms : op_parm
{$$ = $1;} {$$ = $1;}
| op_parm op_parms | op_parm op_parms
{$$ = $1; $1->next_expr = $2;} {$$ = $1; $1->right = $2;}
; ;
op_parm : mathmaticalexpr op_parm : mathmaticalexpr
{$$ = $1;} {$$ = $1;}
@ -160,11 +178,11 @@ math_op : TOKEN_ADD
mathmaticalexpr : type_expr mathmaticalexpr : type_expr
{$$ = $1;} {$$ = $1;}
| mathmaticalexpr math_op term | mathmaticalexpr math_op term
{$$ = expr_create($2->kind, $1, $3);}
| container_expr | container_expr
{$$ = $1;} {$$ = $1;}
| type_expr container_expr | type_expr container_expr
{$$ = $1; $1->next_expr = $2;} {$$ = $1; $1->right = $2;}
; ;
container_expr : TOKEN_LEFT_PARENTHESIS mathmaticalexpr TOKEN_RIGHT_PARENTHESIS container_expr : TOKEN_LEFT_PARENTHESIS mathmaticalexpr TOKEN_RIGHT_PARENTHESIS
; ;

View File

@ -0,0 +1,5 @@
IDENTIFICATION DIVISION.
PROGRAM-ID. HELLO-WORLD.
PROCEDURE DIVISION.
DISPLAY 'Hello World!' 'Hello World' 'Lorem Ipsum'
STOP RUN.