מבוא מהיר לתחביר Pascal Script

מדריך זה מכסה את עקרונות התחביר המרכזיים של Pascal Script בסיסי כפי שהוא משמש במודול התסריטים לרוחב מערכת Hyper.
המדריך מסייע לעבור מהאופי הדינמי של JavaScript אל הסביבה המובנית של Pascal Script.
  • התחביר אינו רגיש לאותיות גדולות/קטנות כלל.
  • פקודות מסתיימות בנקודה-פסיק (;).   ירידות שורה אינן משפיעות על ביצוע הקוד.
  • בלוקים של קוד יש לתחום ב- begin ... end במקום { ... }.
  • תוכניות, פרוצדורות ופונקציות חייבות להצהיר על כל המשתנים לפני השימוש.
  • השמה למשתה תבוצע בסימן :=.
  • הערה בשורה אחת:
    // זו הערה
  • הערה מרובת שורות:
    { זו הערת בלוק }

תוכן העניינים

סוגי נתונים נתמכים

בשונה מ-let או var ב-JavaScript, פסקל דורש הגדרות טיפוס מפורשות. להלן הטיפוסים המובנים הזמינים במנוע הסקריפטים:
טיפוס תיאור מינימום מקסימום
Integer מספר שלם עם סימן, 32-ביט. -2147483648 2147483647
Int64 / LongInt מספר שלם עם סימן, 64-ביט. -9223372036854775808 9223372036854775807
Word מספר שלם ללא סימן, 16-ביט. 0 65535
Cardinal / LongWord מספר שלם ללא סימן, 32-ביט. 0 4294967295
Double מספר בנקודה צפה בדיוק כפול (Double-precision), עד 15 ספרות אחרי הנקודה. 2.23e-308 1.79e+308
String מחרוזת Ansi או Unicode.
Char תו Unicode יחיד (16-ביט).
Boolean דגל TRUE/FALSE.
Variant טיפוס כללי שיכול לאחסן כל ערך או אובייקט.

סימנים ומשמעותם

סימני הפיסוק בפסקל פועלים לפי כללים נוקשים ושונים מתחביר C-style של JavaScript.
סימן תיאור
:= השמה: קובע ערך למשתנה (ב-JS משתמשים ב-=).
= שוויון: אופרטור השוואה המשמש בתנאים (ב-JS משתמשים ב-==).
<> אי-שוויון: לא שווה (ב-JS משתמשים ב-!=).
< , > , <= , >= אופרטורי השוואה: קטן, גדול, קטן או שווה, גדול או שווה.
' ' גרשיים בודדים: ליטרלים של מחרוזות חייבים להשתמש בגרשיים בודדים.

אופרטורים

פעולות לוגיות ואריתמטיות משתמשות לעיתים במילות מפתח במקום בסימנים.
אופרטור תיאור
+ חיבור מספרים או שרשור מחרוזות.
- , * , / חיסור, כפל, חילוק (/ מחזיר תוצאה בנקודה צפה).
DIV חילוק שלם (מחזיר את המספר השלם ללא שארית).
MOD השארית לאחר חילוק שלם (ב-JS: %).
NOT NOT לוגי (ב-JS: !).
AND / OR AND / OR לוגיים (ב-JS: && ו-||).
XOR XOR לוגי (אמת רק כאשר האופרנדים שונים).
SHL / SHR הזזה ביטית שמאלה / ימינה.

הגדרת משתנים (VAR) - גלובאלי ומקומי

ב-Pascal Script אפשר להגדיר משתנים בשני מקומות:
1) מחוץ לפרוצדורה/פונקציה - משתנה גלובאלי, זמין לכל הסקריפט.
2) בתוך פרוצדורה/פונקציה - משתנה מקומי, זמין רק בתוך אותו בלוק.

* בלוק VAR גלובאלי נכתב בדרך כלל בתחילת הסקריפט, לפני הפרוצדורות.
* בהגדרה של ריבוי משתנים מספיק שהמילה VAR תופיע רק מפעם אחת (גם מחוץ וגם בתוך פרוצדורה)
VAR
  GlobalCounter: Integer;
  GlobalUserName: String;

Procedure InitUser;
Var
  LocalMessage: String;
Begin
  GlobalCounter:= 1;             // Global variable
  GlobalUserName:= 'Dana';       // Global variable

  LocalMessage:= 'User initialized';  // Local variable
  PopupMessage(LocalMessage);
End;

// Local VAR only (inside procedure)
Procedure CalcSum;
Var
  X, Y, Z: Integer;
Begin
  X:= 10;
  Y:= 20;
  Z:= X + Y;
  PopupMessage('Sum: ' + _Int_To_Str(Z, False));
End;

הגדרת קבועים (CONST)

קבועים (CONST) מוגדרים תמיד מחוץ לפרוצדורה/פונקציה ויוצבו תמיד מעליה ברצף הקוד.
הם אינם משתנים בזמן ריצה, ומשמשים לערכים קבועים בכל הסקריפט.
CONST
  MAX_RETRIES = 3;
  APP_NAME = 'Pascal Demo';

