RPGLE Calculation Specs and Logic Blocks

RPGLE calculation specs are where traditional RPG programs expressed executable work: calculations, assignments, decisions, loops, calls, and certain input or output operations.
In older source, that work appears on position-dependent C-specification lines.
In modern fully free-form RPGLE, the same responsibilities appear as readable statements and expressions.

This is primarily a maintenance lesson about recognizing legacy code.
Do not use its fixed-format excerpt as a template for new development.
New RPGLE should generally use fully free-form syntax.

The previous lesson, RPGLE Input and Output Specifications Explained, separated record descriptions from the operations that move or change data.
This lesson follows that boundary into the executable logic itself.
It retains the canonical intermediate classification while explaining each idea in beginner-friendly terms for readers entering early-intermediate maintenance work.

Estimated reading time: 11 to 14 minutes

Quick Summary

  • A traditional calculation specification, commonly called a C-spec, describes an operation performed on program data.
  • The operation code is the verb: it tells you whether a line calculates, assigns, compares, branches, repeats, calls, or performs another action.
  • Fixed-format fields and column positions matter when reading legacy C-specs.
  • Modern fully free-form RPGLE expresses the same responsibilities with statements, expressions, built-in functions, and procedure calls.
  • A modernization is a behavior-preserving translation, not necessarily a one-line replacement.
  • Learn C-specs so you can maintain older applications; write new logic in fully free-form RPGLE.
Two input-to-logic-to-result lanes compare a traditional fixed-format C-spec used for legacy reading with fully free-form statements and expressions recommended for new RPGLE.
The representation changed, but input still passes through calculation and business logic to produce a result or action.

Both lanes perform the same broad job: input data enters a business rule, and a result or action comes out.
The representation changed; the logical responsibility remains.

Reader Prerequisites

You should already recognize the major sections of an RPGLE program.
RPGLE Program Structure Explained provides that foundation, and RPGLE Specifications: Fixed, Free, and Fully Free explains the source forms you may encounter.

You do not need to memorize fixed-format columns, indicator numbers, operation extenders, or the RPG program cycle.
The goal is to classify a calculation before looking up its exact rules.

Learning Outcomes

By the end of this lesson, you will be able to:

  • explain what traditional calculation specifications were responsible for;
  • recognize the broad shape of a fixed-format C-spec line;
  • find the operation code, operands, result, and surrounding logic block;
  • map common legacy responsibilities to modern fully free-form syntax;
  • follow IF, SELECT, DOW, DOU, and FOR blocks;
  • recognize older subroutine and call patterns without adopting them by default; and
  • use a safe workflow before changing legacy business logic.

What Calculation Specifications Were

IBM describes calculation specifications as the part of RPG that identifies operations performed on data.
Their order also defines the order in which those calculations run.2
In the traditional main source sequence, calculation specifications follow input specifications and precede output specifications.1

“Calculation” is broader than arithmetic.
A C-spec could:

  • multiply quantity by price;
  • assign or move a value;
  • compare two fields;
  • choose one branch of a business rule;
  • repeat a group of operations;
  • invoke a subroutine or call another program; or
  • request certain program-controlled file operations.

That is why this lesson uses the phrase calculation and business logic.
The C-specification area was the executable center of many traditional RPG programs, not merely a place for addition and subtraction.

The full history also includes detail calculations, total calculations, and cycle-related behavior.
Those topics are important in some legacy applications, but they are not required to understand the basic responsibility map here.

How to Recognize a Legacy Fixed-Format C-Spec

In traditional syntax, C identifies the calculation specification type.
The rest of the record is divided into position-dependent areas for conditions, factor 1, the operation code, factor 2 or an extended expression, the result field, and possible resulting indicators.3

Here is the small recognition excerpt used throughout this lesson:

      * Legacy fixed-format recognition excerpt only.
      * Preserve columns; do not use this as a new-code template.
     C     Quantity      MULT      UnitPrice     LineTotal
     C                   IF        LineTotal > 100
     C                   EVAL      HighValue = *ON
     C                   ENDIF

