Lably
Skip to content

Line number

Identifier of a sequence of characters in a text file

  • 10 min read
  • 4 chapters

Related on Lably

Through Computing, Text file and BASIC

In the C programming language the line number of a source code line is one greater than the number of new-line characters read or introduced up to that point.

Programmers could also assign line numbers to statements in older programming languages, such as Fortran, JOSS, and BASIC. In Fortran, not every statement needed a line number, and line numbers did not have to be in sequential order. The purpose of line numbers was for branching and for reference by formatting statements.

Both JOSS and BASIC made line numbers a required element of syntax. The primary reason for this is that most operating systems at the time lacked interactive text editors; since the programmer's interface was usually limited to a line editor, line numbers provided a mechanism by which specific lines in the source code could be referenced for editing, and by which the programmer could insert a new line at a specific point. Line numbers also provided a convenient means of distinguishing between code to be entered into the program and direct mode commands to be executed immediately when entered by the user (which do not have line numbers).

Largely due to the prevalence of interactive text editing in modern operating systems, line numbers are not a feature of most programming languages, even modern Fortran and Basic.

History

FORTRAN

In Fortran, as first specified in 1956, line numbers were used to define input/output patterns, to specify statements to be repeated, and for conditional branching. For example:

<span id="mwLg"></span><span class="w" id="mwLw"> </span><span class="k" id="mwMA">DIMENSION </span><span class="n" id="mwMQ">ALPHA</span><span class="p" id="mwMg">(</span><span class="mi" id="mwMw">25</span><span class="p" id="mwNA">),</span><span class="w" id="mwNQ"> </span><span class="n" id="mwNg">RHO</span><span class="p" id="mwNw">(</span><span class="mi" id="mwOA">25</span><span class="p" id="mwOQ">)</span> <span class="mi" id="mwOg">1</span><span class="p" id="mwOw">)</span><span class="w" id="mwPA"> </span><span class="k" id="mwPQ">FORMAT</span><span class="p" id="mwPg">(</span><span class="mi" id="mwPw">5</span><span class="n" id="mwQA">F12</span><span class="p" id="mwQQ">.</span><span class="mi" id="mwQg">4</span><span class="p" id="mwQw">)</span> <span class="mi" id="mwRA">2</span><span class="p" id="mwRQ">)</span><span class="w" id="mwRg"> </span><span class="k" id="mwRw">READ </span><span class="mi" id="mwSA">1</span><span class="p" id="mwSQ">,</span><span class="w" id="mwSg"> </span><span class="n" id="mwSw">ALPHA</span><span class="p" id="mwTA">,</span><span class="w" id="mwTQ"> </span><span class="n" id="mwTg">RHO</span><span class="p" id="mwTw">,</span><span class="w" id="mwUA"> </span><span class="n" id="mwUQ">ARG</span> <span class="w" id="mwUg"> </span><span class="nb" id="mwUw">SUM</span><span class="w" id="mwVA"> </span><span class="o" id="mwVQ">=</span><span class="w" id="mwVg"> </span><span class="mf" id="mwVw">0.0</span> <span class="w" id="mwWA"> </span><span class="k" id="mwWQ">DO </span><span class="mi" id="mwWg">3</span><span class="w" id="mwWw"> </span><span class="n" id="mwXA">I</span><span class="o" id="mwXQ">=</span><span class="mi" id="mwXg">1</span><span class="p" id="mwXw">,</span><span class="w" id="mwYA"> </span><span class="mi" id="mwYQ">25</span> <span class="w" id="mwYg"> </span><span class="k" id="mwYw">IF</span><span class="w" id="mwZA"> </span><span class="p" id="mwZQ">(</span><span class="n" id="mwZg">ARG</span><span class="o" id="mwZw">-</span><span class="n" id="mwaA">ALPHA</span><span class="p" id="mwaQ">(</span><span class="n" id="mwag">I</span><span class="p" id="mwaw">))</span><span class="w" id="mwbA"> </span><span class="mi" id="mwbQ">4</span><span class="p" id="mwbg">,</span><span class="mi" id="mwbw">3</span><span class="p" id="mwcA">,</span><span class="mi" id="mwcQ">3</span> <span class="mi" id="mwcg">3</span><span class="p" id="mwcw">)</span><span class="w" id="mwdA"> </span><span class="nb" id="mwdQ">SUM</span><span class="w" id="mwdg"> </span><span class="o" id="mwdw">=</span><span class="w" id="mweA"> </span><span class="nb" id="mweQ">SUM</span><span class="w" id="mweg"> </span><span class="o" id="mwew">+</span><span class="w" id="mwfA"> </span><span class="n" id="mwfQ">ALPHA</span><span class="p" id="mwfg">(</span><span class="n" id="mwfw">I</span><span class="p" id="mwgA">)</span> <span class="mi" id="mwgQ">4</span><span class="p" id="mwgg">)</span><span class="w" id="mwgw"> </span><span class="k" id="mwhA">VALUE</span><span class="w" id="mwhQ"> </span><span class="o" id="mwhg">=</span><span class="w" id="mwhw"> </span><span class="mf" id="mwiA">3.14159</span><span class="o" id="mwiQ">*</span><span class="n" id="mwig">RHO</span><span class="p" id="mwiw">(</span><span class="n" id="mwjA">I</span><span class="o" id="mwjQ">-</span><span class="mi" id="mwjg">1</span><span class="p" id="mwjw">)</span> <span class="w" id="mwkA"> </span><span class="k" id="mwkQ">PRINT </span><span class="mi" id="mwkg">1</span><span class="p" id="mwkw">,</span><span class="w" id="mwlA"> </span><span class="n" id="mwlQ">ARG</span><span class="p" id="mwlg">,</span><span class="w" id="mwlw"> </span><span class="nb" id="mwmA">SUM</span><span class="p" id="mwmQ">,</span><span class="w" id="mwmg"> </span><span class="k" id="mwmw">VALUE</span> <span class="k" id="mwnA"> GO</span><span class="w" id="mwnQ"> </span><span class="k" id="mwng">TO</span><span class="w" id="mwnw"> </span><span class="mi" id="mwoA">2</span>

