allow variadic arguments for print
This commit is contained in:
parent
514f10062b
commit
081005c5fc
|
|
@ -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
|
||||||
|
|
|
||||||
30
lab-5/expr.c
30
lab-5/expr.c
|
|
@ -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;
|
||||||
|
|
|
||||||
|
|
@ -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);
|
||||||
|
|
|
||||||
|
|
@ -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");
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
;
|
;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
IDENTIFICATION DIVISION.
|
||||||
|
PROGRAM-ID. HELLO-WORLD.
|
||||||
|
PROCEDURE DIVISION.
|
||||||
|
DISPLAY 'Hello World!' 'Hello World' 'Lorem Ipsum'
|
||||||
|
STOP RUN.
|
||||||
Loading…
Reference in New Issue