This excerpt is intentionally incomplete.
Its fields would be declared elsewhere, and the exact column placement must be preserved.
Read it in this order:

  1. Find the operation code: MULT, IF, EVAL, or ENDIF.
  2. Read the operands and result around that operation.
  3. Match the opening IF with its closing ENDIF.
  4. Check any conditioning or resulting-indicator positions last.

The first line multiplies Quantity by UnitPrice and places the product in LineTotal.
The block then sets HighValue on when the total is greater than 100.
For quantity 5 and unit price 25.00, the expected total is 125.00, so the condition is true.

The reusable excerpt is stored at content/code/rpgle/article-056/legacy-line-total-c-specs.rpgle.
It exists for recognition practice, not compilation or copying into new programs.

What Operation Codes Did

An operation code is the verb of a calculation line.
It tells you what kind of work to investigate before you become distracted by field names or indicators.

Operation familyLegacy examples you may seeResponsibility to identify
ArithmeticADD, SUB, MULT, DIVProduce a numeric result
Assignment and movementEVAL, MOVE, MOVELPut or reshape a value in a target
DecisionsIF, older IFxx forms, SELECT, WHENChoose which operations run
IterationDOW, DOU, FORRepeat a structured group
Reuse and callsEXSR, CALL, CALLPTransfer control to reusable logic
File workREAD, CHAIN, WRITE, and othersRequest program-controlled I/O

Some operation names, including IF, SELECT, DOW, DOU, and FOR, remain available in free-form calculations.
Other older operations have clearer modern forms.
IBM’s arithmetic map, for example, associates MULT with the * operator, while its movement guidance maps MOVE or MOVEL responsibilities toward evaluation or conversion facilities.5 6

Do not treat the table as an automatic converter.
An old operation may carry rounding, padding, truncation, extender, or indicator behavior that a simple replacement would lose.

Arithmetic and Assignment: From Result Fields to Expressions

The modern equivalent of the sample’s arithmetic responsibility is direct:

lineTotal = quantity * unitPrice;

The target appears on the left, and the expression appears on the right.
The complete rule is visible without aligning factor and result fields.

In a free-form calculation statement, EVAL can normally be omitted when no extender is required and the target name does not conflict with an operation code.4
That is why new code usually uses lineTotal = ...; instead of eval lineTotal = ...;.

The free-form equivalent of the complete small rule is:

lineTotal = quantity * unitPrice;

if lineTotal > 100;
  highValue = *on;
endif;

The repository version at content/code/rpgle/article-056/modern-line-total.rpgle supplies declarations and initialized values.
It produces lineTotal = 125.00 and highValue = *ON.

Simple arithmetic mappings are easy to recognize:

Legacy responsibilityModern expression direction
Addtotal = amountA + amountB;
Subtractbalance = balance - payment; or balance -= payment;
MultiplylineTotal = quantity * unitPrice;
Divideaverage = total / count; after handling a possible zero count

Movement operations need more care.
MOVE and MOVEL can involve alignment, padding, truncation, and type conversion.
Before replacing one, confirm the source and target types and read the operation’s IBM reference.
Modern assignment plus an explicit conversion or string operation is usually easier to understand, but it must preserve the intended behavior.

Comparisons and Conditional Logic

A comparison asks a true-or-false question such as lineTotal > 100.
A conditional block uses that answer to control which statements run.

IF and ELSE

Use IF when the rule has a primary path and perhaps an alternative:

if customerActive and balanceDue > 0;
  action = 'SEND';
else;
  action = 'HOLD';
endif;

The statements inside the first branch run only when the expression is true.
ELSE supplies the alternative, and ENDIF closes the block.7

This runtime IF is not the compile-time /IF directive introduced in RPGLE Control Specifications and Compiler Directives.
One chooses source during compilation; the other chooses work while the program runs.

SELECT, WHEN, and OTHER

Use SELECT when several mutually exclusive outcomes make one long IF chain difficult to scan:

select;
  when subtotal >= 400.00;
    discountRate = 0.1000;
  when subtotal >= 250.00;
    discountRate = 0.0500;
  other;
    discountRate = 0;
