Browse Source

+ Added variable declaration

michael 21 years ago
parent
commit
f620ca6ea8
3 changed files with 240 additions and 0 deletions
  1. 157 0
      docs/ref.tex
  2. 52 0
      docs/syntax/propvar.syn
  3. 31 0
      docs/syntax/vardecl.syn

+ 157 - 0
docs/ref.tex

@@ -1849,6 +1849,163 @@ is executed by inserting the necessary code to query the dispatch interface
 stored in the variant \var{W}, and execute the call if the needed dispatch
 information is found.
 
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Variables
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+\chapter{Variables}
+\label{ch:Variables}
+\section{Definition}
+Variables are explicitly named memory locations with a certain type. When
+assigning values to variables, the \fpc compiler generates machine code 
+to move the value to the memory location reserved for this variable. Where
+this variable is stored depends on where it is declared:
+
+\begin{itemize}
+\item Global variables are variables declared in a unit or program, but not
+inside a procedure or function. They are stored in fixed memory locations,
+and are available during the whole execution time of the program.
+\item Local variables are declared inside a procedure or function. Their
+value is stored on the program stack, i.e. not at fixed locations.
+\end{itemize}
+
+The \fpc compiler handles the allocation of these memory locations
+transparantly, although this location can be influenced in the declaration.
+
+The \fpc compiler also handles reading values from or writing values to
+the variables transparantly. But even this can be explicitly handled by the
+programmer when using properties.
+
+Variables must be explicitly declared when they are needed. No memory is
+allocated unless a variable is declared. Using an variable identifier (for
+instance, a loop variable) which is not declared first, is an error which
+will be reported by the compiler. 
+
+\section{Declaration}
+The variables must be declared in a variable declaration section of a unit
+or a procedure or function. It looks as follows:
+\input{syntax/vardecl.syn}
+
+This means that the following are valid variable declarations:
+\begin{verbatim}
+Var
+  curterm1 : integer;
+
+  curterm2 : integer; cvar;
+  curterm3 : integer; cvar; external;
+
+  curterm4 : integer; external name 'curterm3';
+  curterm5 : integer; external 'libc' name 'curterm9';
+
+  curterm6 : integer absolute curterm1;
+
+  curterm7 : integer; cvar;  export;
+  curterm8 : integer; cvar;  public;
+  curterm9 : integer; export name 'me';
+  curterm10 : integer; public name 'ma';
+
+  curterm11 : integer = 1 ;
+\end{verbatim}
+
+The difference between these declarations is as follows:
+\begin{enumerate}
+\item The first form (\var{curterm1}) defines a regular variable. The
+compiler manages everything by itself.
+\item The second form (\var{curterm2}) declares also a regular variable, 
+but specifies that the assembler name for this variable equals the name 
+of the variable as written in the source.
+\item The third form (\var{curterm3}) declares a variable which is located
+externally: the compiler will assume memory is located elsewhere, and that
+the assembler name of this location is specified by the name of the
+variable, as written in the source. The name may not be specified.
+\item The fourth form is completely equivalent to the third, it declares a
+variable which is stored externally, and explicitly gives the assembler
+name of the location. If \var{cvar} is not used, the name must be specified.
+\item The fifth form is a variant of the fourth form, only the name of the
+library in which the memory is reserved is specified as well.
+\item The sixth form declares a variable (\var{curterm6}), and tells the compiler that it is
+stored in the same location as another variable (\var{curterm1})
+\item The seventh form declares a variable (\var{curterm7}), and tells the
+compiler that the assembler label of this variable should be the name of the
+variable (case sensitive) and must be made public. (i.e. it can be
+referenced from other object files)
+\item The eight form (\var{curterm8}) is equivalent to the seventh: 'public'
+is an alias for 'export'.
+\item The ninth and tenth form are equivalent: they specify the assembler 
+name of the variable.
+\item the elevents form declares a variable (\var{curterm11}) and
+initializes it with a value (1 in the above case).
+\end{enumerate}
+Note that assembler names must be unique. It's not possible to declare or 
+export 2 variables with the same assembler name.
+
+\section{Scope}
+Variables, just as any identifier, obey the general rules of scope. 
+In addition, initialized variables are initialized when they enter scope:
+\begin{itemize}
+\item Global initialized variables are initialized once, when the program starts.
+\item Local initialized variables are initialized each time the procedure is
+entered.
+\end{itemize}
+Note that the behaviour for local initialized variables is different from
+the one of a local typed constant. A local typed constant behaves like a
+global initialized variable.
+
+\section{Properties}
+A global block can declare properties, just as they could be defined in a
+class. The difference is that the global property does not need a class
+instance: there is only 1 instance of this property. Other than that, a
+global property behaves like a class property. The read/write specifiers for
+the global property must also be regular procedures, not methods.
+The concept of a global property is specific to \fpc, and does not exist in
+Delphi.
+
+The concept of a global property can be used to 'hide' the location of the
+value, or to calculate the value on the fly, or to check the values which
+are written to the property.
+
+The declaration is as follows:
+\input{syntax/propvar.syn}
+
+The following is an example:
+\begin{verbatim}
+{$mode objfpc}
+unit testprop;
+
+Interface
+
+Function GetMyInt : Integer;
+Procedure SetMyInt(Value : Integer);
+
+Property
+  MyProp : Integer Read GetMyInt Write SetMyInt;
+  
+Implementation
+
+Uses sysutils;
+
+Var
+  FMyInt : Integer;  
+  
+Function GetMyInt : Integer;
+
+begin
+  Result:=FMyInt;
+end;
+
+Procedure SetMyInt(Value : Integer);
+
+begin
+  If ((Value mod 2)=1) then
+    Raise Exception.Create('MyProp can only contain even value');
+  FMyInt:=Value;  
+end;
+
+end.
+\end{verbatim}
+
+The read/write specifiers can be hidden by declaring them in another unit
+(which must be in the \var{uses} clause of the unit).
+
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % Objects
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%