VAR
  Counter: Integer;

Procedure ShowInfo;
Begin
  Counter := 0;
  PopupMessage(APP_NAME + ' / retries: ' + _Int_To_Str(MAX_RETRIES, False));
End;

תנאי IF

השתמש ב-if ... then ... else לביצוע מותנה. השתמש בסוגריים להבהרה בביטויים מורכבים.
חשוב: אל תשים נקודה-פסיק (;) ממש לפני else.
VAR
  Age: Integer;
  IsMember: Boolean;
Begin
  Age:= 21;
  IsMember:= True;

  IF (Age >= 18) AND IsMember Then
    PopupMessage('Access granted')
  Else
    PopupMessage('Access denied');
End;
// Else-if style (nested if in else branch)
IF Score >= 90 Then
  Grade:= 'A'
Else IF Score >= 80 Then
  Grade:= 'B'
Else
  Grade:= 'C';

בלוקי קוד: Begin...End מול שורה יחידה

ב-JavaScript, סוגריים מסולסלים { } מקבצים פקודות. בפסקל משתמשים ב-begin וב-end.
  • שורה יחידה: אם IF או לולאה מכילים רק פקודה אחת, begin/end הם אופציונליים.
  • בלוק מרובה שורות: מספר פקודות חייבות להיות עטופות בבלוק begin...end;.
  • כלל ה-Else: אסור לשים נקודה-פסיק לפני מילת המפתח else.
// Single line example
IF X > 10 Then
  DoSomething;

// Block example
IF (X <= 10) AND (Y <> 0) Then
  Begin
    X:= X + 1;
    Y:= 0;
  End;

איטרציה (לולאות)

כל משתני הבקרה של הלולאה (כמו i) חייבים להיות מוכרזים בבלוק var לפני שהלולאה מתחילה.

For

משמש אך ורק לספירה בטווח.
VAR
  I: Integer;
Begin
  For I:= 1 to 5 Do
    Begin
      PopupMessage('Iteration: ' + _Int_To_Str(I, False));
    // do something else in this block
    End;

  For I:= 5 downto 1 Do
    PopupMessage('Countdown: ' + _Int_To_Str(I, False));
End;

While

חוזר כל עוד התנאי נשאר True.
While (CurrentValue <= MaxLimit) Do
  Begin
    CurrentValue:= CurrentValue + Step;
  End;

Repeat...Until

דומה ל-do...while ב-JS; תמיד מבצע לפחות פעם אחת ועוצר כאשר התנאי הופך ל-True.
Repeat
  ExecuteTask;
Until (IsFinished = True);

Case (מקביל ל-switch)

Case הוא המקביל בפסקל ל-switch ב-JavaScript. משתמשים בו כדי לבחור בקלות בין מספר ענפים.
VAR
  DayNumber: Integer;
  DayName: String;
Begin
  DayNumber:= 3;

  CASE DayNumber OF
    1: DayName:= 'Sunday';
    2: DayName:= 'Monday';
    3: DayName:= 'Tuesday';
    4: DayName:= 'Wednesday';
    5: DayName:= 'Thursday';
    6: DayName:= 'Friday';
    7: DayName:= 'Saturday';
  Else
    DayName:= 'Unknown';
  End;
End;
נתמך גם Case המבוסס על מחרוזת:
VAR
  CommandText: String;
Begin
  CommandText:= 'start';

  CASE LowerCase(CommandText) OF
    'start': PopupMessage('Starting...');
    'stop': PopupMessage('Stopping...');
    'pause': PopupMessage('Paused.');
  Else
    PopupMessage('Unknown command: ' + CommandText);
  End;
End;

מערך (Array)

מערכים מאחסנים מספר ערכים מאותו טיפוס במיקומים ממוספרים (indexed).
VAR
  Scores: Array[0..4] OF Integer;
  I: Integer;
Begin
  Scores[0]:= 10;
  Scores[1]:= 20;
  Scores[2]:= 30;
  Scores[3]:= 40;
  Scores[4]:= 50;

  For I:= 0 to 4 Do
    PopupMessage('Score #' + _Int_To_Str(I, False) + ': ' + _Int_To_Str(Scores[I], False));
End;

TRY

השתמש ב-Try...Except כדי ללכוד ולטפל בשגיאות בזמן ריצה.
VAR
  X, Y, Z: Integer;
Begin
  X:= 10;
  Y:= 0;

  TRY
    Z:= X Div Y;
    PopupMessage('Result: ' + _Int_To_Str(Z, False));
  EXCEPT
    PopupMessage('An error occurred: division by zero.');
  End;
End;

השתמש ב-Try...Finally כאשר קוד ניקוי חייב לרוץ בין אם מתרחשת שגיאה ובין אם לא.
VAR
  Started: Boolean;
Begin
  Started:= False;

  TRY
    Started:= True;
    PopupMessage('Starting task...');
    ExecuteTask;
  FINALLY
    IF Started Then
      PopupMessage('Cleanup completed.');
  End;
End;

פרוצדורות מול פונקציות

