General Add-ons Plug-ins Scripting Syntax Files Dictionaries (External)

Language Overview

Pascal Script is a natively implemented Pascal-like scripting language that is untyped, Variant-based, and dynamic, supporting declaration of procedures and functions, variables and constants, and global statements, with Delphi-style exception handling via raise/try/except/finally.

The language provides conditional statements for branching, loop statements for iteration, and exception handling statements for robust error control, with all identifiers represented as Variant values including numbers, strings, booleans, dates, IDispatch objects, and special values nil, Unassigned, Null, True, and False.

Arrays are supported as Variant-backed collections, allowing dynamic structures alongside other Variant types, consistent with Delphi's Variant system used by the engine.

Global declarations

At the global level, a unit may declare procedures, functions, variables, and constants, and may include an optional global statements block at the end; there can be multiple var/const sections interleaved with routines.

var
  X, Y;
  Z = 7;
const
  Pi = 3.14;

procedure P(A; B);
var
  i, j;
  k = 3;
begin
  ShowMessage(A + B + F * Pi);
end;

function F;
begin
  Result := 7;
end;

begin
  ShowMessage('This is a global statement');
end;

Declaration order is not significant: routines and variables can reference each other regardless of order; parameters are by value by default, with var/out used for by-reference and const for read-only, and functions expose an implicit Result variable.

Exit immediately leaves the current procedure or function, causing a run-time error if used outside any routine; local variables can have initializers similar to globals.

Compound Statements

A compound statement groups multiple statements between begin and end, allowing sequences where a single statement is syntactically expected, consistent with Delphi-style block structure.

Compound blocks are commonly used as bodies of if, case, for, while, repeat, try/except, and try/finally constructs to encapsulate multi-step logic.

Conditional Statements (if, case)

If

The if/then statement conditionally executes code, with else being optional, supporting both single statements and compound begin/end blocks.

if X > 0 then
  ShowMessage('X is positive');

if S <> '' then
  ShowMessage('S is not empty')
else
  ShowMessage('S is empty');

if S <> '' then
begin
  ShowMessage('S is not empty');
  Result := True;
end
else
  ShowMessage('S is empty');
Case

Case supports expression labels (not just constants), allows non-unique labels, optional else, and supports numbers, strings, and ranges for flexible selection.

case x of
  0: ShowMessage('Zero');
  1, 3, 5, 7, 9: ShowMessage('Odd');
  2, 4, 6, 8, 10: ShowMessage('Even');
else
  ShowMessage('Too big');
end;

case s of
  'True': b := True;
  'False': b := False;
else
  ShowMessage('Invalid value');
end;

case x of
  10, 12, 20..26: x := 2;
end;

Loop Statements (for, while, repeat)

Looping uses for/to for ascending iteration, for/downto for descending, while with pre-condition, and repeat with post-condition, each accepting single or compound statement bodies.

for i := 0 to 10 do
  ShowMessage(i);

for i := 10 downto 0 do
  ShowMessage(i);

i := 1;
while i &lt; 10 do
begin
  ShowMessage(i);
  i := i * 2;
end;

i := 1;
repeat
  ShowMessage(i);
  i := i * 2;
until i &gt;= 10;

Break and Continue

Break exits the innermost loop and Continue skips to the next iteration; using them outside a loop raises a run-time error and nested loops respect innermost semantics.

i := 1;
while i &lt; 100 do
begin
  if i = 15 then Break;
  i := F(i);
end;

for i := 0 to 10 do
begin
  if (i mod 2) &lt;&gt; 0 then Continue;
  ShowMessage(i + ' is an even number');
end;

for i := 0 to 10 do // outer
begin
  if i = 5 then Break; // break outer
  for j := 0 to 10 do // inner
  begin
    if j = 5 then Break; // break inner
  end;
end;

Exception Handling Statements (raise, try)

Raise

Raise throws exceptions created via expressions (e.g., Exception.Create), requiring the appropriate Delphi exception classes to be available to the script through imported units.

if X > 10 then
  raise Exception.Create('X is too big');

Try/except

