copy over changes from main repo
This commit is contained in:
parent
141b10c9c9
commit
5ee9afbcc1
54
expr.c
54
expr.c
|
|
@ -169,6 +169,15 @@ void stmt_print(struct stmt *s) {
|
||||||
case STMT_END_EXECUTION:
|
case STMT_END_EXECUTION:
|
||||||
printf("stop run\n");
|
printf("stop run\n");
|
||||||
break;
|
break;
|
||||||
|
case STMT_PERFORM:
|
||||||
|
decl_print(s->decl);
|
||||||
|
printf("; while ");
|
||||||
|
expr_print(s->expr);
|
||||||
|
printf(" do ");
|
||||||
|
expr_print(s->next_expr);
|
||||||
|
printf("\n");
|
||||||
|
printf(" ");
|
||||||
|
stmt_print(s->body);
|
||||||
}
|
}
|
||||||
|
|
||||||
stmt_print(s->next);
|
stmt_print(s->next);
|
||||||
|
|
@ -312,11 +321,33 @@ void stmt_evaluate(struct stmt *s) {
|
||||||
case STMT_COMPUTE:
|
case STMT_COMPUTE:
|
||||||
stmt_evaluate_compute(s);
|
stmt_evaluate_compute(s);
|
||||||
break;
|
break;
|
||||||
|
case STMT_PERFORM:
|
||||||
|
// evaluate the declaration
|
||||||
|
decl_evaluate(s->decl);
|
||||||
|
// now we can loop
|
||||||
|
stmt_evaluate_perform(s);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
stmt_evaluate(s->next);
|
stmt_evaluate(s->next);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void stmt_evaluate_perform(struct stmt *s) {
|
||||||
|
if (!s) return;
|
||||||
|
|
||||||
|
// Initial value has already been set by decl_evaluate in stmt_evaluate
|
||||||
|
|
||||||
|
// Keep looping until the condition is met
|
||||||
|
while (!expr_evaluate(s->expr)) {
|
||||||
|
// Execute the loop body
|
||||||
|
stmt_evaluate(s->body);
|
||||||
|
|
||||||
|
// Increment the loop variable
|
||||||
|
// s->next_expr contains the increment expression (name + BY value)
|
||||||
|
decl_evaluate(decl_create(s->decl->name, NULL, s->next_expr, NULL, NULL));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void stmt_evaluate_print(struct expr *e) {
|
void stmt_evaluate_print(struct expr *e) {
|
||||||
if (!e)
|
if (!e)
|
||||||
return;
|
return;
|
||||||
|
|
@ -328,6 +359,9 @@ void stmt_evaluate_print(struct expr *e) {
|
||||||
printf("%f", expr_evaluate(e));
|
printf("%f", expr_evaluate(e));
|
||||||
} else if (e->kind == EXPR_INTEGER_LITERAL || e->kind == EXPR_SUBSCRIPT) {
|
} else if (e->kind == EXPR_INTEGER_LITERAL || e->kind == EXPR_SUBSCRIPT) {
|
||||||
printf("%.0f", expr_evaluate(e));
|
printf("%.0f", expr_evaluate(e));
|
||||||
|
if (e->kind == EXPR_SUBSCRIPT) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
} else if (e->kind == EXPR_NAME) {
|
} else if (e->kind == EXPR_NAME) {
|
||||||
struct expr *value = scope_lookup(e->name);
|
struct expr *value = scope_lookup(e->name);
|
||||||
stmt_evaluate_print(value);
|
stmt_evaluate_print(value);
|
||||||
|
|
@ -356,7 +390,7 @@ void decl_evaluate(struct decl *d) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (d->name->kind == EXPR_NAME && d->value->kind == EXPR_ARRAY) {
|
if (d->name->kind == EXPR_NAME && d->value->kind == EXPR_ARRAY) {
|
||||||
struct expr *e = expr_sub_evaluate(d->value);
|
struct expr *e = expr_sub_evaluate(d->value, d->type);
|
||||||
scope_bind(d->name->name, e);
|
scope_bind(d->name->name, e);
|
||||||
} else if (d->name->kind == EXPR_NAME) {
|
} else if (d->name->kind == EXPR_NAME) {
|
||||||
if (d->value->kind != EXPR_STRING_LITERAL) {
|
if (d->value->kind != EXPR_STRING_LITERAL) {
|
||||||
|
|
@ -387,7 +421,7 @@ void decl_subscript_evaluate(struct expr *e, float value) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e->left->kind != EXPR_NAME) {
|
if (e->left == NULL || e->left->kind != EXPR_NAME) {
|
||||||
printf("runtime error: subscript has no name\n");
|
printf("runtime error: subscript has no name\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
@ -395,6 +429,10 @@ void decl_subscript_evaluate(struct expr *e, float value) {
|
||||||
// Get array expresion
|
// Get array expresion
|
||||||
struct expr *a = scope_lookup(e->left->name);
|
struct expr *a = scope_lookup(e->left->name);
|
||||||
float index = expr_evaluate(e->right);
|
float index = expr_evaluate(e->right);
|
||||||
|
if (!a) {
|
||||||
|
printf("runtime error: array not found\n");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
// Find the right offset
|
// Find the right offset
|
||||||
while (index > 0) {
|
while (index > 0) {
|
||||||
|
|
@ -437,14 +475,20 @@ const char *expr_string_evaluate(struct expr *e) {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
struct expr *expr_sub_evaluate(struct expr *e) {
|
struct expr *expr_sub_evaluate(struct expr *e, struct type *t) {
|
||||||
/* Careful: Return zero on null pointer. */
|
/* Careful: Return zero on null pointer. */
|
||||||
if (!e)
|
if (!e)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
// TODO evaluate each item in the array and save the result
|
// TODO evaluate each item in the array and save the result
|
||||||
|
if (!e->right) {
|
||||||
|
for (int i = 0; i < t->limit; i++) {
|
||||||
|
struct expr *temp = expr_create_float_literal(0);
|
||||||
|
e->right = expr_create(EXPR_ARRAY_ITEM, temp, e->right);
|
||||||
|
}
|
||||||
return e;
|
return e;
|
||||||
|
}
|
||||||
|
return expr_sub_evaluate(e->right, t);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
|
@ -462,7 +506,7 @@ float expr_subscript_evaluate(struct expr *e) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (e->left->kind != EXPR_NAME) {
|
if (e->left == NULL || e->left->kind != EXPR_NAME) {
|
||||||
printf("runtime error: subscript has no name\n");
|
printf("runtime error: subscript has no name\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
12
expr.h
12
expr.h
|
|
@ -37,7 +37,8 @@ typedef enum {
|
||||||
EXPR_NULL,
|
EXPR_NULL,
|
||||||
EXPR_CUSTOM_FUNCTION,
|
EXPR_CUSTOM_FUNCTION,
|
||||||
EXPR_OCCURS,
|
EXPR_OCCURS,
|
||||||
EXPR_VALUE
|
EXPR_VALUE,
|
||||||
|
EXPR_ARRAY_ITEM,
|
||||||
} expr_t;
|
} expr_t;
|
||||||
|
|
||||||
struct expr {
|
struct expr {
|
||||||
|
|
@ -55,7 +56,8 @@ typedef enum {
|
||||||
TYPE_ALPHANUMERIC,
|
TYPE_ALPHANUMERIC,
|
||||||
TYPE_IMPLIED_DECIMAL,
|
TYPE_IMPLIED_DECIMAL,
|
||||||
TYPE_NUMERIC,
|
TYPE_NUMERIC,
|
||||||
TYPE_SIGNED_NUMERIC
|
TYPE_SIGNED_NUMERIC,
|
||||||
|
TYPE_ARRAY
|
||||||
} type_t;
|
} type_t;
|
||||||
|
|
||||||
typedef enum { LEVEL_0, LEVEL_1, LEVEL_2, LEVEL_3 } computation_level_t;
|
typedef enum { LEVEL_0, LEVEL_1, LEVEL_2, LEVEL_3 } computation_level_t;
|
||||||
|
|
@ -86,6 +88,7 @@ typedef enum {
|
||||||
STMT_COMPUTE,
|
STMT_COMPUTE,
|
||||||
STMT_MOVE,
|
STMT_MOVE,
|
||||||
STMT_END_EXECUTION,
|
STMT_END_EXECUTION,
|
||||||
|
STMT_PERFORM
|
||||||
} stmt_t;
|
} stmt_t;
|
||||||
|
|
||||||
struct stmt {
|
struct stmt {
|
||||||
|
|
@ -124,11 +127,12 @@ void ast_print(struct stmt *e);
|
||||||
|
|
||||||
void stmt_evaluate(struct stmt *e);
|
void stmt_evaluate(struct stmt *e);
|
||||||
void stmt_evaluate_compute(struct stmt *e);
|
void stmt_evaluate_compute(struct stmt *e);
|
||||||
void decl_evaluate(struct decl *e);
|
|
||||||
void stmt_evaluate_print(struct expr *e);
|
void stmt_evaluate_print(struct expr *e);
|
||||||
|
void stmt_evaluate_perform(struct stmt *s);
|
||||||
|
void decl_evaluate(struct decl *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, struct type *t);
|
||||||
float expr_subscript_evaluate(struct expr *e);
|
float expr_subscript_evaluate(struct expr *e);
|
||||||
const char *expr_string_evaluate(struct expr *e);
|
const char *expr_string_evaluate(struct expr *e);
|
||||||
float expr_evaluate_custom_function(struct expr *e);
|
float expr_evaluate_custom_function(struct expr *e);
|
||||||
|
|
|
||||||
26
main_test.c
26
main_test.c
|
|
@ -135,11 +135,17 @@ UTEST_F(InterpreterTestFile, branching) {
|
||||||
utest_fixture->evaluated_file = "samples/outputs/branching_evaluate.txt";
|
utest_fixture->evaluated_file = "samples/outputs/branching_evaluate.txt";
|
||||||
}
|
}
|
||||||
|
|
||||||
// UTEST_F(InterpreterTestFile, looping) {
|
UTEST_F(InterpreterTestFile, looping) {
|
||||||
// utest_fixture->test_file = "samples/looping.cbl";
|
utest_fixture->test_file = "samples/looping.cbl";
|
||||||
// utest_fixture->print_file = "samples/outputs/looping_print.txt";
|
utest_fixture->print_file = "samples/outputs/looping_print.txt";
|
||||||
// utest_fixture->evaluated_file = "samples/outputs/looping_evaluate.txt";
|
utest_fixture->evaluated_file = "samples/outputs/looping_evaluate.txt";
|
||||||
// }
|
}
|
||||||
|
|
||||||
|
UTEST_F(InterpreterTestFile, array) {
|
||||||
|
utest_fixture->test_file = "samples/array.cbl";
|
||||||
|
utest_fixture->print_file = "samples/outputs/array_print.txt";
|
||||||
|
utest_fixture->evaluated_file = "samples/outputs/array_evaluate.txt";
|
||||||
|
}
|
||||||
|
|
||||||
UTEST_F(InterpreterTestFile, helloworld) {
|
UTEST_F(InterpreterTestFile, helloworld) {
|
||||||
utest_fixture->test_file = "samples/hello-world.cbl";
|
utest_fixture->test_file = "samples/hello-world.cbl";
|
||||||
|
|
@ -153,8 +159,8 @@ UTEST_F(InterpreterTestFile, quadratic) {
|
||||||
utest_fixture->evaluated_file = "samples/outputs/quadratic_evaluate.txt";
|
utest_fixture->evaluated_file = "samples/outputs/quadratic_evaluate.txt";
|
||||||
}
|
}
|
||||||
|
|
||||||
// UTEST_F(InterpreterTestFile, sorting) {
|
UTEST_F(InterpreterTestFile, sorting) {
|
||||||
// utest_fixture->test_file = "samples/sorting-snippet.cbl";
|
utest_fixture->test_file = "samples/sorting-snippet.cbl";
|
||||||
// utest_fixture->print_file = "samples/outputs/sorting_print.txt";
|
utest_fixture->print_file = "samples/outputs/sorting_print.txt";
|
||||||
// utest_fixture->evaluated_file = "samples/outputs/sorting_evaluate.txt";
|
utest_fixture->evaluated_file = "samples/outputs/sorting_evaluate.txt";
|
||||||
// }
|
}
|
||||||
|
|
|
||||||
22
parser.bison
22
parser.bison
|
|
@ -94,7 +94,7 @@ extern struct stmt *parser_result = 0;
|
||||||
struct type *type;
|
struct type *type;
|
||||||
}
|
}
|
||||||
|
|
||||||
%type <stmt> statement_list statement section stop_run sect_data simple_stmt cbl_func_stmt if_branch else_parts else_branch perform_stmt data_space display_stmt assignment_stmt
|
%type <stmt> statement_list statement section stop_run sect_data simple_stmt cbl_func_stmt if_branch else_parts else_branch perform_stmt data_space display_stmt assignment_stmt perform_header
|
||||||
%type <expr> mathmaticalexpr booleanexpr term op_parm container_expr type_expr op_parms math_op categry_contain category_value ident ext_function
|
%type <expr> mathmaticalexpr booleanexpr term op_parm container_expr type_expr op_parms math_op categry_contain category_value ident ext_function
|
||||||
%type <decl> simple_decl complex_decl data_declaration category_spec
|
%type <decl> simple_decl complex_decl data_declaration category_spec
|
||||||
%type <type> data_category complete_category data_clause
|
%type <type> data_category complete_category data_clause
|
||||||
|
|
@ -138,6 +138,7 @@ simple_stmt : cbl_func_stmt
|
||||||
| if_branch
|
| if_branch
|
||||||
{$$ = $1;}
|
{$$ = $1;}
|
||||||
| perform_stmt
|
| perform_stmt
|
||||||
|
{$$ = $1;}
|
||||||
;
|
;
|
||||||
cbl_func_stmt : display_stmt
|
cbl_func_stmt : display_stmt
|
||||||
{$$ = $1;}
|
{$$ = $1;}
|
||||||
|
|
@ -182,7 +183,7 @@ mathmaticalexpr : type_expr
|
||||||
| container_expr
|
| container_expr
|
||||||
{$$ = $1;}
|
{$$ = $1;}
|
||||||
| type_expr container_expr
|
| type_expr container_expr
|
||||||
{$$ = $1; $1->right = $2;}
|
{ $$ = expr_create(EXPR_SUBSCRIPT, $1, $2);}
|
||||||
;
|
;
|
||||||
container_expr : TOKEN_LEFT_PARENTHESIS mathmaticalexpr TOKEN_RIGHT_PARENTHESIS
|
container_expr : TOKEN_LEFT_PARENTHESIS mathmaticalexpr TOKEN_RIGHT_PARENTHESIS
|
||||||
{$$ = $2;}
|
{$$ = $2;}
|
||||||
|
|
@ -223,8 +224,14 @@ else_branch : TOKEN_ELSE_IF booleanexpr simple_stmt
|
||||||
{$$ = stmt_create(STMT_IF, NULL, NULL, expr_create(EXPR_EQUAL_EQUAL, expr_create_integer_literal(0), expr_create_integer_literal(0)), NULL, $2, NULL, NULL);}
|
{$$ = stmt_create(STMT_IF, NULL, NULL, expr_create(EXPR_EQUAL_EQUAL, expr_create_integer_literal(0), expr_create_integer_literal(0)), NULL, $2, NULL, NULL);}
|
||||||
| TOKEN_END_IF
|
| TOKEN_END_IF
|
||||||
{$$ = NULL;}
|
{$$ = NULL;}
|
||||||
perform_stmt : TOKEN_PERFORM TOKEN_VARYING ident TOKEN_KEYWORD_FROM TOKEN_INTEGER TOKEN_KEYWORD_BY TOKEN_INTEGER TOKEN_UNTIL op_parms
|
perform_stmt : perform_header statement_list TOKEN_END_PERFORM
|
||||||
| TOKEN_END_PERFORM
|
{$1->body = $2; $$=$1;}
|
||||||
|
;
|
||||||
|
// for (int i = 0; i < 10 i++)
|
||||||
|
perform_header : TOKEN_PERFORM TOKEN_VARYING ident TOKEN_KEYWORD_FROM type_expr TOKEN_KEYWORD_BY type_expr TOKEN_UNTIL op_parms
|
||||||
|
{
|
||||||
|
$$ = stmt_create(STMT_PERFORM, decl_create($3, NULL, $5, NULL, NULL), NULL, $9, expr_create(EXPR_ADD, $3, $7), NULL, NULL, NULL);
|
||||||
|
}
|
||||||
;
|
;
|
||||||
data_space : TOKEN_WORKING_STORAGE TOKEN_KEYWORD_SECTION TOKEN_DOT
|
data_space : TOKEN_WORKING_STORAGE TOKEN_KEYWORD_SECTION TOKEN_DOT
|
||||||
;
|
;
|
||||||
|
|
@ -264,7 +271,12 @@ category_value : TOKEN_KEYWORD_VALUE TOKEN_INTEGER
|
||||||
{$$ = expr_create(EXPR_NULL, NULL, NULL);}
|
{$$ = expr_create(EXPR_NULL, NULL, NULL);}
|
||||||
;
|
;
|
||||||
category_spec : complete_category data_clause category_value
|
category_spec : complete_category data_clause category_value
|
||||||
{ $1->level = $2->level; $$ = decl_create(NULL, $1, $3, NULL, NULL);}
|
{
|
||||||
|
if ($3->kind == EXPR_OCCURS) {
|
||||||
|
$1->limit = $3->integer_value;
|
||||||
|
$3->kind = EXPR_ARRAY;
|
||||||
|
}
|
||||||
|
$1->level = $2->level; $$ = decl_create(NULL, $1, $3, NULL, NULL);}
|
||||||
;
|
;
|
||||||
//TODO: implement levels
|
//TODO: implement levels
|
||||||
simple_decl : TOKEN_INTEGER ident TOKEN_DOT
|
simple_decl : TOKEN_INTEGER ident TOKEN_DOT
|
||||||
|
|
|
||||||
117
parser.bison.new
117
parser.bison.new
|
|
@ -1,117 +0,0 @@
|
||||||
%{
|
|
||||||
#define YYDEBUG 1
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include "expr.h"
|
|
||||||
|
|
||||||
/*
|
|
||||||
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 *
|
|
||||||
|
|
||||||
/*
|
|
||||||
Clunky: Manually declare the interface to the scanner generated by flex.
|
|
||||||
*/
|
|
||||||
|
|
||||||
extern char *yytext;
|
|
||||||
extern int yylex();
|
|
||||||
// void yyerror(struct stmt *parser_result, const char*);
|
|
||||||
void yyerror(const char*);
|
|
||||||
|
|
||||||
extern int yylineno;
|
|
||||||
|
|
||||||
struct stmt *parser_result = 0;
|
|
||||||
|
|
||||||
%}
|
|
||||||
|
|
||||||
// %parse-param {struct stmt *parser_result}
|
|
||||||
|
|
||||||
%debug
|
|
||||||
%define parse.error detailed
|
|
||||||
|
|
||||||
%token TOKEN_EOF
|
|
||||||
%token TOKEN_KEYWORD_IDENTIFICATION
|
|
||||||
%token TOKEN_KEYWORD_DIVISION
|
|
||||||
%token TOKEN_KEYWORD_DATA
|
|
||||||
%token TOKEN_KEYWORD_SECTION
|
|
||||||
%token TOKEN_PROGRAM_ID
|
|
||||||
%token TOKEN_WORKING_STORAGE
|
|
||||||
%token TOKEN_PROCEDURE
|
|
||||||
%token TOKEN_STOP
|
|
||||||
%token TOKEN_RUN
|
|
||||||
%token TOKEN_MOVE
|
|
||||||
%token TOKEN_KEYWORD_TO
|
|
||||||
%token TOKEN_PERFORM
|
|
||||||
%token TOKEN_VARYING
|
|
||||||
%token TOKEN_KEYWORD_FROM
|
|
||||||
%token TOKEN_KEYWORD_BY
|
|
||||||
%token TOKEN_UNTIL
|
|
||||||
%token TOKEN_END_PERFORM
|
|
||||||
%token TOKEN_IF
|
|
||||||
%token TOKEN_ELSE_IF
|
|
||||||
%token TOKEN_ELSE
|
|
||||||
%token TOKEN_END_IF
|
|
||||||
%token TOKEN_SPACE
|
|
||||||
%token TOKEN_KEYWORD_OCCURS
|
|
||||||
%token TOKEN_KEYWORD_VALUE
|
|
||||||
%token TOKEN_KEYWORD_COMPUTE
|
|
||||||
%token TOKEN_KEYWORD_FUNCTION
|
|
||||||
%token TOKEN_IDENT
|
|
||||||
%token TOKEN_STRING
|
|
||||||
%token TOKEN_INTEGER
|
|
||||||
%token TOKEN_PICTURE
|
|
||||||
%token TOKEN_ALPHANUMERIC
|
|
||||||
%token TOKEN_NUMERIC
|
|
||||||
%token TOKEN_SIGNED_NUMERIC
|
|
||||||
%token TOKEN_IMPLIED_DECIMAL
|
|
||||||
%token TOKEN_COMPUTATION_LEVEL_0
|
|
||||||
%token TOKEN_COMPUTATION_LEVEL_1
|
|
||||||
%token TOKEN_COMPUTATION_LEVEL_2
|
|
||||||
%token TOKEN_COMPUTATION_LEVEL_3
|
|
||||||
%token TOKEN_LEFT_PARENTHESIS
|
|
||||||
%token TOKEN_RIGHT_PARENTHESIS
|
|
||||||
%token TOKEN_DOT
|
|
||||||
%token TOKEN_ADD
|
|
||||||
%token TOKEN_SUB
|
|
||||||
%token TOKEN_MULTIPLY
|
|
||||||
%token TOKEN_DIVIDE
|
|
||||||
%token TOKEN_EQUAL
|
|
||||||
%token TOKEN_GREATER_THAN
|
|
||||||
%token TOKEN_LESS_THAN
|
|
||||||
%token TOKEN_EXPONENTIAL
|
|
||||||
%token TOKEN_DISPLAY
|
|
||||||
|
|
||||||
|
|
||||||
%%
|
|
||||||
file : statements
|
|
||||||
{parser_result = $1; return 0;}
|
|
||||||
;
|
|
||||||
statements : statements statement
|
|
||||||
{ $$ = $1; $1->next = $2; }
|
|
||||||
| statement
|
|
||||||
{ $$ = $1; }
|
|
||||||
;
|
|
||||||
statement : simple_stmt
|
|
||||||
{$$ = stmt_create(STMT_BLOCK, NULL, NULL, NULL, NULL, $1, NULL, NULL);}
|
|
||||||
;
|
|
||||||
simple_stmt : cbl_func_stmt
|
|
||||||
{$$ = $1;}
|
|
||||||
;
|
|
||||||
cbl_func_stmt : display_stmt
|
|
||||||
{$$ = $1;}
|
|
||||||
;
|
|
||||||
display_stmt : TOKEN_DISPLAY expr
|
|
||||||
{$$ = stmt_create(STMT_PRINT, NULL, NULL, $2, NULL, NULL, NULL, NULL);}
|
|
||||||
;
|
|
||||||
expr : TOKEN_STRING
|
|
||||||
{ $$ = expr_create_string_literal(yytext);}
|
|
||||||
;
|
|
||||||
%%
|
|
||||||
|
|
||||||
void yyerror(const char* msg) {
|
|
||||||
fprintf(stderr, "Error | Line: %d\n%s\n",yylineno,msg);
|
|
||||||
}
|
|
||||||
|
|
@ -71,7 +71,7 @@ UTEST(parser, branching) {
|
||||||
}
|
}
|
||||||
|
|
||||||
UTEST(parser, looping) {
|
UTEST(parser, looping) {
|
||||||
char string[] = "PERFORM VARYING I FROM 1 BY 1 UNTIL I > 10\0";
|
char string[] = "PERFORM VARYING I FROM 1 BY 1 UNTIL I > 10 DISPLAY I END-PERFORM\0";
|
||||||
YY_BUFFER_STATE buffer = yy_scan_buffer(string, sizeof(string));
|
YY_BUFFER_STATE buffer = yy_scan_buffer(string, sizeof(string));
|
||||||
|
|
||||||
yylineno = 1;
|
yylineno = 1;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
IDENTIFICATION DIVISION.
|
||||||
|
PROGRAM-ID. array.
|
||||||
|
DATA DIVISION.
|
||||||
|
WORKING-STORAGE SECTION.
|
||||||
|
01 WS-ARRAY.
|
||||||
|
05 WS-ARRAY-ROW PIC S9(4) OCCURS 4.
|
||||||
|
05 WS-ARRAY-INDEX PIC 9(3) VALUE 1.
|
||||||
|
|
||||||
|
PROCEDURE DIVISION.
|
||||||
|
MOVE 5 TO WS-ARRAY-ROW(1)
|
||||||
|
MOVE 10 TO WS-ARRAY-ROW(2)
|
||||||
|
MOVE 43 TO WS-ARRAY-ROW(3)
|
||||||
|
MOVE 101 TO WS-ARRAY-ROW(4)
|
||||||
|
DISPLAY "The first element is: " WS-ARRAY-ROW(1)
|
||||||
|
DISPLAY "The second element is: " WS-ARRAY-ROW(2)
|
||||||
|
DISPLAY "The third element is: " WS-ARRAY-ROW(3)
|
||||||
|
DISPLAY "The fourth element is: " WS-ARRAY-ROW(4)
|
||||||
|
STOP RUN.
|
||||||
|
|
@ -1,7 +1,12 @@
|
||||||
IDENTIFICATION DIVISION.
|
IDENTIFICATION DIVISION.
|
||||||
PROGRAM-ID. LOOPING.
|
PROGRAM-ID. LOOPING.
|
||||||
|
DATA DIVISION.
|
||||||
|
WORKING-STORAGE SECTION.
|
||||||
|
01 WS-I PIC 9(3) VALUE 1.
|
||||||
|
|
||||||
PROCEDURE DIVISION.
|
PROCEDURE DIVISION.
|
||||||
PERFORM VARYING I FROM 1 BY 1 UNTIL I > 10
|
PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > 10
|
||||||
DISPLAY I
|
DISPLAY WS-I
|
||||||
END-PERFORM
|
END-PERFORM
|
||||||
STOP RUN.
|
STOP RUN.
|
||||||
|
|
||||||
|
|
@ -0,0 +1,4 @@
|
||||||
|
The first element is: 5
|
||||||
|
The second element is: 10
|
||||||
|
The third element is: 43
|
||||||
|
The fourth element is: 101
|
||||||
|
|
@ -0,0 +1,17 @@
|
||||||
|
section
|
||||||
|
section
|
||||||
|
section
|
||||||
|
section
|
||||||
|
WS-ARRAY = ();
|
||||||
|
WS-ARRAY-ROW = [];
|
||||||
|
WS-ARRAY-INDEX = 1;
|
||||||
|
section
|
||||||
|
move 5 to WS-ARRAY-ROW[1];
|
||||||
|
move 10 to WS-ARRAY-ROW[2];
|
||||||
|
move 43 to WS-ARRAY-ROW[3];
|
||||||
|
move 101 to WS-ARRAY-ROW[4];
|
||||||
|
print The first element is: WS-ARRAY-ROW[1];
|
||||||
|
print The second element is: WS-ARRAY-ROW[2];
|
||||||
|
print The third element is: WS-ARRAY-ROW[3];
|
||||||
|
print The fourth element is: WS-ARRAY-ROW[4];
|
||||||
|
stop run
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
1.000000
|
||||||
|
2.000000
|
||||||
|
3.000000
|
||||||
|
4.000000
|
||||||
|
5.000000
|
||||||
|
6.000000
|
||||||
|
7.000000
|
||||||
|
8.000000
|
||||||
|
9.000000
|
||||||
|
10.000000
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
section
|
||||||
|
section
|
||||||
|
section
|
||||||
|
section
|
||||||
|
WS-I = 1;
|
||||||
|
section
|
||||||
|
WS-I = 1; while (WS-I>10) do (WS-I+1)
|
||||||
|
print WS-I;
|
||||||
|
stop run
|
||||||
|
|
@ -1,15 +1,15 @@
|
||||||
Original Array Contents:
|
Original Array Contents:
|
||||||
---------------------
|
---------------------
|
||||||
Element +0001: 30
|
Element 1.000000: 30
|
||||||
Element +0002: 10
|
Element 2.000000: 10
|
||||||
Element +0003: 50
|
Element 3.000000: 50
|
||||||
Element +0004: 20
|
Element 4.000000: 20
|
||||||
Element +0005: 40
|
Element 5.000000: 40
|
||||||
|
|
||||||
Sorted Array Contents:
|
Sorted Array Contents:
|
||||||
--------------------
|
--------------------
|
||||||
Element +0001: 10
|
Element 1.000000: 10
|
||||||
Element +0002: 20
|
Element 2.000000: 20
|
||||||
Element +0003: 30
|
Element 3.000000: 30
|
||||||
Element +0004: 40
|
Element 4.000000: 40
|
||||||
Element +0005: 50
|
Element 5.000000: 50
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,38 @@
|
||||||
|
section
|
||||||
|
section
|
||||||
|
section
|
||||||
|
section
|
||||||
|
WS-SORT-AREA = ();
|
||||||
|
WS-SORT-TABLE = ();
|
||||||
|
WS-SORT-ROW = [];
|
||||||
|
WS-TEMP-ROW = ();
|
||||||
|
WS-ROW-MAX = 100;
|
||||||
|
WS-SORT-MAX = ();
|
||||||
|
WS-I = ();
|
||||||
|
WS-J = ();
|
||||||
|
WS-INDEX = ();
|
||||||
|
section
|
||||||
|
move 30 to WS-SORT-ROW[1];
|
||||||
|
move 10 to WS-SORT-ROW[2];
|
||||||
|
move 50 to WS-SORT-ROW[3];
|
||||||
|
move 20 to WS-SORT-ROW[4];
|
||||||
|
move 40 to WS-SORT-ROW[5];
|
||||||
|
move 5 to WS-SORT-MAX;
|
||||||
|
print Original Array Contents:;
|
||||||
|
print ---------------------;
|
||||||
|
WS-INDEX = 1; while (WS-INDEX>WS-SORT-MAX) do (WS-INDEX+1)
|
||||||
|
print Element WS-INDEX: WS-SORT-ROW[WS-INDEX];
|
||||||
|
print ;
|
||||||
|
WS-I = 1; while (WS-I>(WS-SORT-MAX-1)) do (WS-I+1)
|
||||||
|
WS-J = 1; while (WS-J>(WS-SORT-MAX-WS-I)) do (WS-J+1)
|
||||||
|
if (WS-SORT-ROW[WS-J]>WS-SORT-ROW[(WS-J+1)]) then
|
||||||
|
move WS-SORT-ROW[WS-J] to WS-TEMP-ROW;
|
||||||
|
move WS-SORT-ROW[(WS-J+1)] to WS-SORT-ROW[WS-J];
|
||||||
|
move WS-TEMP-ROW to WS-SORT-ROW[(WS-J+1)];
|
||||||
|
endif
|
||||||
|
|
||||||
|
print Sorted Array Contents:;
|
||||||
|
print --------------------;
|
||||||
|
WS-INDEX = 1; while (WS-INDEX>WS-SORT-MAX) do (WS-INDEX+1)
|
||||||
|
print Element WS-INDEX: WS-SORT-ROW[WS-INDEX];
|
||||||
|
stop run
|
||||||
|
|
@ -4,8 +4,8 @@ DATA DIVISION.
|
||||||
WORKING-STORAGE SECTION.
|
WORKING-STORAGE SECTION.
|
||||||
01 WS-SORT-AREA.
|
01 WS-SORT-AREA.
|
||||||
05 WS-SORT-TABLE.
|
05 WS-SORT-TABLE.
|
||||||
10 WS-SORT-ROW PIC X(10) OCCURS 100.
|
10 WS-SORT-ROW PIC S9(4) OCCURS 100.
|
||||||
05 WS-TEMP-ROW PIC X(10).
|
05 WS-TEMP-ROW PIC S9(4).
|
||||||
05 WS-ROW-MAX PIC S9(4) COMP VALUE 100.
|
05 WS-ROW-MAX PIC S9(4) COMP VALUE 100.
|
||||||
05 WS-SORT-MAX PIC S9(4) COMP.
|
05 WS-SORT-MAX PIC S9(4) COMP.
|
||||||
05 WS-I PIC S9(4) COMP.
|
05 WS-I PIC S9(4) COMP.
|
||||||
|
|
@ -14,11 +14,11 @@ WORKING-STORAGE SECTION.
|
||||||
|
|
||||||
PROCEDURE DIVISION.
|
PROCEDURE DIVISION.
|
||||||
*> Initialize test data
|
*> Initialize test data
|
||||||
MOVE "30" TO WS-SORT-ROW(1)
|
MOVE 30 TO WS-SORT-ROW(1)
|
||||||
MOVE "10" TO WS-SORT-ROW(2)
|
MOVE 10 TO WS-SORT-ROW(2)
|
||||||
MOVE "50" TO WS-SORT-ROW(3)
|
MOVE 50 TO WS-SORT-ROW(3)
|
||||||
MOVE "20" TO WS-SORT-ROW(4)
|
MOVE 20 TO WS-SORT-ROW(4)
|
||||||
MOVE "40" TO WS-SORT-ROW(5)
|
MOVE 40 TO WS-SORT-ROW(5)
|
||||||
MOVE 5 TO WS-SORT-MAX
|
MOVE 5 TO WS-SORT-MAX
|
||||||
|
|
||||||
*> * Display original array
|
*> * Display original array
|
||||||
|
|
@ -28,7 +28,7 @@ PROCEDURE DIVISION.
|
||||||
UNTIL WS-INDEX > WS-SORT-MAX
|
UNTIL WS-INDEX > WS-SORT-MAX
|
||||||
DISPLAY "Element " WS-INDEX ": " WS-SORT-ROW(WS-INDEX)
|
DISPLAY "Element " WS-INDEX ": " WS-SORT-ROW(WS-INDEX)
|
||||||
END-PERFORM
|
END-PERFORM
|
||||||
DISPLAY SPACE
|
DISPLAY ""
|
||||||
|
|
||||||
*> * Simplified bubble sort
|
*> * Simplified bubble sort
|
||||||
PERFORM VARYING WS-I FROM 1 BY 1
|
PERFORM VARYING WS-I FROM 1 BY 1
|
||||||
|
|
|
||||||
|
|
@ -31,7 +31,7 @@ UTEST(scanner, hello) {
|
||||||
{TOKEN_KEYWORD_DIVISION, "DIVISION"},
|
{TOKEN_KEYWORD_DIVISION, "DIVISION"},
|
||||||
{TOKEN_DOT, "."},
|
{TOKEN_DOT, "."},
|
||||||
{TOKEN_DISPLAY, "DISPLAY"},
|
{TOKEN_DISPLAY, "DISPLAY"},
|
||||||
{TOKEN_STRING, "Hello World!"},
|
{TOKEN_STRING, "'Hello World!'"},
|
||||||
{TOKEN_STOP, "STOP"},
|
{TOKEN_STOP, "STOP"},
|
||||||
{TOKEN_RUN, "RUN"},
|
{TOKEN_RUN, "RUN"},
|
||||||
{TOKEN_DOT, "."},
|
{TOKEN_DOT, "."},
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue