Yorick (שפת תכנות)

**Yorick** היא שפת תכנות הנעזרת במפרש (Interpreter) עבור סימולציות וחישובים מדעיים, טיפול בגרפים וקטעי קוד ארוכים, וכן עבור קריאה, כתיבה, או תרגום של קבצים גדולים של מספרים. השפה שפותחה בשנת 1996 על ידי דייוויד מונרו  נכתבה באמצעות שפת C וגם התחביר שלה באופן כללי בסגנון של השפות מבוססות-C. שפת Yorick יכולה לרוץ על רוב המעבדים ומערכות ההפעלה הנפוצות.

## סביבת העבודה
### הפעלה

בעת התקנת השפה, מקבלים תיקייה ששמה מתחיל ב"yorick", ובתוכה יש שתי תיקיות עם קובצי הפעלה:

התיקייה bin נועדה לעבוד בתוך שורת הפקודה של Windows, ואילו התיקייה binmfc פותחת חלון בממשק גרפי.

בשני המקרים, מקבלים ממשק להקלדת פקודות וביצוע מיידי (כמו בשפות אחרות המשתמשות ב-interpreter).

### קובצי קוד

מקובל לתת לקובצי קוד של yorick את הסיומת i.

כדאי למקם את הקבצים בתיקיית שבה נמצאים קובצי ההרצה של הטרמינל (binmfc) כיוון שהיא מוגדרת כספריית ברירת המחדל שבה המפרש מחפש את הקבצים. בכל מקרה ניתן לעשות שימוש בפקודת cd כדי לשנות את התיקייה שבה המפרש מחפש את הקבצים.


```c
>cd, "directory_name"
```


כדי לדעת מהי התיקייה הנוכחית יש להפעיל את הפונקציה get_cwd


```c
>get_cwd()
```


כדי להכליל קובצי קוד בתוכנית יש לבצע פקודת include


```c
>include, "file_name"
```


אפשרות נוספת להכללת קובץ קוד כבר בשלב הפעלת התוכנית היא באמצעות פקודת include בשורת הפקודה בה אנו מפעילים את yorick:


```c
>yorick -i "file_name"
```


ניתן גם לתת כתובת מלאה של הקובץ, ככל כללי העבודה בשורת הפקודה.

בכל מקרה של הכללת קובץ - הפעולה מתבצעת כמו בשפת C ו-C++, כלומר: הכללת קובץ שקולה להקלדתו במיקום הנוכחי אות באות.

## משתנים

כמו בפייתון, מנגנון הטיפוסים ב-Yorick הוא דינאמי. למשתנים אין טיפוס ולכן אין אפשרות להגדיר את סוג המשתנה לפני ההשמה. תקינות של טיפוסים בביטוי נבדקת רק במהלך חישוב הביטוי עצמו, תוך כדי ריצת התוכנית. תכונה זאת מקלה על הכנסת שגיאות, וגורמת לגילוי שלהן להתרחש מאוחר למדי, אם בכלל. מאידך, קל יותר לכתוב תוכניות פשוטות וזמן הכתיבה קצר בהרבה.

פונקציית info משמשת לקבלת מידע על סוג המשתנה.

### תחום ההכרזה של משתנים

כל המשתנים נחשבים גלובליים גם אם הוגדרו בתחום הכרזה ספציפי. לדוגמה, משתנה שהוגדר בפונקציה אחת יהיה מוכר בפונקציה אחרת.

עם זאת, כאשר פונקציה מתחילה את השימוש שלה במשתנה בהצבה לתוכו - המשתנה הזה יוגדר כמשתנה חדש מקומי, גם אם כבר הוגדר במקום אחר.

ישנה אפשרות להצהיר על משתנה כ-external, או לחלופין כ-local.

### המרות

המרה ל-string: בדומה לפונקציה toString של #c, קיימת פונקציה בשם pr1 שממירה את הביטוי שמתקבל כפרמטר ל-string.

הפונקציה strchar ממירה בין מחרוזת למערך של תווים, ולהפך.

המרה בין char ל-int באמצעות המרה מרומזת:


```c
>ch='a'
>a+0
>97
```


### מצביעים ואיסוף זבל

ניתן להשתמש במצביעים באמצעות התו &, כמו בשפת C++ (זהו שינוי משמעותי לעומת פייתון שאינה תומכת במצביעים).