endsl;

RPG evaluates the alternatives in order and processes the first satisfied WHEN branch.
OTHER handles the case in which none of the earlier conditions is satisfied, and ENDSL closes the group.7

Older code may express comparisons through resulting indicators or conditional operation-code forms.
Resulting indicators belong to traditional C-spec syntax, not free-form calculation specifications; IBM notes that built-in functions can replace them in many cases.9
Do not remove an indicator until you can say in plain language what status it carries.
The planned next lesson, RPGLE Indicators and Status Flags, explores that maintenance problem directly.

Loops and Iteration

Loops repeat a group of statements.
The important first question is not “Which loop is best?” but “When is the condition tested, and what ends the repetition?”

DOW and DOU

DOW repeats while its condition is true and can run zero times.
DOU repeats until its condition becomes true and runs its group at least once.
Both close with ENDDO.7

dow itemsRemaining > 0;
  itemsRemaining -= 1;
enddo;
dou responseValid;
  responseValid = validateResponse();
enddo;

The second micro-example assumes a separately defined procedure named validateResponse.
It illustrates loop shape only.

FOR

FOR is a clear choice when a counter moves through a known range:

for lineIndex = 1 to %elem(lineAmounts);
  subtotal += lineAmounts(lineIndex);
endfor;

%ELEM supplies the number of elements in the array, so the loop limit stays aligned with its declared size.8
ENDFOR makes the block boundary explicit.

When reading any loop, locate the opener, closer, exit condition, changed variables, and side effects before editing it.

Subroutines, Calls, and Modern Modular Logic

Legacy programs often group calculations between BEGSR and ENDSR, then invoke that group with EXSR.
These operations remain recognizable in free-form syntax, so it would be inaccurate to say that fully free-form RPGLE forbids subroutines.10

For new modular logic, prefer a clearly named procedure with an explicit interface where parameters or a return value are needed.
A modern call can read like an ordinary statement or expression:

discountAmount = calculateDiscount(subtotal);

IBM recommends prototyped calls over older CALL/CALLB and PARM/PLIST patterns.
Prototypes allow the compiler to check the call interface, and the caller passes arguments on the call itself.11

Do not convert an EXSR mechanically.
First identify which fields the subroutine reads or changes, whether it depends on global state, where it can leave early, and how errors return to the caller.
Those observations become the candidate procedure’s parameters, return value, and error contract.

Map Legacy Responsibilities to Modern RPGLE

Use this table as a reading guide, not a promise of one-to-one conversion:

Traditional pattern to recognizeResponsibilityModern fully free-form direction
EVAL or a result-producing calculationAssign or calculatetarget = expression;
MOVE or MOVELTransfer or reshape dataExplicit assignment plus the verified conversion or string operation
ADD, SUB, MULT, or DIVArithmetic+, -, *, /, or a clear compound assignment
COMP and indicators, or older conditional operationsCompare and chooseBoolean expression in IF, ELSEIF, or SELECT
IF / ELSE / ENDIFConditional flowThe corresponding free-form structured block
SELECT / WHEN / OTHER / ENDSLMultiple alternativesThe corresponding free-form selection group
DOW / DOU / ENDDOConditional iterationA free-form loop with an explicit condition
Counted repetitionVisit a known rangeFOR / ENDFOR
Resulting indicatorsCarry a condition or operation statusA named boolean expression or relevant built-in function where documented
EXSR with BEGSR / ENDSRReuse an in-program groupA clearly named procedure when creating new modular logic
CALL with PARMCall another program with an older interfaceA prototyped call with arguments on the call

The safe sequence is responsibility first, syntax second, behavior verification last.

Build a Modern Pricing Logic Block

The larger teaching sample uses four in-memory line amounts.
It totals the array, chooses a discount, and calculates the final amount.
There is no database, file, indicator, or external-service dependency.

lineAmounts(1) = 50.00;
lineAmounts(2) = 75.00;
lineAmounts(3) = 125.00;
lineAmounts(4) = 150.00;

for lineIndex = 1 to %elem(lineAmounts);
  subtotal += lineAmounts(lineIndex);
