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
|
||||
|
||||
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
|
||||
|
|
|
|||
30
lab-5/expr.c
30
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;
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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
|
||||
;
|
||||
|
|
|
|||
|
|
@ -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