פרוצדורה ופונקציות שתיהן מבצעות סט פעולות, אך רק פונקציות מחזירות ערך.
* פונקציה תחזיר 0 כברירת מחדל במקרה שלא הוחזר ערך באמצעות הקוד:  
Result:=Value;

* המערכת לא תומכת בתתי-שגרות מקוננות (local).
* פונקציות ופרוצדורות פרטיות (לא אירועי מערכת) יש לקודד מעל אירוע המערכת הקורא לה ואף עדיף להציבם בראש הקוד.
Function AddNumbers(A, B: Integer): Integer;
Begin
  Result:= A + B;
End;

Procedure LogMessage(Msg: String);
VAR
  Sum: Integer;
Begin
  LogMessage('Calculating...');
  Sum:= AddNumbers(7, 5);
  PopupMessage('Sum = ' + _Int_To_Str(Sum, False));
End;

העברת פרמטרים

פרמטרים רגילים מועברים לפי ערך. פרמטרים מסוג var מועברים לפי הפניה (reference).
הערה חשובה: פרמטר עם `VAR` חייב לקבל משתנה אמיתי, ולא לקבל קבוע/ביטוי.
// מקבלת ערך מספרי למשתנה
Procedure IncreaseByValue(X: Integer);
Begin
  X:= X + 1;
End;

// n מקבל הפניה למשוך את תוכן הפרמטר X הפרמטר
Procedure IncreaseByRef(VAR X: Integer);
Begin
  X:= X + 1;
End;


Procedure MyProc;
VAR
  N: Integer;
Begin
  N:= 10;
  IncreaseByValue(N);
  PopupMessage('After value call: ' + _Int_To_Str(N, False)); // 10

  IncreaseByRef(N);
  PopupMessage('After var call: ' + _Int_To_Str(N, False)); // 11
End;

כלי עזר למחרוזות

עזרי מחרוזות נפוצים הם פשוטים ובעלי טיפוסים חזקים.
VAR
  S: String;
Begin
  S:= '  Pascal Script  ';

  PopupMessage('Length: ' + _Int_To_Str(Length(S), False));               //Show number of Characters
  PopupMessage('Trim: [' + Trim(S) + ']');                                //Trim white spaces before and after
  PopupMessage('Upper: ' + UpperCase(S));                                 //Set Upper Case
  PopupMessage('Lower: ' + LowerCase(S));                                 //Set Lower Case
  PopupMessage('Pos of Script: ' + _Int_To_Str(Pos('Script', S), False)); //Return the numeric position of starting phrase
  PopupMessage('Copy 1..6: ' + Copy(Trim(S), 1, 6));                      //Return the string within a position
End;

יסודות תאריך/שעה

המרה וטיפול בערכי תאריך/שעה.
הפונקציות הבאות הן רק דוגמא לחלק מהפונקציות הקיימות ואינן משקפות את כל היכולות של המערכת.
לרשימת כלל הפונקציות הזמינות עבורך מערכת התסריטים קרא את המדריך כאן.
VAR
  nowValue: TDateTime;
Begin
  nowValue:= Now;

  PopupMessage('Date: ' + _Date_To_Str(Date, False));                      //Returns value formatted like: '03/12/2025' OR '2025-03-12'
  PopupMessage('Time: ' + _Hour_To_Str(Time));                             //Returns value formatted like: '10:30'
  PopupMessage('Now: ' + _YYYY_MM_DD_To_Str(nowValue));                    //Returns value formatted in ISO 8601, like: '2025-03-12T00:00:00'
  PopupMessage('Custom: ' + Format_FixDT_To_Str(he_DD_MM_YYYY, nowValue)); //Returns current date/time in local format like: '03/12/2026' and has more options...
End;

המרת טיפוסים

המרות הן מפורשות. השתמש בגרסאות Try כאשר קלט משתמש עלול להיות לא תקין.
VAR
  S: String;
  N: Integer;
  F: Double;
Begin
  S:= '42';
  N:= StrToInt(S);
  F:= StrToFloat('3.14');

  PopupMessage('IntToStr: ' + _Int_To_Str(N, False));
  PopupMessage('FloatToStr: ' + FloatToStr(F));

  IF TryStrToInt('abc', N) Then
    PopupMessage('Converted: ' + _Int_To_Str(N, False))
  Else
    PopupMessage('Invalid integer input.');
End;

רשומות (Records)

Record הוא מבנה נתונים מטופס, הדומה ל"צורת אובייקט" פשוטה ב-JavaScript.
שים לב שה- RECORD חייב להיות מוגדר מחוץ לפרוצדורה/פונקציה.
type
// גלובאלית TYPE הגדרת
TYPE
  TUser = RECORD
    Name: String;
    Age: Integer;
    Active: Boolean;
End;

// גישה מתוך פרוצדורה
Procedue MyProc;
VAR
  User: TUser;
Begin
  User.Name:= 'Dana';
  User.Age:= 28;
  User.Active:= True;

  PopupMessage('User: ' + User.Name + ', age ' + _Int_To_Str(User.Age, False));
End;