נשים לב, שכאשר אנו מציבים ערך לתוך משתנה שמוצבע על ידי משתנה אחר - זה גורם להגדרת משתנה חדש, ולא משנה את הישן. אם רוצים לשנות את הערך ולא להגדיר חדש צריך להשתמש בשני האופרטורים * ו-& ביחד. לדוגמה:


```c
>*&x=9
```


איסוף זבל (Garbage collection) מתבצע בשיטת מונה-שימושים (Reference counting), שכאשר הוא מתאפס אז האובייקט נמחק.

השפה לא תומכת באריתמטיקה של מצביעים, וגם לא בפונקציות-הורסות (כיוון שאין מחלקות).

### אובייקטים - עצמים

השפה לא מכירה במחלקות בעלות פונקציות, אלא במבנים (structs) בלבד.

הצהרה על struct:


```c
>struct x{int a,b,c; char d;}
```


בניית מופע של x:


```c
>x1=x(a=1, b=2, c='c')
```


גישה לאחד משדות המופע מתבצעת על ידי האופרטור ".":

```c
>x1.a
```


### מחרוזות

השפה כוללת פונקציות מובנות רבות ויעילות לטיפול במחרוזות. לדוגמה:

# strpart - יצירת תת-מחרוזת ממחרוזת קיימת.

# strfind - מציאת תת-מחרוזת במחרוזת נתונה.

# strlen - מחזירה אורך של מחרוזת.

# strtrim - הסרת רווחים

# strgrep - חיפוש במחרוזת תוך שימוש בביטויים רגולריים

# strtok - מחלקת מחרוזת לתתי מחרוזות (בדומה ל-split)

שרשור של מחרוזות מתבצע האמצעות האופרטור +.


```c
>a="aaa"
>b="bbb"
>a+b
>"aaabbb"
```


בשביל לעבור על תווי המחרוזת אחד אחד נשתמש בקוד הבא (השורה הראשונה נותנת מחרוזת בגודל 1 כדי להפוך את זה לתו צריך את השורה השנייה).


```c
>c = strpart(string,[i,i+1]);
>c = strchar(c)(1);
```


### מערכים

שפת yorick מכוונת לעבודה עם מערכים (Array programming languages). השימוש במערכים מאפשר הרצה מהירה יותר של קוד.

קיימות פקודות ופונקציות מובנות בשפה עבור עבודה עם מערכים.

כל המשתנים ב-yorick מיוצגים כמערך.

הגדרת מערך נעשית בדרך כלל על ידי סוגריים מרובעים ובהם ערכי המערך.

כברירת מחדל האינדקסים במערך מתחילים ב-1 ולא ב-0.

פונקציות שימושיות לעבודה עם מערכים:

# grow - הגדלת מערך.

# numberof - מחזירה את מספר האיברים במערך.

הפעלת פונקציה על מערך הפונקציה מופעלת על כל איבר במערך.

למשל אם נגדיר את הפונקציה:


```c
func b(&a){
 a = a * 2;
}
```


ונגדיר מערך:


```c
> t = [1, 8 ,4 ,1568]
```


אם נשלח את t לפונקציה:

```c
> b,t
> t
[2,16,8,3136]
```


ההפניה לאינדקסים של מערכים, וכן חלוקת מערך לחלקים וכו' - מתבצעות כמו בפייתון. לדוגמה הקוד הבא יציב למשתנה b את ארבעת האיברים הראשונים במערך a, למשתנה c את ארבעת האיברים הבאים, ואילו במשתנה d יהיו כל השאר:

```c
> b=a[:4]
> c=a[5:8]
> d=a[9:]
```


## פונקציות
### הגדרת פונקציה

דוגמה להגדרה של פונקציה שממירה string ל-int:


```c
func toInt(n_string)
{
 n_chars=strchar(n_string)
 n=0
 for (i=1;i<strlen(n_string)+1;i++)
 n=n*10+n_chars(i)-'0'
 return n
}
```


לא ניתן להציב ערכי ברירת מחדל לפמטרים של הפונקציה, אך ניתן להשמיט פרמטרים, ואז הם יקבלו ערך nil (המוצג במסך כמערך ריק). מותר גם לדלג על משתנה אמצעי אך בתנאי שלא נשמיט את הפסיק.

אין אפשרות של הצבת פרמטרים לפי שמות.

### קריאה לפונקציה

ניתן לקרוא לפונקציה כאשר רשימת הפרמטרים בתוך סוגריים (כמקובל ברוב השפות), או כאשר היא מופרדת משם הפונקציה בפסיקים (דבר די ייחודי אשר איננו נפוץ בשפות אחרות).

