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
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

View File

@ -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;

View File

@ -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);

View File

@ -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");

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.
*/
#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 <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
{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
;

View File

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