Like assembler language before it, Fortran did not assume every line needed a label (line number, in this case). Only statements referenced elsewhere required a line number:

  • Line 1 specifies a format pattern for input; the READ command in line 2 and the later PRINT command both reference this line.
  • The DO loop executes line 3.
  • The arithmetic IF statement branches to line 4 on a negative value, line 3 on zero, and again line 3 on a positive value.

While the line numbers are sequential in this example, in the very first "complete but simple [Fortran] program" published the line numbers are in the sequence 1, 5, 30, 10, 20, 2.

Line numbers could also be assigned to fixed-point variables (e.g., ASSIGN i TO n) for referencing in subsequent assigned GO TO statements (e.g., GO TO n,(n1,n2,...nm)).

COBOL

In COBOL, line numbers were specified in the first six characters (the sequence number area) of punched cards. This was originally used for facilitating mechanical card sorting to assure intended program code sequence after manual handling. The line numbers were actually ignored by the compiler.

DOPE

In 1962, DOPE (Dartmouth Oversimplified Programming Experiment) became one of the first programming languages to require a line number for every statement and to use sequential ordering of line numbers. Line numbers were specified as destinations for two commands, C (Compare operation, an arithmetic IF) and T (To operation, a GO TO).

JOSS

In 1963, JOSS independently made line numbers mandatory for every statement in a program and ordered lines in sequential order. JOSS introduced the idea of a single command line editor that worked both as an interactive language and a program editor. Commands that were typed without a line number were executed immediately, in what JOSS referred to as "direct mode". If the same line was prefixed with a line number, it was instead copied into the program code storage area, which JOSS called "indirect mode".

Unlike FORTRAN before it or BASIC after it, JOSS required line numbers to be fixed-point numbers consisting of a pair of two-digit integers separated by a period (e.g., 1.1). The portion of the line number to the left of the period is known as the "page" or "part", while the portion to the right is known as the "line"; for example, the line number 10.12 refers to page 10, line 12. Branches can target either a page or a line within a page. When the later format is used, the combined page and line is known as a "step".

Pages are used to define subroutines, which return when the next line is on a different page. For instance, if a subroutine for calculating the square root of a number is in page 3, one might have three lines of code 3.1, 3.2 and 3.3, and it would be called using Do part 3. The code would return to the statement after the Do when it reaches the next line on a different page, for instance, 4.1. There is no need for the equivalent of a RETURN at the end, although if an early return is required, Done accomplishes this. Example:

*Routine to ask the user for a positive value and repeat until it gets one 01.10 Demand X as "Enter a positive value greater than zero". 01.20 Done if X>0. 01.30 To step 1.1

BASIC

Introduced in 1964, Dartmouth BASIC adopted mandatory line numbers, as in JOSS, but made them integers, as in FORTRAN. As defined initially, BASIC only used line numbers for GOTO and GOSUB (go to subroutine, then return). Some Tiny BASIC implementations supported numeric expressions instead of constants, while switch statements were present in different dialects (ON GOTO; ON GOSUB; ON ERROR GOTO).

