זוהי הפקודה prima-gencls שניתן להריץ בספק האירוח החינמי של OnWorks באמצעות אחת מתחנות העבודה המקוונות המרובות שלנו, כגון Ubuntu Online, Fedora Online, אמולטור מקוון של Windows או אמולטור מקוון של MAC OS
תָכְנִית:
שֵׁם
gencls - מהדר ממשק מחלקה עבור מודולי ליבה של Prima
תַקצִיר
gencls --h --inc --tml -O -I --depend --sayparent filename.cls
תיאור
יוצר כותרות עם פקודות מאקרו ומבנים C עבור הגדרות אובייקט מודול ליבה של Prima.
טיעונים
gencls מקבל את הטיעונים הבאים:
--h יוצר קובץ .h (עם הצהרות שייכללו בקובץ אחד או יותר)
-- Inc
יוצר קובץ .inc (עם הצהרות שייכללו בקובץ בלבד)
-O מפעיל את אלגוריתם האופטימיזציה עבור קבצי .inc. האלגוריתם מבוסס על הנחה,
שחלק מהפונקציות מוכרזות בצורה זהה, ולכן קטע הקוד שמטפל
ניתן לשתף את הפרמטר וההמרה של התוצאה. עם דגל "-O" על, גוף thunk הוא
מוחלף לקריאה לפונקציה, ששמה מורכב מכל פרמטרי השיטה
תוצאה פלוס. הפונקציה בפועל לא כתובה בקובץ .inc, אלא בקובץ tml. את כל
ניתן להסיר הצהרות כפולות מקבוצה של קבצי tml ולתזכורת
נכתב לקובץ אחד על ידי כלי השירות tmlink.
--tml
יוצר קובץ tml. מפעיל את "-O" באופן אוטומטי.
-Idirname
מוסיף ספריה לנתיב חיפוש, שבו כלי השירות מחפש קבצי cls. יכול להיות
צוין מספר פעמים.
--לִסְמוֹך
מדפיס תלות עבור קובץ נתון.
--הורה אומר
מדפיס את ההורה המיידי של כיתה בתוך קובץ נתון.
תחביר
בקצרה, ניתן לתאר את התחביר של קובץ cls באמצעות הסכמה הבאה:
[ הצהרות מסוג אפס או יותר ]
[ הצהרת מחלקה אפס או אחת ]
Gencls מייצר קובצי .h, .inc או .tml, עם שם בסיס של קובץ .cls, אם אין אובייקט או
שם החבילה ניתן, או עם שם האובייקט או החבילה אחרת.
בסיסי סקלר נתונים סוגים
ל-Gencls יש כמה סוגי נתונים סקלרים מובנים, שהיא יודעת להתמודד איתם. להתמודד'
פירושו שהוא יכול ליצור קוד שמעביר נתונים מסוגים אלה בין C ל-perl,
באמצעות ממשק ספריית XS (ראה perlguts).
הסוגים הם:
int
בול
ידית
לְהַכפִּיל
SV*
HV*
char *
מחרוזת (הצהרת C היא char[256] )
ישנם גם כמה סוגים מובנים נגזרים, שהם
ארוך
קצר
char
צֶבַע
U8
שמופו ל- int. הנתונים לא עוברים המרה ל-int בתהליך ההעברה, אבל זה
מאוחסן במקום ב-perl scalar באמצעות newSViv() פונקציה, אשר, בתורה, עלולה לאבד ביטים
או שלט.
נגזר נתונים סוגים
התחביר עבור הגדרת סוגי נתונים חדשים הוא כדלקמן:
היקף יכול להיות אחת משתי פרגמות, "גלובליות" או "מקומיות". הם מרמזים על שימוש בנתונים חדשים
סוג, האם הסוג ישמש רק עבור אובייקט אחד או יותר. השימוש ב"מקומי" הוא
דומה במקצת ל-C pragma static. כרגע ההבדל היחיד הוא שפונקציה
שימוש בסוג מקומי מורכב ברשימת הפרמטרים או כתוצאה מכך אינו נושא עבור
אופטימיזציה של "-O".
סקלר סוגים
ניתן לכנות סוגים סקלרים חדשים רק לקיימים, בעיקר עבור קידוד C
נוֹחוּת. ניתן להגדיר סוג סקלרי בשתי דרכים:
כינוי ישיר
תחביר:
$id => ;
דוגמא:
גלובלי $Handle => int;
מזהה הסוג החדש לא יהיה גלוי בקבצי C, אך הסוג יוחלף
כל קבצי cls הכוללים הגדרה זו.
מאקרו C
תחביר:
id1 id2
דוגמא:
Global API_HANDLE UV
קוד כזה יוצר הגדרת מאקרו C בקובץ כותרת .h בטופס
#define id1 id2
פקודות מאקרו C עם פרמטרים אינן מותרות. id1 ו-id2 אינם נדרשים להיות נוכחים
במרחב השמות cls, ולא מתבצעת החלפה במהלך עיבוד קבצי cls. זֶה
השימוש בפרגמה מוגבל מאוד.
מורכב סוגים
סוגי נתונים מורכבים יכולים להיות מערכים, מבנים ו-hash. הם יכולים להיות שילוב או א
וקטור של סוגי נתונים סקלאריים (אך לא מורכבים).
Gencls מאפשר מספר שילובים של סוגי נתונים מורכבים שאין בשפת C
לזהות. אלה יתוארו להלן.
סוגי נתונים מורכבים אינם מיובאים לקוד perl. מתכנת perl חייב להתאים ל
סוג הנתונים המשמש בעת העברת פרמטרים לפונקציה.
מערכים
תחביר:
@תְעוּדַת זֶהוּת [מֵמַד];
דוגמא:
העולמי @FillPattern U8[8];
דוגמה לפונקציות המשתמשות במערכים:
מערך * func( מערך a1, מערך * a2);
קוד Perl:
@ret = func(@array1, @array2);
שימו לב שלא נעשה שימוש בהפניות למערך, ומספר הפריטים בכל המערך
הפרמטרים חייבים להיות בדיוק כמו הממדים של המערכים.
הערה: ההצהרה הבאה לא תתבצע קומפילציה עם מהדר C, מכיוון ש-C לא יכול לחזור
מערכים. עם זאת, זה לא מטופל כשגיאה על ידי gencls:
מערך func();
סטרוקטורים
תחביר:
@id {
;
...
;
};
דוגמא:
גלובלי @Struc {
מספר int;
מזהה מחרוזת;
}
דוגמה לפונקציות המשתמשות במבנים:
Struc * func1( Struc a1, Struc * a2);
Struc func2( Struc a1, Struc * a2);
קוד Perl:
@ret = func1( @struc1, @struc2);
@ret = func2( @struc1, @struc2);
שים לב שלא נעשה שימוש בהפניות למערך, וגם מספר וסדר של פריטים בסך הכל
יש להגדיר את פרמטרי המערך בדיוק לפי הממדים והסדר של המבנים. מבנה
שמות שדות אינם בשימוש גם בקוד perl.
האש
תחביר:
%id {
;
...
;
};
דוגמא:
%Hash גלובלי {
מספר int;
מזהה מחרוזת;
}
דוגמה לפונקציות המשתמשות ב-hash:
Hash * func1( Hash a1, Hash * a2);
Hash func2( Hash a1, Hash * a2);
קוד Perl:
%ret = %{func1(\%hash1, \%hash2)};
%ret = %{func2(\%hash1, \%hash2)};
שימו לב שרק הפניות Hash משמשות ומוחזרות. כאשר מועבר hash מ-perl
קוד זה עשוי להיות חלק מהשדות או כולם לא מוגדרים. מבנה C מתמלא ומועבר ל-a
פונקציית C, והשדות שלא הוגדרו מוקצים למתאים
ערך C_TYPE_UNDEF, כאשר TYPE הוא אחד מיליוני NUMERIC, STRING ו-POINTER.
המרה לאחור לא נסמכת על הערכים האלה ותמיד מחזירה את כל מפתחות ה-hash עם a
זוג מתאים.
מרחב שמות סעיף
תחביר:
{
...
}
לקובץ cls יכול להיות אפס או מקטע מרחב שמות אחד, מלא בתיאורי פונקציות.
פונקציות המתוארות כאן ייצאו למזהה הנתון במהלך קוד האתחול. א
מרחב השמות יכול להיות "אובייקט" או "חבילה".
תחביר מרחב השמות של החבילה מאפשר רק הצהרה של פונקציות בתוך "חבילה"
לַחסוֹם.
חֲבִילָה {
...
}
תחביר מרחב השמות של האובייקט כולל משתנים ומאפיינים כמו גם פונקציות (
נקראות מתודות בתחביר האובייקט ). תחביר מרחב השמות הכללי של האובייקט הוא
לְהִתְנַגֵד [(זיהוי כיתה הורה)] {
}
בתוך מרחב שמות של אובייקט ניתן להשתמש בתחביר הירושה:
לְהִתְנַגֵד ( ) { ... }
או תיאור אובייקט שורש חשוף (ללא אב קדמון)
לְהִתְנַגֵד {...}
עבור הצהרת מחלקת האובייקט.
פונקציות
תחביר:
[ ] ( ) [ => ];
דוגמאות:
int package_func1( int a, int b = 1) => c_func_2;
Point package_func2( Struc * x, ...);
שיטה void object_func3 (פרופיל HV *);
נעשה שימוש בקידומת עם פונקציות אובייקט (שיטות) בלבד. עוד על הקידומת בשיטות
סָעִיף.
פונקציה לא יכולה להחזיר כלום ( void ), סקלארי (int, מחרוזת וכו') או קומפלקס (
array, hash ) סוג. זה גם יכול לקבל פרמטרים סקלרים ומורכבים, עם סוג
המרה התואמת את הכללים המתוארים לעיל ב"סוגי נתונים סקלרים בסיסיים"
סָעִיף.
אם לפונקציה יש פרמטרים ו/או תוצאה מסוג שלא ניתן להמיר
באופן אוטומטי בין C ל-perl, הוא מוצהר אך לא נחשף למרחב השמות של perl. ה
ניתנת אזהרה מתאימה. לא ניתן להשתמש בתחביר gencls כדי להכריז על a
פונקציה עם פרמטרים מותאמים אישית או נתוני תוצאות. לשם כך כתב ה-C המפורש
יש לבצע הצהרת קוד יחד עם קריאת "newXS".
דוגמה: אי אפשר להמיר אליפסיס (...) על ידי gencls, אולם מדובר ב-C חוקי
בְּנִיָה.
Point package_func2( Struc * x, ...);
לתחביר הפונקציה יש מספר תוספות נוחות:
ערכי ברירת מחדל של פרמטרים
דוגמא:
void func( int a = 15);
פונקציה שהוכרזה בצורה כזו יכולה להיקרא הן עם 0 או 1 פרמטרים. אם זה
נקרא עם 0 פרמטרים, ערך שלם של 15 ישמש אוטומטית. ה
תחביר מאפשר פרמטרים של ברירת מחדל עבור סוגי int, pointer ומחרוזת והסקלרי שלהם
כינויים.
פרמטרי ברירת המחדל יכולים להיות רבים ככל האפשר, אך הם חייבים להיות בסוף ה-
רשימת פרמטרים של פונקציות. ההצהרה "func( int a = 1, int b)" אינה נכונה.
כינוי
בקוד C שנוצר, יש לקרוא לפונקציה C לאחר שהפרמטרים בוצעו
מנותח. Gencls מצפה שפונקציה תואמת תהיה קיימת בקוד C, עם שם קבוע
ורשימת פרמטרים. עם זאת, אם המשימה של פונקציה כזו היא עטיפה זהה
פונקציה שפורסמה תחת שם אחר, ניתן לבצע כינוי כדי לשמור גם קוד וגם
מְהִירוּת.
דוגמא:
חבילה חבילה {
void func( int x) => internal;
}
פונקציה שהוכרזה בצורה כזו לא תקרא Package_func() פונקציה C, אבל
פְּנִימִי() לתפקד במקום. הבקשה היחידה היא זאת פְּנִימִי() לפונקציה חייבת להיות
פרמטר והצהרת תוצאה זהים ל-a פונק ().
Hash מוטבע
הומצאה דרך שימושית לקרוא לפונקציה עם hash כפרמטר מ-perl. אם
הפונקציה מוצהרת עם הפרמטר האחרון או הקלד "HV*", ולאחר מכן תרגום פרמטר
מ-perl ל-C מתבצע כאילו כל הפרמטרים שהועברו היו hash. האש הזה הוא
הועבר לפונקציה C והתוכן שלה הוחזר ואז חזרה ל-perl כ-hash שוב.
ניתן לשנות את תוכן הגיבוב בתוך הפונקציה C.
בהצהרה זו נעשה שימוש רב בבנאים, אשר קוד perl אופייני
sub init
{
שלי %ret = shift-> SUPER::init(@_);
...
החזר %ret;
}
וקוד C הוא בדרך כלל
void Obj_init (פרופיל HV *) {
init(פרופיל בירושה);
... [ שנה את תוכן הפרופיל ] ...
}
שיטות
שיטות הן פונקציות הנקראות בהקשר של אובייקט. כמעט כל השיטות צריכות
יש להם גישה לאובייקט שהם מתמודדים איתו. אובייקטים של פרימה נראים ב-C as
טיפול בסוג הנתונים. Handle כזה הוא למעשה מצביע למופע של אובייקט, שבתורו
מכיל מצביע לטבלת השיטות הווירטואליות של האובייקט (VMT). כדי להקל על OO-like
תחביר, פרמטר Handle זה כמעט ולא מוזכר בכל השיטות של אובייקט
תיאור בקובץ cls, למרות שהוא נספר במרומז, אז כל שיטה של cls
הכרזה
שיטה void a( int x)
עבור מחלקת אובייקט אובייקט משתקף ב-C as
void Object_a( Handle self, int x)
הצהרת פונקציה. בניגוד לפונקציות החבילה, ש-gencls אינו מסוגל לפרסם אם
זה לא מסוגל להתמודד עם הפרמטרים הנתמכים שאינם ניתנים להמרה, יש דרך לעשות זאת
להוציא הצהרה כזו עם שיטה. השימוש העיקרי לכך הוא שם השיטה מקבל
שמור ב-VMT של האובייקט.
שיטות נגישות בקוד C על ידי ייחוס השם הישיר של "עצמי ידית" בתור א
מבנה מתאים:
(((PSampleObject) self)-> self)-> sample_method( self, ...);
לשיטה יכולה להיות אחת משש קידומות השולטות ביצירת קוד C:
שיטה
זהו סוג השיטה הראשון והבסיסי ביותר. זה שם הקידומת, "שיטה" הוא
לכן נבחר כשם התיאורי ביותר. שיטות צפויות להיות מקודדות
C, ידית האובייקט היא מרומזת ואינה נכללת בתיאור cls.
שיטה void a()
תוצאות ב
void Object_a( ידית עצמית)
הצהרת ג. שיטה שפורסמה ממירה אוטומטית את הפרמטרים והתוצאה שלה
בין C ל-perl.
ציבורי
כאשר השיטות שיש להן פרמטרים ו/או תוצאה שלא יכולה להיות אוטומטית
צריך להצהיר על המרה בין C ל-perl, או שהצהרת הפונקציה לא
מתאים לתחביר C, נעשה שימוש בקידומת "ציבורי". השיטות המוצהרות עם "ציבור" היא
צפוי לתקשר עם perl באמצעות ממשק XS (ראה perlxs). זה גם
ציפיתי ששיטה "ציבורית" יוצרת גם פונקציות REDEFINED וגם FROMPERL (ראה
Prima::internals לפרטים). דוגמאות רבות בכל מקור פרימה, ורצון
לא יוצג כאן. לשיטות "ציבוריות" יש בדרך כלל תוצאה בטלה וללא פרמטרים, אבל
זה לא משנה הרבה, מכיוון ש-gencls לא מייצר המרה לשיטות כאלה.
לייבא
עבור השיטות שלא הגיוני לקוד ב-C אבל במקום זאת ב-perl, gencls יכולים להיות
נאמר לייצר את העטיפות המתאימות באמצעות הקידומת "ייבוא". סוג זה של א
ניתן לראות בשיטה "שיטה" מבפנים החוצה. פונקציית "ייבוא" אינה זקוקה ל-C
מקביל, למעט הקוד שנוצר אוטומטית.
סטטי
אם שיטה צריכה להיות מסוגלת לעבוד גם עם ובלי מופע אובייקט, היא צריכה
יש להוסיף קידומת "סטטית". שיטות "סטטיות" הן כולן דומות לשיטות "שיטה",
אלא שהפרמטר הראשון של "Handle self" אינו מוצהר באופן מרומז. אם "סטטי"
מתודה נקראת ללא אובייקט (אבל עם מחלקה), כמו
Class::Object-> static_method();
הפרמטר הראשון שלו אינו אובייקט אלא מחרוזת "Class::Object". אם שיטה אף פעם
עוסק בחפץ, די להשתמש בהצהרה שלו כ
static a( char * className = "");
אבל אם כן, א
static a( SV * class_or_object = nil);
יש צורך בהצהרה. במקרה האחרון קוד C עצמו צריך לקבוע מה בדיוק יש
עברו, אם בכלל. שימו לב לפרמטר ברירת המחדל כאן: שיטה "סטטית" היא בדרך כלל
קריא להתקשר בתור
Class::Object::static_method();
שבו לא מועברים אליו פרמטרים. ללא פרמטר ברירת המחדל קריאה כזו
יוצר שגיאת זמן ריצה 'לא מספיק פרמטרים עברו'.
משונה
לא מצאנו שם טוב יותר עבורו. קידומת "מוזר" מציינת שיטה ששילבה
מאפיינים הן מ"סטטי" והן מ"ציבורי". במילים אחרות, gencls מייצר לא
קוד המרה ולא מצפה ל"Handle self" כפרמטר ראשון לשיטה כזו.
כדוגמה ניתן לתאר Prima::Image::load, אשר ניתן לקרוא לו באמצעות רחב
ספקטרום של סמנטיקה של שיחות (ראה Prima::image-load לפרטים).
ג_בלבד
כפי ששמה מציין, "c_only" היא שיטה שקיימת ב-VMT אבל לא
נגיש מ-perl. ניתן להעמיס עליו מ-C בלבד. יתרה מכך, מותר
רשום פונקציית perl עם שם של שיטה "c_only", ועדיין ישויות אלה
יהיו עצמאיים לחלוטין זה מזה - העומס לא יתרחש.
הערה: שיטות שיש להן סוגי נתונים של תוצאות ו/או פרמטרים שלא ניתן להמיר
באופן אוטומטי, שנה את הקידומת שלהם ל-"c_only". כנראה שזו התנהגות לא נכונה,
ומצב כזה צריך לאותת על שגיאה.
פרויקטים
ערכת הכלים של Prima מציגה ישות בשם מאפיין, שצפויה להחליף את השיטה
זוגות שתפקידם לרכוש ולהקצות משתנה אובייקט פנימי כלשהו, למשל,
שם אובייקט, צבע וכו'. במקום זוג שיטות כמו Object::set_color ו
Object::get_color, מאפיין Object::color נוצר. נכס היא שיטה עם ה
שיקולים מיוחדים, בפרט, כאשר הוא נקרא ללא פרמטרים, מצב 'קבל'
משתמע. להיפך, אם הוא נקרא עם פרמטר אחד, מצב 'סט' מופעל.
שים לב שגם בקריאת 'הגדר' וגם ב'קבל' הפרמטר המרומז הראשון הוא "טיפול עצמי".
נוכח תמיד.
מאפיינים יכולים לפעול עם כמות שונה, אך קבועה של פרמטרים, ולבצע 'סט'
ופונקציות 'קבל' רק עבור אחת. כברירת מחדל, הפרמטר היחיד הוא "הידית
עצמי":
נכס char * שם
יש מקביל C
char * Object_name( Handle self, Bool set, char * name)
בהתאם למצב, "Bool set" הוא "true" או "false". במצב 'סט' קוד C
התוצאה נמחקת, במצב 'קבל' ערך הפרמטר אינו מוגדר.
התחביר למאפיין מרובה פרמטרים הוא
מאפיין ארוך פיקסל( int x, int y);
וקוד C
long Object_pixel( ידית עצמית, Bool set, int x, int y, פיקסל ארוך)
שימו לב שבמקרה של ריבוי פרמטרים הפרמטרים המוצהרים אחרי שם המאפיין הם
תמיד מאותחל, הן במצב 'קבע' והן במצב 'קבל'.
מופע משתנים
כל חפץ מאופיין במצבו הפנימי הייחודי. תחביר Gencls מאפשר א
הצהרת משתנה, עבור משתנים המוקצים לכל מופע אובייקט. למרות ש
אימות סוג נתונים לא מתבצע עבור משתנים, וההצהרות שלהם פשוט מתקבלות
שהועתקו 'כמות שהם', הצהרות C מורכבות הכוללות מצביעי מערך, מבנה ופונקציה
לא מזוהה. כדרך לעקיפת הבעיה, נעשה שימוש במצביעים ליישויות מסוג def'd. דוגמא:
object SampleObject {
int x;
רשימה רשימה;
struct { int x } s; # הצהרה בלתי חוקית
}
משתנים נגישים בקוד C על ידי הפניית שם ישיר של "עצמי ידית" בתור א
מבנה מתאים:
((PSampleObject) self)-> x;
מחברים
דמיטרי קראסיק,[מוגן בדוא"ל]>. אנטון ברזין,[מוגן בדוא"ל]>.
השתמש ב-prima-gencls באופן מקוון באמצעות שירותי onworks.net