+ 52 - 0
docs/syntax/propvar.syn

@@ -0,0 +1,52 @@
+\begin{diagram}{Properties}{properties}
+\begin{mysyntdiag}
+\synt{property\ definition}
+\synt{identifier} \begin{stack}\\ \synt{property\ interface} \end{stack}
+\synt{property\ specifiers}
+\end{mysyntdiag}
+\begin{mysyntdiag}
+\synt{property\ interface}
+\begin{stack}\\ \synt{property\ parameter\ list}\end{stack} \lit*: \synt{type\ identifier}
+\begin{stack}\\
+\lit*{index} \synt{integer constant}
+\end{stack}
+\end{mysyntdiag}
+\begin{mysyntdiag}
+\synt{property\ parameter\ list} \lit*[
+\begin{rep}[b] \synt{parameter\ declaration} \\ \lit; \end{rep} 
+\lit*]
+\end{mysyntdiag}
+\begin{mysyntdiag}
+\synt{property\ specifiers}
+\begin{stack}\\ \synt{read\ specifier} \end{stack}
+\begin{stack}\\ \synt{write\ specifier} \end{stack}
+\begin{stack}\\ \synt{default\ specifier} \end{stack}
+\end{mysyntdiag}
+\begin{mysyntdiag}
+\synt{read\ specifier} \lit*{read} \synt{field\ or\ function}
+\end{mysyntdiag}
+\begin{mysyntdiag}
+\synt{write\ specifier} \lit*{write} \synt{field\ or\ procedure}
+\end{mysyntdiag}
+\begin{mysyntdiag}
+\synt{default\ specifier}
+\begin{stack} 
+\lit*{default} \begin{stack}\\ \synt{constant} \end{stack} \\
+\lit*{nodefault}
+\end{stack}
+\end{mysyntdiag}
+\begin{mysyntdiag}
+\synt{field\ or\ procedure}
+\begin{stack}
+\synt{field\ identifier} \\
+\synt{procedure\ identifier}
+\end{stack}
+\end{mysyntdiag}
+\begin{mysyntdiag}
+\synt{field\ or\ function}
+\begin{stack}
+\synt{field\ identifier} \\
+\synt{function\ identifier}
+\end{stack}
+\end{mysyntdiag}
+\end{diagram}

+ 31 - 0
docs/syntax/vardecl.syn

@@ -0,0 +1,31 @@
+\begin{diagram}{Variable declaration}{vardecl}
+\begin{mysyntdiag}
+\synt{variable\ declaration} \synt{identifier} \lit*: \synt{type} 
+\begin{stack}\\
+\lit* = \synt{expression}
+\end{stack}
+\begin{stack}\\ \synt{variable\ modifiers} \end{stack}
+\lit* ; 
+\end{mysyntdiag}
+\begin{mysyntdiag}
+\synt{variable\ modifiers}
+\begin{rep}[b]
+  \begin{stack}
+    \lit*{absolute} 
+    \begin{stack}
+      \synt{integer\ expression}\\
+      \synt{identifier}
+    \end{stack} \\
+    \lit*{;\ export} \\
+    \lit*{;\ cvar} \\
+    \lit*{;\ external}
+     \begin{stack} \\
+       \synt{string\ constant}
+     \end{stack} 
+     \begin{stack} \\
+       \lit*{name} \synt{string\ constant}
+     \end{stack}
+  \end{stack} 
+\end{rep}
+\end{mysyntdiag}
+\end{diagram}