תכנות פונקציונלי, מודל הסביבה, זרמים, תכנות לוגי ומערכות טיפוסים
(num-val 12)(num-val 9)(num-val 11)(num-val 2)(num-val 4)(proc-val ...)Expression ::= {&}+ (Expression)
multiptr-exp (ptrs data)
Expression ::= {*}+ (Expression)
multistar-exp (stars v)
Expression ::= option Identifier = Expression assign-exp (opt id newval) Option ::= ε | @
assign-exp המוחדש יש option של @ או שאינו מופיע (ריקה ε). כאשר ה-option הוא ריקה (ε), ביטוי זה assign-exp כותב ישירות לתא הזיכרון של identifier, כמו set רגיל. כאשר ה-option הוא @, ה-identifier חייב להיות שם של משתנה רב-מימדי, ובמקרה זה ביטוי assign-exp יעדכן את הנחון (הערך) שאליו מצביע identifier לפי ערכו של ביטוי newval.multiptr-exp מאפשר להגדיר מצביע רב-מימדי (מצביע למצביע) על ידי שימוש ב-&. הביטוי ptrs הוא רשימת סמני & המגדירים את עומק המצביע. הרכיב data הוא ביטוי המייצג את הערך הבסיסי שאליו מצביע המצביע.multistar-exp הוא ביטוי הפניה (dereference) על מצביע רב-מימדי. ניתן להשתמש בו רק על ביטוי מסוג multiptr-exp; כל ניסיון אחר יגרור שגיאה.set @p = 9 מעדכן את הנחון שאליו מצביע p להיות 9 במקום הפרוצדורה, ולבסוף מבצעים dereference מלא על p ומחזירים 9-2 ולכן הוא (num-val 7).set @q = 20 משנה את הערך שאליו מצביע q (רמה אחת מתחתיו), כלומר מעדכן את תא הזיכרון הבסיסי ל-20. לכן כעת ****(p) עובר 4 רמות ומגיע לאותו תא בסיסי שכעת מכיל 20, ולכן הניב הוא (num-val 17).set @p = 20 מעדכן את הנחון שאליו מצביע p (רמה אחת מתחתיו) ל-20, כך שגם q (שמצביע לאותה רמה) רואה כעת את הערך 20 בסוף שרשרתו. לאחר מכן set p = 5 משווה את p עצמו ל-5 (מספר). כעת **(q) מבצע dereference דו-מימדי דרך q ומגיע ל-20; ו-p הוא 5. לכן הניב הוא -(20, 5) = (num-val 15).for/proc.Expression ::= for/proc ( identifier ;
| { identifier }*(,) | ;
| { Expression }*(,) | )
{< Guard>}*
{
Expression
}
forproc-exp (Id Ids Bodies Guards Body)
Guard ::= skip : Expression
skip-guard (exp)
Guard ::= break : Expression
break-guard (exp)
forproc הרכיבים הבאים:id ילקח מרשימת ids ויהיה שם הפרמטר בגוף הפרוצדורה שנקבע לפי הביטוי המקביל ברשימת bodies.Guard מסוג שני: skip ו-break. כל Guard מבוטא בביטוי. אם Guard מסוג skip מתקיים (מחזיר אמת), הלולאה מדלגת על האיטרציה הנוכחית וממשיכת לאיטרציה הבאה. ב-Guard מסוג break, כאשר הביטוי מחזיר אמת, הלולאה מסתיימת לאלתר. בכל איטרציה נבדקים כל ה-Guards בסדרם.break מחזיר אמת, או כאשר נגמרים האיברים ברשימות ה-Ids וה-Bodies.forproc-exp אין ערך מוחזר, ולכן יש להחזיר ערך פיקטיבי של num-val 27.w1,w2,w3 המאותחלים לערכים 100,300,500 בהתאמה. לאחר מכן, מבוצעת לולאה for/proc עם משתנה לולאה בשם p. בלולאה יש 4 פרוצדורות (בכל איטרציה נבחרת p עם גוף שונה):p מייצג פרוצדורה בעלת פרמטר a וגוף -(a,1). לא אחד מה-Guards מתקיים, ולכן מבוצע גוף הלולאה. מכיוון שה-p מקבל 1 ומחשב -(1,1)=0, w1 משתנה להיות 7000.p מייצג פרוצדורה בעלת פרמטר b וגוף -(b,2). ה-Guard מסוג skip מתקיים (כי -(2,2)=0), ולכן הלולאה מדלגת לאיטרציה הבאה.p מייצג פרוצדורה עם פרמטר c וגוף -(c,3). אף אחד מה-Guards לא מתקיים, ולכן מבוצע גוף הלולאה. w2 משתנה להיות p (הפרוצדורה הנוכחית).p מייצג פרוצדורה עם פרמטר d וגוף -(d,4). אף אחד מה-Guards לא מתקיים, ולכן מבוצע גוף הלולאה. w3 משתנה להיות (p w1) = (p 7000) = -(7000,4) = 6996.(w2 w3): w2 הוא הפרוצדורה מאיטרציה 3 (פרמטר c, גוף -(c,3)), ומופעלת עם w3=6996, ומחזירה -(6996,3)=6993.break (ולא skip). לכן באיטרציה הראשונה (p עם גוף -(a,1)): Guard ראשון בודק zero?((p 2)) = zero?(-(2,1)) = zero?(1) = שקר — ממשיכים. Guard שני בודק zero?((p 12)) = zero?(-(12,1)) = zero?(11) = שקר — ממשיכים. Guard שלישי בודק zero?((p 200)) = zero?(-(200,1)) = שקר — ממשיכים. מבוצע גוף הלולאה: zero?((p 1)) = zero?(0) = אמת, לכן w1=7000. לאחר מכן ממשיכים לאיטרציה הבאה. לבסוף הלולאה מסתיימת ומחושב -(w1,w2) = -(7000,300) = 6700.Expression ::= event.create()
event-create-exp()Expression ::= <Identifier> += [ Expression ]+
event-add-exp(evt, procs)<Identifier>. מחזיר את ערך הארגומנט האחרון (המשתנה שרשמנו אליו). הדקדוק הנתון בשאלה — ניקוד יורד על אי ניתוח ומימוש נכון של הדקדוק, כלומר יש להפקיד על זיהוי וטיפול נכון ב- terminals, non-terminals ופעולות סגור ( ), { }*, { }+.(OnClick 50) מפעיל את כל הפרוצדורות הרשומות ל-OnClick עם הארגומנט 50.(dec_x 100) מורידה a ל-900. לאחר מכן (OnClick 50) מפעיל את dec_x שלוש פעמים עם 50, מוריד a ב-150, לכן a = 750... (ראה פרטים בדוגמה).const, כלומר לאחר קביעת ערכם, הם לא ניתנים לשינוי.let ומגדירים במסגרתו מתחדש בתוך הפרוצדורה, שבו הפעלת הפרוצדורה בתהליך ההפעלה מתווסף פרמטר הפרוצדורה לסביבה עמה מחשבים את גוף הפרוצדורה, ובה הוא מקבל את ערכו של הארגומנט הנשלח בביטויי ההפעלה.const, כלומר, רק אם המתכנת שהשתמש במתכונת המוגדרת בשפה יהיה כ-const אז לא ניתן יהיה לשנות את ערכו. אך אם לא היה שימוש באופציה של const אזי המשתנה ניתן לשינוי יותר.Expression ::= let option Identifier = Expression
in Expression
let-exp (opt id exp1 body)Expression ::= ( Expression option Expression )
call-exp (rator opt rand)option ::= ε | const
option היא הריקה, let-exp ו-call-exp מתנהגים כרגיל.option היא const:let-exp: לא ניתן יהיה לשנות את ערכו של id במסגרת ה-body של ה-let; אם יהיה ניסיון כזה יש להדפיס שגיאה מתאימה.call-exp: לפני הארגומנט הנשלח (rand) ניתן לציין את המילה const או לא לציין דבר; אם כן, לא ניתן יהיה לשנות את ערכו של פרמטר הפרוצדורה המופעלת במסגרת ביצוע גוף הפרוצדורה, וגם אם יהיה ניסיון שינוי שם יש להדפיס שגיאה מתאימה.value-of או כאלה המוטמעות בתוכו).w והוצהרה עבורו הגנה עד כך שהוא אמור לקבל תמיד ערך מספרי, אזי אם יהיה ניסיון לתת לו ערך שאינו מספרי (הפרה של ההגנה עליו) אזי תודפס הודעת שגיאה מתאימה ותיעצר ריצת התוכנית.let בו מגדירים משתנה ונותנים לו ערך.set-exp בו רוצים למשתנה קיים לשנות את ערכו הנוכחי לערך אחר.let-exp ושל ביטוי proc-exp לפי הדקדוקים הבאים:let-exp ו-proc-exp:Expression ::= let Guard Identifier = Expression
in Expression
let-exp (grd id exp1 body)
Expression ::= proc ( Guard Identifier ) Expression
proc-exp (grd var body)
Guard ::= ε | # | ? | @
Guard # — המציין שהמשתנה אמור להיות תמיד מספרי במהלך ריצת התוכנית.Guard ? — המציין שהמשתנה אמור להיות תמיד ערך בוליאני לאורך ריצת התוכנית.Guard @ — המציין שהמשתנה אמור להיות תמיד מסוג פרוצדורה (כלשהי) לאורך ריצת התוכנית.ε) ובמקרה כזה אין למשתנה כזה שום הגנה.let עם אפשרות לההגנה עליו.> (run "let # q = zero?(9)
in q")
guard-violation: expression #(struct:zero?-exp #(struct:const-exp 9)) violate let guard
>
q עם הגנה # עם ערך מספרי. מאחר ומנסים להציב לו ערך בוליאני המפר את ההגנה עליו, הודפסה הודעת שגיאה מתאימה.> (run "let @ q=proc (# w) -(w,1)
in
(q zero? (9))")
guard-violation: argument violate procedure bound variable w guard
>
q עם הגנה @ עם ערך מסוג פרוצדורה. ל-q אכן ניתנת פרוצדורה כערך. לפרוצדורה יש פרמטר w עם הגנה # עם ערך מספרי, בגוף ביטוי ה-let נעשית קריאה לפרוצדורה עם ארגומט w שאינו מספרי המפר את ההגנה עליו, ולכן התקבלה השגיאה.> (run "let # w = 8
in
set w = zero?(9)")
guard-violation: assign expression violate variable w guard
>
w עם הגנה # עם ערך מספרי, המשתנה אכן מקבל ערך מספרי של 8. לאחר מכן, יש ניסיון לשנותו לערך בוליאני המפר את ההגנה עליו, ולכן התקבלה הודעת השגיאה.> (run "let w = 8
in
begin
set w = zero?(9);
if w then 1 else 2
end")
(num-val 2)
>
w ללא שום הגנה, בתחילה ניתן למשתנה ערך מספרי של 8. לאחר מכן, הוצב במשתנה ערך אחר (בוליאני) — ואין כאן שום הפרה מאחר ואין שום הגנה.value-of או כאלה המוטמעות בתוכו).expression) לבין תוצאת חישוב ביטוי (expval) לבין identifier.)* או { }+).שאלות תרגול בשפות תכנות בנושא מצב ממבחנים של האוניברסיטה הפתוחה. השאלות ממוינות לפי רמת קושי, עם פתרונות לבדיקה עצמית - כך שניתן ללמוד מטעויות ולהבין את דרך הפתרון לפני הבחינה. ניתן לאתר שאלות חוזרות ולהריץ מבחני סימולציה ממוקדים בנושא מצב.