endfor;

select;
  when subtotal >= 400.00;
    discountRate = 0.1000;
  when subtotal >= 250.00;
    discountRate = 0.0500;
  other;
    discountRate = 0;
endsl;

discountAmount = subtotal * discountRate;
finalTotal = subtotal - discountAmount;

Read the block in three passes:

  1. The FOR loop adds 50.00 + 75.00 + 125.00 + 150.00, producing subtotal = 400.00.
  2. The first WHEN is true, so discountRate = 0.1000.
  3. The calculation produces discountAmount = 40.00 and finalTotal = 360.00.

The complete sample is at content/code/rpgle/article-056/modern-order-pricing.rpgle.
Its descriptive names, initialized values, shallow nesting, and stated result make the business rule testable without unrelated infrastructure.

Common Beginner Mistakes

  • Calling all executable RPGLE “C-specs.” Modern fully free-form calculations are statements; reserve C-spec for the traditional calculation-specification context.
  • Ignoring fixed-format spacing. Columns carry meaning in a traditional C-spec, even when a rendered excerpt looks like loosely spaced text.
  • Reading field names before the verb. Start with the operation code, then interpret its operands and result.
  • Converting one line at a time. A line may depend on surrounding indicators, block boundaries, shared fields, extenders, or subroutines.
  • Treating DOW and DOU as interchangeable. They test different continuation conditions and have different minimum execution counts.
  • Confusing IF with /IF. IF controls runtime logic; /IF controls conditional compilation.
  • Replacing MOVE with = without checking behavior. Alignment, padding, truncation, and conversion can change the result.
  • Assuming indicators are meaningless noise. Give each one a plain-language meaning before deciding whether a boolean expression or built-in function should replace it.
  • Using EXSR for every new reusable rule. Procedures provide a clearer modular direction for new code.
  • Adding database logic to learn control flow. Isolate the business rule first; file access deserves its own lesson and tests.

A Practical Legacy-Maintenance Workflow

Use this process before changing calculation logic:

  1. Identify the source form. Look for fixed-format records, column-limited free-form blocks, **free, and included copy source.
  2. Locate the procedure. Separate declarations from the executable body and confirm whether you are in the main procedure, a subprocedure, or a subroutine.
  3. Classify each operation. Mark it as assignment, arithmetic, decision, loop, call, I/O, or another side effect.
  4. Match every block. Pair IF with ENDIF, SELECT with ENDSL, loop openers with their endings, and BEGSR with ENDSR.
  5. Translate conditions into words. “Indicator 42 is on” is less useful than “the customer record was found.” Confirm that meaning from every place the indicator is set and tested.
  6. Trace important fields. Find where a total, status, or key value is assigned, changed, and consumed.
  7. List side effects. Record calls, subroutines, file operations, messages, and state changes outside the apparent block.
  8. Check exact semantics. Use IBM’s operation reference for extenders, data types, rounding, truncation, errors, and status behavior.
  9. Preserve behavior with tests. Capture representative inputs and expected outputs before restructuring.

How to Read an RPGLE Program From Top to Bottom provides the broader reading pass that surrounds this calculation-focused workflow.

FAQ

What is a C-spec in RPGLE?

A C-spec is a traditional calculation specification.
It uses a position-dependent record to express an operation, its operands or expression, its result, and sometimes conditions or resulting indicators.

Are calculation specifications still used in modern RPGLE?

The calculation responsibility still exists, but new fully free-form RPGLE expresses it with statements and expressions rather than traditional fixed-format C-spec records.
Older and mixed-form applications can still contain C-specs, so maintainers need to recognize them.

How do I recognize a fixed-format calculation specification?

Look for C as the specification type and then locate the operation-code area.
Read the operation first, its factors or expression and result second, and its conditions or indicators last.
Preserve the columns while inspecting the source.

What replaced C-specs in fully free-form RPGLE?

There is no single replacement construct.
Assignments, expressions, structured operations, built-in functions, procedure calls, and I/O statements collectively express the responsibilities that appeared in traditional calculation specifications.