Line numbers were rarely used elsewhere. One exception was allowing the pointer used by READ (which iterated through DATA statements) to be set to a specific line number using RESTORE.

<span id="mw7Q"></span><span class="w" id="mw7g"> </span><span class="mi" id="mw7w">1</span><span class="w" id="mw8A"> </span><span class="kd" id="mw8Q">REM</span><span class="c1" id="mw8g"> RESTORE COULD BE USED IF A BASIC LACKED STRING ARRAYS</span> <span class="w" id="mw8w"> </span><span class="mi" id="mw9A">2</span><span class="w" id="mw9Q"> </span><span class="k" id="mw9g">DIM</span><span class="w" id="mw9w"> </span><span class="nv" id="mw-A">M$</span><span class="o" id="mw-Q">(</span><span class="mi" id="mw-g">9</span><span class="o" id="mw-w">)</span><span class="cp" id="mw_A">:</span><span class="w" id="mw_Q"> </span><span class="kd" id="mw_g">REM</span><span class="c1" id="mw_w"> DEFINE LENGTH OF 9 CHARACTERS</span> <span class="w" id="mwAQA"> </span><span class="mi" id="mwAQE">5</span><span class="w" id="mwAQI"> </span><span class="k" id="mwAQM">INPUT</span><span class="w" id="mwAQQ"> </span><span class="s2" id="mwAQU">"MONTH #?"</span><span class="o" id="mwAQY">;</span><span class="w" id="mwAQc"> </span><span class="nv" id="mwAQg">M</span><span class="cp" id="mwAQk">:</span><span class="w" id="mwAQo"> </span><span class="k" id="mwAQs">IF</span><span class="w" id="mwAQw"> </span><span class="nv" id="mwAQ0">M</span><span class="o" id="mwAQ4"><</span><span class="mi" id="mwAQ8">1</span><span class="w" id="mwARA"> </span><span class="k" id="mwARE">OR</span><span class="w" id="mwARI"> </span><span class="nv" id="mwARM">M</span><span class="o" id="mwARQ">></span><span class="mi" id="mwARU">12</span><span class="w" id="mwARY"> </span><span class="k" id="mwARc">THEN</span><span class="w" id="mwARg"> </span><span class="nl" id="mwARk">5</span> <span class="w" id="mwARo"> </span><span class="mi" id="mwARs">7</span><span class="w" id="mwARw"> </span><span class="k" id="mwAR0">RESTORE</span><span class="w" id="mwAR4"> </span><span class="nl" id="mwAR8">10</span><span class="o" id="mwASA">*</span><span class="nv" id="mwASE">M</span><span class="cp" id="mwASI">:</span><span class="w" id="mwASM"> </span><span class="k" id="mwASQ">READ</span><span class="w" id="mwASU"> </span><span class="nv" id="mwASY">M$</span><span class="cp" id="mwASc">:</span><span class="w" id="mwASg"> </span><span class="k" id="mwASk">PRINT</span><span class="w" id="mwASo"> </span><span class="nv" id="mwASs">M$</span> <span class="w" id="mwASw"> </span><span class="mi" id="mwAS0">10</span><span class="w" id="mwAS4"> </span><span class="k" id="mwAS8">DATA</span><span class="w" id="mwATA"> </span><span class="s2" id="mwATE">"JANUARY"</span> <span class="w" id="mwATI"> </span><span class="mi" id="mwATM">20</span><span class="w" id="mwATQ"> </span><span class="k" id="mwATU">DATA</span><span class="w" id="mwATY"> </span><span class="s2" id="mwATc">"FEBRUARY"</span> <span class="w" id="mwATg"> </span><span class="mi" id="mwATk">30</span><span class="w" id="mwATo"> </span><span class="k" id="mwATs">DATA</span><span class="w" id="mwATw"> </span><span class="s2" id="mwAT0">"MARCH"</span> <span class="w" id="mwAT4"> </span><span class="err" id="mwAT8">...</span>

In the first editions of Dartmouth BASIC, THEN could only be followed by a line number (for an implied GOTO), not - as in later implementations - by a statement.

The range of valid line numbers varied widely from implementation to implementation, depending on the representation used to store the binary equivalent of the line number (one or two bytes; signed or unsigned). While Dartmouth BASIC supported 1 to 99999, the typical microcomputer implementation supported 1 to 32767 (a signed 16-bit word).

Sign in to keep reading

3 more chapters are free with a Lably account.

More in From Lably lessons