Try/except catches exceptions with simple catch-all or typed handlers using on E: TClass do, supporting multiple handlers and optional else for uncaught cases.

try
  DoSomething;
except
  ShowMessage('Error has occurred.');
end;

try
  DoSomething;
except
  on E: EArgumentException do ShowMessage('Invalid argument');
  on E: EOutOfMemory do ShowMessage('Out of memory');
  else ShowMessage('Other error.');
end;

try
  DoSomething;
except
  on E: EArgumentException do LogMessage('Error: ' + E.Message);
end;

Re-raising is done with a bare raise inside an except block; using it elsewhere is illegal and results in a run-time error per the language rules.

try
  DoSomething;
except
  ShowMessage('Error');
  raise;
end;

Try/finally

Try/finally guarantees execution of cleanup code and implicitly re-raises the current exception; Break/Continue/Exit that jump out still execute finally, but using them inside finally is illegal.

obj := TMyObject.Create;
try
  DoSomething(obj);
finally
  obj.Free;
end;

for i := 0 to 10 do
begin
  try
    Break;
  finally
    ShowMessage('In finally');
  end;
end;

// Illegal:
for i := 0 to 10 do
begin
  try
    DoSomething;
  finally
    Break; // run-time error
  end;
end;

Expressions

Expressions cover assignments, calls, property access (including indexed), arithmetic and logical operations, and literals including integers, floats, strings, nil, True, False, Unassigned, and Null.

x := 7;  x := -7;  x := 7.0;  x := +0.25E+10;
s := 'Some string';
x := $A23BD7;

s := 'This is a string containing a single '' symbol';
s := 'This is a ' + #13#10 + 'two line string';

Nil denotes no-object (Variant varDispatch=nil), Unassigned corresponds to an empty Variant (varEmpty), and Null represents database NULL (varNull), aligning with Delphi semantics.

Short-circuit Boolean

Operators and/or use incomplete Boolean evaluation like Delphi, evaluating the right operand only when necessary, avoiding dereferencing errors in guard patterns.

if (obj <> nil) and (obj.Width < 100) then
   ...

Calls, properties, sets, and event handlers

P(5, 7);
x := F1(3);
x := F2;     // brackets omitted
x := F2();

h := MyFont.Height;
s := Application.ActiveForm.Caption;
s := Memo.Lines.Items; // indexed property

Font.Style := ;
if fsBold in Font.Style then ShowMessage('Font is bold');
Include(FontStyle, fsBold);

procedure Button1Click(Sender);
begin
  ShowMessage('Hello from script');
end;

begin
  Button1.OnClick := @Button1Click;
end;

Set constructors use brackets with elements and ranges, in tests membership, Include/Exclude manipulate sets, and @ obtains a procedure reference to assign event handlers.

Arrays

Pascal Script supports single- and multi-dimensional arrays with optional low bounds; array constructors use array syntax, and element type can be specified for efficiency (e.g., Byte).

a := array;         // multi-dimensional
a := array;         // same as 
a := array;         // same as 
a := array of Byte; // element type override

Use square brackets for indexing, Length(array), Low(array), and High(array) mirror Delphi functions, with dimensions numbered from 1 for multi-dimensional arrays.

Intrinsic Functions

Pascal Script includes built-in procedures, functions, and constants closely matching Delphi, available without importing additional units for common operations and control flow.

These include special branching helpers, standard constants like True, and a broad set of utility routines that align with Delphi naming and behavior for familiarity.

Special branching functions

  • Exit
  • Break
  • Continue

Constants

  • Null
  • Unassigned
  • True
  • False