ההבדל בין שתי הקריאות הוא בנוגע לערך המוחזר:

אם קראנו לפונקציה באמצעות שימוש בפסיקים - הערך המוחזר מהפונקציה לא ייקלט ולא יישמר בשום מקום (ולא ניתן להציב אותו לתוך משתנה), אך כאשר קוראים לפונקציה באמצעות סוגריים - אז היא מחזירה ערך לתוך משתנה. במקרה שלא הצבנו את הערך לתוך משתנה - הערך יודפס למסך. במקרה שהפונקציה לא החזירה ערך - זה נחשב כמו פקודת הדפסה של משתנה שאינו מאותחל שמדפיסה למסך "מערך ריק" (סוגריים מרובעים).

שתי התכונות הבאות קיימות רק בפונקציה המוגדרת על ידי המשתמש, ולא בפונקציות מערכת:

פונקציה שאינה מקבלת פרמטרים - קוראים לה בלי סוגריים בלבד, ולכן היא אינה יכולה להחזיר ערך.

אם נציב שם של פונקציה לתוך מזהה - המזהה יהיה העתק של הפונקציה, וגם אם נשכתב את הפונקציה - זה לא יפגע בפעולת הפונקציה המוגדרת על המזהה.

כדי לגשת למשתנה הריאלי מתוך הפונקציה ניתן:

#להשתמש ב-extern (בתוך הפונקציה).

#להשתמש ב-& (בהעברת הפרמטרים).

#להתחיל את השימוש במשתנה בפקודת שאינה השמה.

## קלט ופלט
### עבודה עם קובצי טקסט

# פתיחת קובץ וסגירתו באמצעות פונקציות open ו-close.הפונקציה open מקבלת שני פרמטרים, שם של קובץ ואופן פתיחה, לקריאה - "r", לכתיבה - "w" ולשניהם - "+r"

# קריאה מקובץ: rdline - קריאת שורה בקובץ וקידום המצביע לשורה הבאה (הפונקציה מקבלת את שם הקובץ ומחזירה מחרוזת של שורה). rdfile - קוראת את כל הקובץ המתקבל כפרמטר, ומחזירה את כל השורות כמערך של מחרוזות.

# כתיבה לקובץ: הפונקציה write, אם הפרמטר הראשון שלה הוא אובייקט של קובץ פתוח, אז היא תכתוב את שאר הפרמטרים לתוכו. הפונקציה write מדפיסה רווח בתחילת שורה וכן רווחים בין הפרמטרים. כדי להימנע מרווחים מיותרים ניתן להשתמש בפקודה הבאה:


```c
write, "\n" + string1 + string2
```


או באופציה הבאה:


```c
write, file,format="%s%d%s",string,number,"\n";
```


במקרה שאחד הפרמטרים המועברים ל-write אינו מסוג string ניתן להמיר באמצעות הפונקציה pr1.

פונקציות חשובות של yorick לעבודה עם קבצים: remove ו-rename.

### כתיבה למסך

כתיבה למסך מתבצעת בשתי שיטות: או באמצעות פונקציית write (כאשר הפרמטר הראשון איננו אובייקט של קובץ פתוח) או באמצעות פונקציית print.

יש ביניהן כמה הבדלים, כשבאופן כללי ניתן לומר שהפונקציה print מראה את הערך כפי שהוזן, והפונקציה write מדפיסה בצורה קריאה יותר.

### קריאה מהמקלדת

קריאת שורה מהמקלדת מתבצעת באמצעות הפונקציה ()rdline (צריך להשתמש עם סוגריים ריקים, אך בלי פרמטרים) המחזירה מחרוזת של השורה שהוזנה על ידי המשתמש.

## תחביר
### Case sensitivity

השפה רגישה לאותיות קטנות או גדולות (Case sensitivity).

## יכולות גרפיות

לyorick יש יכולות מובנות של יצירת גרפים, למשל:


```c
> plg , [1,2,3],[1,4,9]
```


ייצור גרף של המערך הראשון כפונקציה של השני

## פונקציית help

לקבלת הסבר ודוגמאות עבור כל פקודה בשפה יש לכתוב במפרש help ולאחר מכן פסיק ואת שם הפקודה.

לדוגמה:


```c
> help, help
```


## קישורים חיצוניים
* 

* דף הבית של השפה

* הורדת הגרסה האחרונה ל-Windows

* אינדקס של פונקציות השפה

* מאמר על השפה

קטגוריה:שפות תכנות