copy over changes from main repo
This commit is contained in:
parent
141b10c9c9
commit
5ee9afbcc1
56
expr.c
56
expr.c
|
|
@ -169,6 +169,15 @@ void stmt_print(struct stmt *s) {
|
|||
case STMT_END_EXECUTION:
|
||||
printf("stop run\n");
|
||||
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);
|
||||
|
|
@ -312,11 +321,33 @@ void stmt_evaluate(struct stmt *s) {
|
|||
case STMT_COMPUTE:
|
||||
stmt_evaluate_compute(s);
|
||||
break;
|
||||
case STMT_PERFORM:
|
||||
// evaluate the declaration
|
||||
decl_evaluate(s->decl);
|
||||
// now we can loop
|
||||
stmt_evaluate_perform(s);
|
||||
break;
|
||||
}
|
||||
|
||||
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) {
|
||||
if (!e)
|
||||
return;
|
||||
|
|
@ -328,6 +359,9 @@ void stmt_evaluate_print(struct expr *e) {
|
|||
printf("%f", expr_evaluate(e));
|
||||
} else if (e->kind == EXPR_INTEGER_LITERAL || e->kind == EXPR_SUBSCRIPT) {
|
||||
printf("%.0f", expr_evaluate(e));
|
||||
if (e->kind == EXPR_SUBSCRIPT) {
|
||||
return;
|
||||
}
|
||||
} else if (e->kind == EXPR_NAME) {
|
||||
struct expr *value = scope_lookup(e->name);
|
||||
stmt_evaluate_print(value);
|
||||
|
|
@ -356,7 +390,7 @@ void decl_evaluate(struct decl *d) {
|
|||
return;
|
||||
}
|
||||
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);
|
||||
} else if (d->name->kind == EXPR_NAME) {
|
||||
if (d->value->kind != EXPR_STRING_LITERAL) {
|
||||
|
|
@ -387,7 +421,7 @@ void decl_subscript_evaluate(struct expr *e, float value) {
|
|||
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");
|
||||
exit(1);
|
||||
}
|
||||
|
|
@ -395,6 +429,10 @@ void decl_subscript_evaluate(struct expr *e, float value) {
|
|||
// Get array expresion
|
||||
struct expr *a = scope_lookup(e->left->name);
|
||||
float index = expr_evaluate(e->right);
|
||||
if (!a) {
|
||||
printf("runtime error: array not found\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
// Find the right offset
|
||||
while (index > 0) {
|
||||
|
|
@ -437,14 +475,20 @@ const char *expr_string_evaluate(struct expr *e) {
|
|||
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. */
|
||||
if (!e)
|
||||
return 0;
|
||||
|
||||
// TODO evaluate each item in the array and save the result
|
||||
|
||||
return e;
|
||||
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 expr_sub_evaluate(e->right, t);
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
@ -462,7 +506,7 @@ float expr_subscript_evaluate(struct expr *e) {
|
|||
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");
|
||||
exit(1);
|
||||
}
|
||||
|
|
|
|||
12
expr.h
12
expr.h
|
|
@ -37,7 +37,8 @@ typedef enum {
|
|||
EXPR_NULL,
|
||||
EXPR_CUSTOM_FUNCTION,
|
||||
EXPR_OCCURS,
|
||||
EXPR_VALUE
|
||||
EXPR_VALUE,
|
||||
EXPR_ARRAY_ITEM,
|
||||
} expr_t;
|
||||
|
||||
struct expr {
|
||||
|
|
@ -55,7 +56,8 @@ typedef enum {
|
|||
TYPE_ALPHANUMERIC,
|
||||
TYPE_IMPLIED_DECIMAL,
|
||||
TYPE_NUMERIC,
|
||||
TYPE_SIGNED_NUMERIC
|
||||
TYPE_SIGNED_NUMERIC,
|
||||
TYPE_ARRAY
|
||||
} type_t;
|
||||
|
||||
typedef enum { LEVEL_0, LEVEL_1, LEVEL_2, LEVEL_3 } computation_level_t;
|
||||
|
|
@ -86,6 +88,7 @@ typedef enum {
|
|||
STMT_COMPUTE,
|
||||
STMT_MOVE,
|
||||
STMT_END_EXECUTION,
|
||||
STMT_PERFORM
|
||||
} stmt_t;
|
||||
|
||||
struct stmt {
|
||||
|
|
@ -124,11 +127,12 @@ void ast_print(struct stmt *e);
|
|||
|
||||
void stmt_evaluate(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_perform(struct stmt *s);
|
||||
void decl_evaluate(struct decl *e);
|
||||
void decl_subscript_evaluate(struct expr *e, float value);
|
||||
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);
|
||||
const char *expr_string_evaluate(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_F(InterpreterTestFile, looping) {
|
||||
// utest_fixture->test_file = "samples/looping.cbl";
|
||||
// utest_fixture->print_file = "samples/outputs/looping_print.txt";
|
||||
// utest_fixture->evaluated_file = "samples/outputs/looping_evaluate.txt";
|
||||
// }
|
||||
UTEST_F(InterpreterTestFile, looping) {
|
||||
utest_fixture->test_file = "samples/looping.cbl";
|
||||
utest_fixture->print_file = "samples/outputs/looping_print.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_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_F(InterpreterTestFile, sorting) {
|
||||
// utest_fixture->test_file = "samples/sorting-snippet.cbl";
|
||||
// utest_fixture->print_file = "samples/outputs/sorting_print.txt";
|
||||
// utest_fixture->evaluated_file = "samples/outputs/sorting_evaluate.txt";
|
||||
// }
|
||||
UTEST_F(InterpreterTestFile, sorting) {
|
||||
utest_fixture->test_file = "samples/sorting-snippet.cbl";
|
||||
utest_fixture->print_file = "samples/outputs/sorting_print.txt";
|
||||
utest_fixture->evaluated_file = "samples/outputs/sorting_evaluate.txt";
|
||||
}
|
||||
|
|
|
|||
26
parser.bison
26
parser.bison
|
|
@ -94,8 +94,8 @@ extern struct stmt *parser_result = 0;
|
|||
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 <expr> mathmaticalexpr booleanexpr term op_parm container_expr type_expr op_parms math_op categry_contain category_value ident ext_function
|
||||
%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 <decl> simple_decl complex_decl data_declaration category_spec
|
||||
%type <type> data_category complete_category data_clause
|
||||
%%
|
||||
|
|
@ -138,6 +138,7 @@ simple_stmt : cbl_func_stmt
|
|||
| if_branch
|
||||
{$$ = $1;}
|
||||
| perform_stmt
|
||||
{$$ = $1;}
|
||||
;
|
||||
cbl_func_stmt : display_stmt
|
||||
{$$ = $1;}
|
||||
|
|
@ -182,7 +183,7 @@ mathmaticalexpr : type_expr
|
|||
| container_expr
|
||||
{$$ = $1;}
|
||||
| type_expr container_expr
|
||||
{$$ = $1; $1->right = $2;}
|
||||
{ $$ = expr_create(EXPR_SUBSCRIPT, $1, $2);}
|
||||
;
|
||||
container_expr : TOKEN_LEFT_PARENTHESIS mathmaticalexpr TOKEN_RIGHT_PARENTHESIS
|
||||
{$$ = $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);}
|
||||
| TOKEN_END_IF
|
||||
{$$ = NULL;}
|
||||
perform_stmt : TOKEN_PERFORM TOKEN_VARYING ident TOKEN_KEYWORD_FROM TOKEN_INTEGER TOKEN_KEYWORD_BY TOKEN_INTEGER TOKEN_UNTIL op_parms
|
||||
| TOKEN_END_PERFORM
|
||||
perform_stmt : perform_header statement_list 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
|
||||
;
|
||||
|
|
@ -259,12 +266,17 @@ data_clause : TOKEN_COMPUTATION_LEVEL_0
|
|||
category_value : TOKEN_KEYWORD_VALUE TOKEN_INTEGER
|
||||
{$$ = expr_create_integer_literal(atoi(yytext)); $$->kind = EXPR_VALUE;}
|
||||
| TOKEN_KEYWORD_OCCURS TOKEN_INTEGER
|
||||
{$$ = expr_create_integer_literal(atoi(yytext)); $$->kind = EXPR_OCCURS;}
|
||||
{$$ = expr_create_integer_literal(atoi(yytext)); $$->kind = EXPR_OCCURS;}
|
||||
|
|
||||
{$$ = expr_create(EXPR_NULL, NULL, NULL);}
|
||||
;
|
||||
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
|
||||
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) {
|
||||
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));
|
||||
|
||||
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.
|
||||
PROGRAM-ID. LOOPING.
|
||||
DATA DIVISION.
|
||||
WORKING-STORAGE SECTION.
|
||||
01 WS-I PIC 9(3) VALUE 1.
|
||||
|
||||
PROCEDURE DIVISION.
|
||||
PERFORM VARYING I FROM 1 BY 1 UNTIL I > 10
|
||||
DISPLAY I
|
||||
PERFORM VARYING WS-I FROM 1 BY 1 UNTIL WS-I > 10
|
||||
DISPLAY WS-I
|
||||
END-PERFORM
|
||||
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:
|
||||
---------------------
|
||||
Element +0001: 30
|
||||
Element +0002: 10
|
||||
Element +0003: 50
|
||||
Element +0004: 20
|
||||
Element +0005: 40
|
||||
|
||||
Element 1.000000: 30
|
||||
Element 2.000000: 10
|
||||
Element 3.000000: 50
|
||||
Element 4.000000: 20
|
||||
Element 5.000000: 40
|
||||
|
||||
Sorted Array Contents:
|
||||
--------------------
|
||||
Element +0001: 10
|
||||
Element +0002: 20
|
||||
Element +0003: 30
|
||||
Element +0004: 40
|
||||
Element +0005: 50
|
||||
Element 1.000000: 10
|
||||
Element 2.000000: 20
|
||||
Element 3.000000: 30
|
||||
Element 4.000000: 40
|
||||
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.
|
||||
01 WS-SORT-AREA.
|
||||
05 WS-SORT-TABLE.
|
||||
10 WS-SORT-ROW PIC X(10) OCCURS 100.
|
||||
05 WS-TEMP-ROW PIC X(10).
|
||||
10 WS-SORT-ROW PIC S9(4) OCCURS 100.
|
||||
05 WS-TEMP-ROW PIC S9(4).
|
||||
05 WS-ROW-MAX PIC S9(4) COMP VALUE 100.
|
||||
05 WS-SORT-MAX PIC S9(4) COMP.
|
||||
05 WS-I PIC S9(4) COMP.
|
||||
|
|
@ -14,11 +14,11 @@ WORKING-STORAGE SECTION.
|
|||
|
||||
PROCEDURE DIVISION.
|
||||
*> Initialize test data
|
||||
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 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
|
||||
|
||||
*> * Display original array
|
||||
|
|
@ -28,7 +28,7 @@ PROCEDURE DIVISION.
|
|||
UNTIL WS-INDEX > WS-SORT-MAX
|
||||
DISPLAY "Element " WS-INDEX ": " WS-SORT-ROW(WS-INDEX)
|
||||
END-PERFORM
|
||||
DISPLAY SPACE
|
||||
DISPLAY ""
|
||||
|
||||
*> * Simplified bubble sort
|
||||
PERFORM VARYING WS-I FROM 1 BY 1
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ UTEST(scanner, hello) {
|
|||
{TOKEN_KEYWORD_DIVISION, "DIVISION"},
|
||||
{TOKEN_DOT, "."},
|
||||
{TOKEN_DISPLAY, "DISPLAY"},
|
||||
{TOKEN_STRING, "Hello World!"},
|
||||
{TOKEN_STRING, "'Hello World!'"},
|
||||
{TOKEN_STOP, "STOP"},
|
||||
{TOKEN_RUN, "RUN"},
|
||||
{TOKEN_DOT, "."},
|
||||
|
|
|
|||
Loading…
Reference in New Issue