In this chapter you will learn
Before we get know “expressions”, let’s define “statements” more precisely, shall we:Astatement tells the computer tochange something.All statements in some way or otherchange the program state.Program state refers to a whole conglomerate of individual states, including but not limited to:
The last metric is stored in an invisible variable, theprogram counter.ThePCalways points to the currently processed statement.Imagine pointing with your finger to one source code line (or, more precisely, statement): “Here we are!”After a statement has successfully been executed, thePC advances to the effect that it points to the next statement.[fn 1]ThePC cannot be altered directly, but onlyimplicitly.In this chapter we will learn how.
Statements can be categorized into two groups:Elementary and complex statements.Elementary statements are the minimal building blocks of high-level programming languages.In Pascal they are:[fn 2][fn 3]
:=), andreadLn(x) andwriteLn('Hi!')).“Complex” statements are:
begin andend),Unlike many other programming languages, in Pascal the semicolon;separates two statements.Lots of programming languages use some symbol toterminate a statement, e. g. the semicolon.Pascal, however, recognized that an extra symbol should not bepart of a statement in order to make it an actual statement.ThehelloWorld program from the second chapter could be written without a semicolon after thewriteLn(…), because there is no following statement:
programhelloWorld(output);beginwriteLn('Hello world!')end.
We, however, recommend you to put a semicolon there anyway, even though it is not required.Later in this chapter you will learn one place you most probably (that means not necessarily always) do not want to put a semicolon.
Although a semicolon does not terminate astatement, the program header, constant definitions, variable declarations and some other language constructsare terminated by this symbol.You cannot omit a semicolon at these locations.
Expressions, in contrast to statements, do not change the program state.They aretransient values that can be used aspart of statements.Examples of expressions are:
42,'D’oh!', orx (wherex is the name of a previously declared variable).Every expression has a type:When an expression is evaluated it results in a value of a certain data type.The expression42 has the data typeinteger,'D’oh!' is a “string type” and the expression merely consisting of a variable’s name, such as x, evaluates to the data type of that variable.Because the data type of an expression is so important, expressions are named after their type.The expressiontrue is aBoolean expression, as isfalse.
Expressions appear at many places:
:=) you write an expression on theRHS. This expression has to have the data type of the variable on theLHS.[fn 5] An assignment makes thetransient value of an expression “permanent” by storing it into the variable’s memory block.writeLn(output, 'Hi!') can be understood asoutput'Hi!'writeLn with the invisible “variables”destination and “first parameter”The power of expressions lies in their capability to link withother expressions.This is done by using special symbols calledoperators.In theprevious chapter we already saw one operator, the equals operator =.Now we can break up such an expression:
response = 'y' {│ └──────┰─────┘ ┃ └──────┰──────┘ ││ sub-expression operator sub-expression ││ │└─────────────────────┰─────────────────────┘ expression }
As you can you can see in the diagram, an expression can be part of a larger expression.The sub-expressions are linked using the operator symbol =.Sub-expressions that are linked via, or associated with an operator symbol are also calledoperands.
Linking expressions via an operand “creates” anew expression which has a data type on its own.Whileresponse and'y' in the example above were bothchar-expressions, the overall data type of the whole expression isBoolean, because the linking operator is the equal comparison.An equal comparison yields aBoolean expression.Here is a table of relational operators which we can already use with our knowledge:
| name | source code symbol |
|---|---|
| =, equals | = |
| ≠, unequal | <> |
| <, less than | < |
| >, greater than | > |
| ≤, less than or equal to | <= |
| ≥, greater than or equal to | >= |
Using these symbols yield Boolean expressions.The value of the expression will be eithertrue orfalse depending on the operator’s definition.
All those relational operators require operands on both sides to be of thesame data type.[fn 6]Although wecan say'$' = 1337 is wrong, that means it should evaluate to the valuefalse, it is nevertheless illegal, because'$' is achar‑expression and1337 is aninteger‑expression.Pascal forbids you to compare things/objects that differ in their data type.(Note, a few conversion routines will allow you to dosome comparisons that are not alloweddirectly, but by taking a detour. In the next chapter we will see some of them.)
Expressions are also used for calculations, the machine you are using is not called “computer” for no reason.In Standard Pascal you can add, subtract, multiply and divide two numbers, i. e.integer‑ andreal‑expressions and any combination thereof.The symbols that work for all combinations are:
| name | source code symbol |
|---|---|
| +, plus | + |
| −, minus | - |
| ×, times | * |
The division operation has been omitted as it is tricky, and will be explained in a following chapter.
If at least one of the operands is areal‑expression, the entire expression is of typereal, even if the exact value could be represented by aninteger. |
Note, unlike in mathematics, there isno invisible times assumed between two “operands”:You always need to write the “times”, meaning the asterisk *explicitly.
The operator symbols+ and- can also appear withone number expression only.It then indicates the positive or negative sign, or – more formally – sign identity or sign inversion respectively.
Just like in mathematics, operators have a certain “force” associated with them, inCS we call thisoperator precedence.You may recall from your primary or secondary education, school or homeschooling, the acronym PEMDAS:It is a mnemonic standing for the initial letters of
giving us the correct order to evaluate an arithmetic expression in mathematics.Luckily, Pascal’s operator precedence is just the same, although – to be fair – technically not defined by the word “PEMDAS”.[fn 7]
As you might have guessed it, operator precedence can be overridden on a per-expression basis by using parentheses:In order to evaluate5 * (x + 7), the sub-expressionx + 7 is evaluated first and that value is then multiplied by5, even though multiplication is generally evaluated prior sums or differences.
Branches are complex statements.Up to this point all programs we wrote were linear:They started at the top and the computer (ideally) executed them line-by-line until the finalend..Branches allow you to choose alternative paths, like at a T‑bone intersection: “Do I turn left or do I turn right?”The general tendency to process the program “downward” remains, but there is (in principle) a choice.
Let’s review the programiceCream from the previous chapter.The conditional statement is highlighted:
programiceCream(input,output);varresponse:char;beginwriteLn('Do you like ice cream?');writeLn('Type “y” for “yes” (“Yummy!”) and “n” for “no”.');writeLn('Confirm your selection by hitting Enter.');readLn(input,response);ifresponse='y'thenbeginwriteLn('Awesome!');end;end.
Now we can say thatresponse = 'y' is a Boolean expression.The wordsif andthen are part of the language construct we callconditional statement.Afterthen comes a statement, in this case a complex statement:begin … end is asequence and considered to beone statement.
If you remember or can infer from the source code, the statements betweenbegin … end, thewriteLn('Awesome!') is only executed if the expressionresponse = 'y' evaluated totrue.Otherwise, this is skipped as if there was nothing.
Due to this binary nature – yes / no, execute the code or skip it – the expression betweenif andthenhas to be a Boolean expression.You cannot writeif 1 * 1 then …, since1 * 1 is aninteger-expression.The computer cannot decide based on aninteger-expression, whether it shall take a route or not.
Let’s expand the programiceCream by giving an alternative response if the user says not to like ice cream.We could do this with anotherif‑statement, yet there is a smarter solution for this frequently occurring situation:
ifresponse='y'thenbeginwriteLn('Awesome!');endelsebeginwriteLn('That’s a pity!');end;
The highlighted alternative, theelse‑branch, will only be executed if the supplied Boolean expression evaluated tofalse.In either case, regardless whether thethen‑branch or theelse‑branch was taken, program execution resumes after theelse‑statement (in this after theend; in the last line).
Branches and (soon explained) loops are theonly method of modifying thePC, “your finger” pointing to the currently executed statement, based on data, an expression, and thus a means of responding to user input.Without them, your programs would be static and do the same over and over again, so pretty boring.Utilizing branches and loops will make your program way more responsive to the given input.
char-expressions? All? None?'0' through'9','A' through'Z', and'a' through'z' are sorted as you are familiar from the English alphabet, or – with respect to the digits – their numeral value in ascending order.Because of that you are allowed to make a comparison such as'A' <= 'F' (which will evaluate totrue).'0' through'9','A' through'Z', and'a' through'z' are sorted as you are familiar from the English alphabet, or – with respect to the digits – their numeral value in ascending order.Because of that you are allowed to make a comparison such as'A' <= 'F' (which will evaluate totrue).Notes:
%eip, extended instruction pointer) and points to thefollowing instruction (not current statement). SeeSubject: Assembly languages for more details.goto) have been deliberately banned into theappendix, and are not covered here, yetgoto is also an elementary statement.raise as an elementary statement.procedure calls.integer expression can be stored into a variable of the data typereal, but not the other way round. As we progress we will learn more about “compatible” types.