Functions

  • Include
  • Exclude
  • Beep
  • ArcTan
  • Cos
  • Dec
  • Sin
  • LowerCase
  • High
  • Low
  • Ln
  • AnsiCompareStr
  • AnsiCompareText
  • AnsiLowerCase
  • AnsiUpperCase
  • Abs
  • CompareStr
  • CompareText
  • Date
  • DateTimeToStr
  • DateToStr
  • DayOfWeek
  • DecodeDate
  • Exp
  • FloatToStr
  • FracInt
  • IntToHex
  • IntToStr
  • IsLeapYear
  • IsValidIdent
  • Length
  • Now
  • Odd
  • Pos
  • Random
  • Round
  • Sqr
  • Sqrt
  • StrToDate
  • StrToDateTime
  • StrToFloat
  • StrToInt
  • StrToIntDef
  • Time
  • TimeToStr
  • StrToTime
  • Trim
  • TrimLeft
  • TrimRight
  • Trunc
  • UpperCase
  • VarIsNull
  • VarToStr
  • Assigned
  • ShowMessage
  • Insert
  • IncMonth
  • Inc
  • Chr
  • Copy
  • Delete
  • CreateOleObject
  • GetActiveOleObject
  • InputQuery
  • DecodeTime
  • EncodeDate
  • EncodeTime
  • Format
  • FormatFloat
  • FormatDateTime
  • Ord

BNF Syntax

The grammar below summarizes units, declarations, statements, expressions, sets, arrays, operators, and designators, reflecting the Pascal Script parser's accepted forms and precedence.

<Unit> ::=  {<VarSection> | <ConstSection> | <ProcedureDecl>} 

<UsesClause> ::= uses <Identifier> {"," <Identifier>} ";"

<VarSection> ::= var <VarDecl> ";" {<VarDecl> ";"}
<VarDecl> ::= <Identifier> ({"," <Identifier>} | "=" <Expression>)

<ConstSection> ::= const <ConstDecl> ";" {<ConstDecl> ";"}
<ConstDecl> ::= <Identifier> "=" <Expression>

<ProcedureDecl> ::= (procedure | function) <Identifier>  ";"
                      {<VarSection> | <ConstSection>}
                      begin <StmtList> end ";"

<ParamsDecl> ::= <ParamDecl> {";" <ParamDecl>}
<ParamDecl> ::= (var | out | const ) <Identifier>

<Statement> ::= <Designator> 
               | <CompoundStmt> | <IfStmt> | <CaseStmt> | <RepeatStmt>
               | <WhileStmt> | <ForStmt> | <TryStmt> | <RaiseStmt> | <EmptyStmt>

<StmtList> ::= <Statement> ";" {<Statement> ";"}
<EmptyStmt> ::= ";" | else | until | end

<CompoundStmt> ::= begin <StmtList> end
<IfStmt> ::= if <Expression> then <Statement> 

<CaseStmt> ::= case <Expression> of <CaseSelector> ";"
                {<CaseSelector> ";"}  end
<CaseSelector> ::= <CaseLabel> {"," <CaseLabel>} ":" <Statement>
<CaseLabel> ::= <Expression> 

<RepeatStmt> ::= repeat <StmtList> until <Expression>
<WhileStmt> ::= while <Expression> do <Statement>
<ForStmt> ::= for <Identifier> ":=" <Expression> (to | downto) <Expression> do <Statement>

<TryStmt> ::= try  (except (<ExceptionBlock> | <StmtList>) | finally <StmtList>) end
<ExceptionBlock> ::= {on  <Expression> do <Statement> ";"} 
<RaiseStmt> ::= raise 

<Expression> ::= <SimpleExpression> {<RelOp> <SimpleExpression>}
<SimpleExpression> ::= <Term> {<AddOp> <Term>}
<Term> ::= <Factor> {<MulOp> <Factor>}

<Factor> ::= <Designator> | INT_LITERAL | FLOAT_LITERAL | STRING_LITERAL | nil
            | "(" <Expression> ")" | not <Factor> | "-" <Factor> | "+" <Factor>
            | <SetConstructor> | array "" 
            | "@" <Identifier>

<ArrayDim> ::= <Expression> 
<RelOp> ::= ">" | "<" | "<=" | ">=" | "<>" | "=" | in | is
<AddOp> ::= "+" | "-" | or | xor
<MulOp> ::= "*" | "/" | div | mod | and | shl | shr

<Designator> ::= <Identifier> {"." <Identifier> | ""
                                      | "("  ")"}

<SetConstructor> ::= " "]"
<SetElement> ::= <Expression> 

<Identifier> ::= IDENTIFIER


© 1998 - 2026 Carthago Software. All rights reserved.