{$mode objfpc}{$h+}
program TRonScopes;
procedure a(ParameterA : integer); // -> scope a
{ ^ the procedure block and its corresponding scope start at the }
{ open parenthesis. This is important for 2 reasons: 1. it causes }
{ ParameterA NOT to be available outside of procedure "a" and 2. }
{ it causes the parameter to be in the same scope as all other }
{ definitions contained in the procedure block. }
{ ParameterA, "c", "k", "b" and "v" are all in the same scope which is what }
{ allows procedure "a" to use them without qualifier. }
var
c: integer = 1;
const
k = 100;
{ ------------------------------------------------------------------------- }
{ nested procedures }
procedure b(ParameterB : integer); // -> scope b
{ ^ start of procedure block and scope (nested in scope of "a") }
var
d: integer = k; { "k" from the outer scope is visible }
c: integer = 2;
{ ^ "c" become visible after the ";", not before }
{ note that "x" and "z" below are not visible yet even though they are in }
{ the same scope (defined by "b"'s procedure block) }
const
x = 3; { x is visible after the ";" but not before }
z = x; { this is ok because "x" is visible }
{ the definition below is erroneous and the compiler knows that because }
{ "y" has not been fully defined by the time it is used. }
// y = y; { uncomment to see the error "identifier not found" }
begin { scopes "a" and "b" are visible }
d := d; // gets rid of "not used" hint
writeln('scope b: ', ParameterA); // ParameterA = 7
writeln('scope b: ', ParameterB); // ParameterB = 3 and 33
writeln('scope b: ', c); // c = 2
end; { end of scope b }
{ "v" is in the same scope as the other identifiers defined in procedure "a"}
{ but, because of _where_ it is defined, it is not visible to procedure "b" }
{ IOW, scope <> visibility }
var
v : integer = 2; { procedure "b" cannot see (thus not use) this variable }
{ end of nested procedures }
{ ------------------------------------------------------------------------- }
begin { scope "a" is visible ("b" is not) }
writeln('scope a: ', c); // c = 1
b(3);
writeln('scope a: ', c); // c = 1
b(33);
{ procedure "b" is in the scope of procedure "a" BUT the ParameterB is NOT }
{ uncomment the following to see "identifier not found" which proves that }
{ the parameter is in a different scope than the procedure name. }
// ParameterB := 1;
end; // <- scope a
begin // -> scope main/TRonScopes
a(7);
readln;
end. // <- scope main/TRonScopes