Is EVAL required for assignment in free-form RPGLE?

Usually not.
You can normally write target = expression; when no EVAL extender is needed and the target name does not conflict with a supported operation-code name.4

What is the difference between DOW and DOU?

DOW repeats while its condition is true and may run zero times.
DOU repeats until its condition becomes true and processes its group at least once.7

Should new RPGLE use EXSR subroutines or procedures?

Learn EXSR, BEGSR, and ENDSR so you can maintain existing code.
For new modular logic, prefer clearly named procedures and prototyped calls because their inputs, outputs, and compiler-checked interfaces can be made explicit.11

Key Takeaways

  • Traditional C-specs expressed the executable calculations and business logic of RPG programs.
  • Their fixed fields help you recognize operations, operands, results, conditions, and indicators in legacy source.
  • Operation codes are verbs; classify the responsibility before studying syntax details.
  • Modern fully free-form RPGLE keeps the same responsibilities but expresses them through readable statements, expressions, built-in functions, and calls.
  • Arithmetic and structured logic often map cleanly, while movement, indicator, call, and subroutine patterns require behavioral analysis.
  • C-specs are primarily legacy-reading knowledge. New RPGLE should generally use fully free-form syntax.
  • A safe modernization identifies intent, maps syntax, and verifies preserved behavior.

Continue Your Learning

  1. Previous: RPGLE Input and Output Specifications Explained
  2. Current: RPGLE Calculation Specs and Logic Blocks
  3. Next: RPGLE Indicators and Status Flags (ARTICLE-057, planned in the canonical RPGLE cluster)
  4. Later: RPGLE Source Layout and Readability (ARTICLE-058, planned)
  5. Return to: RPGLE for Beginners: A Practical IBM i Learning Path
Five-step roadmap from recognizing a legacy C-spec and identifying its responsibility through mapping intent, writing fully free-form RPGLE, and verifying preserved behavior.
Legacy-reading knowledge should lead to clear modern syntax and behavior verification.

The next lesson examines indicators and status flags because legacy calculation lines often use them to carry conditions between operations.
That lesson keeps indicators visible for maintenance without making them the center of new RPGLE design.

IBM Evidence Used

This lesson uses IBM’s ILE RPG documentation as its technical evidence:

  • IBM’s specification references define the purpose, order, and traditional layout of calculation specifications.1 2 3
  • IBM’s free-form and operation references support the assignment, arithmetic, movement, structured-flow, and array mappings used in the examples.4 5 6 7 8
  • IBM’s indicator, subroutine, and call references support the legacy-maintenance cautions and modern modular direction.9 10 11

  1. IBM, “RPG IV Specification Types,” IBM i 7.4 documentation. ↩↩

  2. IBM, “Calculation Specifications,” IBM i 7.4 documentation. ↩↩

  3. IBM, “Traditional Syntax,” IBM i 7.4 documentation. ↩↩

  4. IBM, “Free-Form Statements,” IBM i 7.4 documentation. ↩↩↩

  5. IBM, “Arithmetic Operations,” IBM i 7.4 documentation. ↩↩

  6. IBM, “Move Operations,” IBM i 7.4 documentation. ↩↩

  7. IBM, “Structured Programming Operations,” IBM i 7.4 documentation. ↩↩↩↩↩

  8. IBM, “Array Operations,” IBM i 7.4 documentation. ↩↩

  9. IBM, “Resulting Indicators,” IBM i 7.4 documentation. ↩↩

  10. IBM, “Subroutine Operations,” IBM i 7.5 documentation. ↩↩

  11. IBM, “Call Operations,” IBM i 7.5 documentation. ↩↩↩

References

  1. Calculation Specifications — IBM
  2. RPG IV Specification Types — IBM
  3. Traditional Syntax — IBM
  4. Arithmetic Operations — IBM
  5. Move Operations — IBM
  6. Free-Form Statements — IBM
  7. Structured Programming Operations — IBM
  8. Resulting Indicators — IBM
  9. Array Operations — IBM
  10. Subroutine Operations — IBM
  11. Call Operations — IBM



Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top