| NICKLE(1) | General Commands Manual | NICKLE(1) |
نام (NAME)
nickle - یک زبان ماشینحساب رومیزی
خلاصه دستور (SYNOPSIS)
nickle [--help|--usage] [-f file] [-l library] [-e expr] [-V] [ script ] [--] [arg ...]
توضیحات (DESCRIPTION)
Nickle یک زبان ماشینحساب رومیزی با قابلیتهای قدرتمند برنامهنویسی و اسکریپتنویسی است. Nickle از انواع گوناگون دادهها، بهویژه اعداد صحیح با دقت دلخواه، اعداد گویا و اعداد حقیقی با دقت تقریبی پشتیبانی میکند. زبان ورودی تا حدودی شبیه به C است. برخی از موارد در C که تطبیق آنها ساده نبوده متفاوت هستند، برخی تصمیمهای طراحی به شکل دیگری گرفته شدهاند، و تعداد بسیار اندکی از قابلیتها به سادگی حذف شدهاند.
نحوه استفاده (USAGE)
یک آرگومان بدون گزینه (بدون پرچم) به عنوان یک اسکریپت Nickle در نظر گرفته میشود و جایگزین ورودی استاندارد میگردد. هر آرگومان باقیمانده پس از اسکریپت، برای بررسی برنامهنویسی در آرایه رشتهای argv در Nickle قرار میگیرد. هنگامی که برنامه بدون هیچ عبارت یا آرگومان اسکریپتی فراخوانی شود، Nickle از ورودی استاندارد میخواند و در خروجی استاندارد مینویسد.
گزینهها به شرح زیر هستند:
- --help,--usage
- چاپ پیام راهنما/نحوه استفاده و خروج. این یک قابلیت داخلی در ماژول ParseArgs برنامه Nickle است و بنابراین برای اسکریپتهای Nickle که از این کتابخانه استفاده میکنند نیز صادق خواهد بود.
- -f,--file file
- بارگذاری file در Nickle پیش از آغاز اجرا.
- -l,--library library
- بارگذاری library در Nickle پیش از آغاز اجرا. برای شرح قابلیت کتابخانه به بخشهای زیر مراجعه کنید.
- -e,--expr expr
- ارزیابی expr پیش از آغاز اجرا.
- -V,--version
- چاپ نسخه Nickle و خروج.
- --
- پایان تجزیه آرگومانها و ارسال باقیمانده آنها بدون ارزیابی به argv.
سینتکس (SYNTAX)
برای کاربردیتر کردن زبان ورودی در یک محیط تعاملی، newline دستورات را تنها در زمانهای «معقول» خاتمه میدهد. Newline عبارات یا تکدستورهای تایپشده توسط کاربر را خاتمه میدهد (به استثنای چند دستور که نیازمند پیشنگری هستند: بهویژه ()if و ()twixt که دارای بخش اختیاری else هستند). در داخل دستورهای مرکب یا تعاریف توابع، فقط یک ; دستورات را خاتمه میدهد. این رویکرد مناسب است و به نظر نمیرسد در استفاده عادی مشکلی ایجاد کند.
سینتکس برنامههای Nickle به شرح زیر است. در این توضیحات، name نشاندهنده هر دنبالهای از حروف، ارقام و نویسههای _ است که با رقم شروع نمیشود؛ E نشاندهنده هر عبارت؛ S نشاندهنده هر دستور؛ و T نشاندهنده هر نوع است. سینتکس X,X,...,X نشاندهنده یک یا چند X جداشده با ویرگول است، مگر اینکه طور دیگری مشخص شده باشد.
کامنتها (Comments):
کامنتهای سبک C در /* و */ محصور میشوند، و کامنتهای سبک شل با یک # در ابتدای خط مشخص میگردند.
عملوندها (Operands):
- عدد حقیقی (real number)
- میتواند شامل توان باشد، اما نیازی به ممیز اعشاری یا علامت ندارد. به عنوان اعداد گویای دقیق در نظر گرفته میشوند. اگر بخش اعشاری پایانی شامل یک آکولاد باز باشد، آکولاد بدون خطا نادیده گرفته میشود؛ اگر شامل یک بخش پایانی درون آکولاد باشد، به عنوان یک عدد اعشاری متناوب در نظر گرفته میشود. ثابتهای «ممیز شناور» در حال حاضر در ساختار داخلی به عنوان اعداد گویا نمایش داده میشوند: برای ثابتهای ممیز شناور با یک دقت معین (و یک توان با دقت نامحدود)، از تابع داخلی ()imprecise که در ادامه توضیح داده شده است استفاده کنید.
- عدد هشتهشتی (octal number)
- با 0 شروع میشود (برای مثال، 014 همان 12 است).
- عدد شانزدهشانزدهی (hexadecimal number)
- با "0x" شروع میشود (برای مثال، 0x1a همان 26 است).
- رشته (string)
- مانند C. ثابتهای رشتهای درون گیومه جفتی قرار میگیرند. نویسههای دارای بکاسلش (از جمله گیومهها) نشاندهنده خودشان هستند، به جز "\n" که نشاندهنده خط جدید، "\r" برای بازگشت به ابتدای سطر، "\b" برای پسبر، "\t" برای تب و "\f" برای صفحه جدید است.
- name
- یک ارجاع به متغیر.
- name() name(E,E,...,E)
- یک فراخوانی تابع با صفر یا چند آرگومان. توابع کاملاً فراخوانی با مقدار (call-by-value) هستند: آرایهها و ساختارها کپی میشوند، به جای آنکه مانند C به آنها ارجاع داده شود.
- desc name T name = value
- عبارات تعریف: یک نام جدید در دسترس قرار میگیرد، به طوری که در فرم دوم مقدار تعریف برابر با مقدار مقداردهی اولیه است، و در فرم اول مقداردهی نشده است. توصیفگر desc اختیاری نیست: از هر ترکیبی از دیدپذیری (visibility)، کلاس حافظه (storage class) یا نوع (type) (به همان ترتیب) تشکیل شده است. برای شرح این توصیفکنندهها به QUALIFIERS در ادامه مراجعه کنید. عبارت مقدار ساختاریافته نیز امکانپذیر است: به VALUES در زیر مراجعه کنید.
- علاوه بر
امکان
مقداردهی
اولیه یک
تعریف با یک
مقدار Nickle،
تعاریف
آرایه،
ساختار و
اجتماع (union) به
سبک C نیز
مجاز هستند:
برای مثال،
موارد زیر
int[*,*] name = {{0,1},{2,3}} int[2,2] name = {{0...}...}با معنای مشخص مجاز هستند. این همان زمینهای است که در آن ابعاد موجود در یک نوع ممکن است عبارت باشند: به بحث انواع آرایه در بالا مراجعه کنید. برای سینتکس مقداردهی اولیه آرایهها و ساختارها، به بحث مقادیر آرایه و ساختار مراجعه کنید.
یک اعلان یا تعریف ممکن است مانند C، با توصیفکنندهها مشخص شود تا جزئیات رفتار برنامهنویسی را تعیین کند. برخلاف C، این توصیفکنندهها اگرچه اختیاری هستند، اما باید به همان ترتیب ذکرشده ظاهر شوند.
دیدپذیری (Visibility):
- public
- هر عبارت تعریفی (تعریف تابع، تعریف متغیر، تعریف نوع) میتواند با public مشخص شود تا نشان دهد نامی که تعریف میشود باید در خارج از فضای نام (namespace) فعلی قابل مشاهده باشد و باید بهطور خودکار وارد (import) شود. برای اطلاعات بیشتر، بخش Namespaces را در ادامه ببینید.
- protected
- هر عبارت تعریفی (تعریف تابع، تعریف متغیر، تعریف نوع) میتواند با protected مشخص شود تا نشان دهد نامی که تعریف میشود باید در خارج از فضای نام فعلی قابل مشاهده باشد، اما نباید از طریق اعلانهای import در دسترس قرار گیرد. برای اطلاعات بیشتر، بخش Namespaces را در ادامه ببینید.
طول عمر (Lifetime):
- auto
- یک شیء auto مختص به یک بلوک مشخص است: طول عمر آن حداقل برابر با طول عمر آن بلوک است. یک شیء auto دارای مقداردهی اولیه، هر بار که ارزیابی شود مجدداً مقداردهی اولیه خواهد شد. این، طول عمر پیشفرض برای اشیاء محلی است.
- static
- یک شیء static مختص به تعریف یک تابع مشخص است: طول عمر آن حداقل به اندازه طول عمر آن تعریف است. هر بار که تعریف تابعِ دربرگیرنده آن ارزیابی شود، یک شیء static جدید ایجاد خواهد شد.
- در Nickle، کلیدواژه static فقط با طول عمر سر و کار دارد (مانند استفاده از static درون توابع C)، نه با دیدپذیری (که همانطور که در بالا توضیح داده شد توسط توصیفکنندههای مجزا مدیریت میشود، برخلاف استفاده از static در حوزه سراسری در C).
- global
- یک شیء global در کل برنامه سراسری است: طول عمر آن برابر با طول عمر برنامه است. یک شیء global هنگام مشاهده اولیه تعریف آن ایجاد و مقداردهی اولیه میشود. این طول عمر پیشفرض برای اشیاء سراسری است.
- تمایز میان طول عمر static و global در Nickle، در C امکانپذیر نیست؛ چرا که توابع در C اشیاء درجه یک (first class) با حوزه تودرتو نیستند. هنگام تصمیمگیری درباره اینکه از کدامیک در یک برنامه Nickle استفاده کنید، به این فکر کنید که در صورت ارزیابی مجدد یک تعریف چه اتفاقی باید بیفتد.
عملگرها (OPERATORS)
عملگرهای پایهای Nickle در ادامه آمده است که به ترتیب اولویت نزولی گروهبندی شدهاند:
- A[E,E,...,E]
- به عنصر E-اُم از عبارت آرایهای A، یا عنصر E1-اُم/E2-اُم/غیره از یک آرایه چندبُعدی اشاره دارد. هم آرایهای از آرایهها به سبک C و هم آرایههای چندبُعدی به سبک NAWK امکانپذیر هستند.
- struct.tag
- ارجاع به عضو ساختار (Structure dereference).
- struct->tag
- ارجاع به عضو اشارهگر ساختار به سبک C.
- =============
- ++ --
- افزایش/کاهش یکانی. میتواند پسوندی یا پیشوندی باشد.
- -
- منفیساز یکانی.
- ! E
- نقیض منطقی.
- E !
- فاکتوریل. به یک آرگومان عدد صحیح غیرمنفی نیاز دارد.
- * E
- باز ارجاع اشارهگر (Pointer dereference).
- & E
- ساخت مرجع (Reference construction).
- =============
- (U) E
- ساخت مقداری از نوع union با برچسب U و مقدار E.
- =============
- **
- توانرسانی. هر دو عملوند میتوانند کسری باشند. عملوند سمت چپ باید غیرمنفی باشد مگر اینکه عملوند سمت راست عدد صحیح باشد. نوع نتیجه در صورتی که عملوند سمت راست عدد صحیح باشد، نوع عملوند سمت چپ است، و در غیر این صورت real خواهد بود.
- این تنها
ویژگی با
نوع ناامن
(type-unsound)
شناختهشده
در Nickle است:
عبارتی
مانند 2 ** -3 به
صورت ایستا
از نوع integer
خواهد بود،
اما به صورت
پویا
مقداری از
نوع rational تولید
میکند. این
امر ممکن
است بعداً
باعث خطای
نوع در زمان
اجرا شود؛
در نظر
بگیرید:
int x = 2 ** -3;
- =============
- * / // %
- ضرب،
تقسیم،
تقسیم
صحیح، و
باقیمانده.
عملوند سمت
راست سه
عملگر آخر
باید
غیرصفر
باشد. نوع
نتیجه
عملگر
تقسیم
همواره
حداقل rational
خواهد بود:
نوع نتیجه
عملگر
تقسیم صحیح
همواره int
خواهد بود.
این یک
تفاوت قابل
توجه با C
است که در
آن تقسیم
عدد صحیح
توسط
عملوندهای
عدد صحیح به
طور ضمنی
تعیین
میشود.
تقسیم صحیح
به این صورت
تعریف
میشود:
x // y == y > 0 ? floor (x / y) : ceil(x / y)
باقیمانده همواره غیرمنفی است و به این صورت تعریف میشود:
x % y = x - (x // y) * y
- =============
- + -
- جمع و تفریق.
- =============
- << >>
- شیفت بیتی
به چپ و
راست با
عملوندهای
عدد صحیح.
عملوندهای
سمت راستِ
منفی طبق
انتظار کار
میکنند.
این
عملگرها به
صورت زیر
تعریف
میشوند:
x << y = x * 2 ** y
x >> y = x // 2 ** y
دیدگاه دیگر برای نگاه به این موضوع این است که عملوندهای سمت چپِ منفی در یک نمایش مکمل دو بینهایت در نظر گرفته میشوند (یعنی بیت علامت تا بینهایت گسترش یافته است)، که در آن شیفت به راست علامتِ عملوند سمت چپ خود را گسترش میدهد (sign-extending). - =============
- <= >= < >
- عملگرهای رابطهای.
- =============
- == !=
- عملگرهای برابری.
- =============
- در نهایت، به ترتیب اولویت نزولی:
- &
- عملگر AND بیتی. عملوندهای منفی در یک نمایش مکمل دو بینهایت در نظر گرفته میشوند (یعنی بیت علامت تا بینهایت گسترش یافته است).
- ^
- عملگر XOR بیتی. عملوندهای منفی همانند AND بیتی هستند.
- |
- عملگر OR بیتی. عملوندهای منفی همانند AND بیتی هستند.
- &&
- عملگر AND منطقی مدارکوتاه (Short-circuit).
- ||
- عملگر OR منطقی مدارکوتاه (Short-circuit).
- E ? E : E
- عبارت شرطی: اگر عبارت نخست از نظر منطقی درست (true) باشد، مقدار آن عبارت دوم است، در غیر این صورت عبارت سوم.
- fork E
- ایجاد (و بازگرداندن) یک ریسه (thread). برای جزئیات به بخش Thread در ادامه مراجعه کنید.
- = += -= *= /= //= %= **= <<= >>= ^= &= |=
- عملگرهای انتساب. سمت چپ باید قابل انتساب باشد. x <op>= y معادل است با x = x <op> y
- E , E
- عبارت سمت راست را بازمیگرداند.
نحو اعلان نوع در Nickle بیش از نحو C، به گونهٔ “چپ” نحو Java شباهت دارد. اساساً، یک نوع داده شامل موارد زیر است:
- poly integer rational real string continuation void
- یک نوع پایه در زبان. نوع void در واقع تنها در زمینههای خاصی قابل استفاده است، بهویژه در بازگشتیهای تابع. این نوع در حال حاضر همانند ML بهصورت نوع “unit” پیادهسازی شده و از این رو رفتاری کمی متفاوت نسبت به C دارد. نوع poly ابرنوع (supertype) تمام انواع دیگر است (به این معنی که میتوان از آن برای غیرفعال کردن بررسی نوع ایستا استفاده کرد)، و در بیشتر مواردی که نیازی به ذکر صریح نوع نیست، نوع پیشفرض محسوب میشود.
- file semaphore thread
- همچنین انواع پایهٔ توکار هستند، اما بخش لاینفک ADTهای File و Thread میباشند: بخش زیر را ببینید.
اطلاعات بیشتر درباره انواع:
Nickle از دادههای چندریختی (polymorphic) پشتیبانی میکند: با ارزیابی یک عبارت، یک نوع داده متناسب با نتیجه انتخاب میشود. هر شیء در Nickle میتواند دارای نوع ایستا باشد، که در این صورت نقض محدودهها در زمان کامپایل بهعنوان خطا مشخص خواهد شد. متغیرها و توابع چندریختی محدودیتی بر روی نوع دادهٔ تخصیصیافته اعمال نمیکنند؛ این نوعِ پیشفرض برای تمام اشیاء است.
- poly
- این نوع، اجتماع تمام انواع داده را توصیف میکند. متغیری با این نوع میتواند شامل هر مقدار دادهای باشد.
- int
- اعداد صحیح با دقت دلخواه.
- rational
- اعداد گویا با دقت دلخواه.
- real
- اعداد ممیز شناور با دقت توان دلخواه. از آنجا که بسیاری از محاسبات را نمیتوان دقیقاً بهصورت اعداد گویا انجام داد، Nickle محاسبات غیردقیق را با استفاده از نمایش مستقل از ماشین خود برای اعداد ممیز شناور پیادهسازی میکند. تابع توکار imprecise(n) یک عدد real با ۲۵۶ بیت دقت از عدد n تولید میکند، در حالی که imprecise(n,p) یک عدد real با p بیت دقت تولید مینماید.
- T[]
- یک آرایه از نوع T، با یک یا چند بعد. هیچ آرایهٔ صفر بعدی در Nickle وجود ندارد.
- T[*]
- یک آرایهٔ یکبعدی از نوع T. برخلاف C، بعد یک آرایه در Nickle هرگز بخشی از نوع آن محسوب نمیشود. علاوه بر این، در Nickle آرایهها و اشارهگرها انواع نامرتبط هستند.
- T[*,*,...,*]
- یک آرایهٔ دو یا چندبعدی از نوع T. ستارههای “*” اختیاری نیستند. همانطور که در بندهای پیشین روشن شد، “T[]” یک آرایهٔ صفر بعدی نیست.
- T[E,E,...,E]
- در زمینههای تعریف، میتوان مقادیر صحیحی را برای هر بعد در یک زمینهٔ آرایه مشخص کرد. این مقادیر صرفاً به منظور ایجاد مقدار هستند و بخشی از نوع محسوب نمیشوند. نوع یک آرایه تنها بر اساس نوع پایه و تعداد ابعاد آرایه تعیین میشود.
- T0() T0(T,T,...,T)
- تابعی که نوع T0 را برمیگرداند. یک تابع ۰ یا چند آرگومان میپذیرد.
- T0() T0(T,T,...,T ...)
- تابعی که صفر یا چند آرگومان الزامی، به همراه تعداد دلخواهی از آرگومانهای اختیاری را میپذیرد. دومین توالی سهنقطه جزئی از نحو است و نه فرانحو: برای جزئیات به توضیحات توابع varargs مراجعه کنید.
- *T
- یک اشارهگر به مکانی از نوع T. حساب اشارهگرها در Nickle تنها بر روی اشارهگرهای به آرایهها عمل میکند: اشارهگر باید از نوع صحیح باشد و هرگز نباید از محدوده خارج شود. یک اشارهگر میتواند به مکانی اشاره کند یا تهی (0 یا null) باشد. مانند C، اولویت “*” کمتر از اولویت “[]” یا “()” است: در صورت نیاز از پرانتز استفاده کنید.
- struct {T name; T name; ...}
- یک ساختار با فیلدهایی از نام و نوع دادهشده. انواع T اختیاری هستند: در صورت عدم وجود آنها، نوع فیلد poly خواهد بود.
- union {T name; T name; ...}
- یک “اجتماع مجزا” (disjoint union) از انواع دادهشده. این ساختار بیشتر به نوع رکورد متغیر در Pascal یا datatype در ML شباهت دارد تا نوع union در C: نامها برچسبهایی از نوع مشخصشده هستند که در هر زمان دقیقاً یکی از آنها برای یک مقدار معین صدق میکند.
- (T)
- پرانتز برای گروهبندی.
دستور Typedef:
مانند C،
نامهای
نوع جدید را
میتوان با
دستور typedef
ایجاد کرد.
نحو آن به
این صورت
است:
typedef T typename;
که در آن T یک
نوع در Nickle است.
typename حاصل
میتواند
در هر جایی
که انتظار
یک نوع
میرود
استفاده
شود.
مقادیر (VALUES)
مقادیر انواع پایه در Nickle مطابق انتظار هستند. نحو ثوابت را در بالا ببینید. مقادیر از نوع file، semaphore و continuation در حال حاضر تنها از طریق فراخوانی توابع توکار قابل ایجاد هستند: هیچ ثابتی از این انواع در Nickle وجود ندارد.
همانطور که در بخش TYPES در بالا اشاره شد، Nickle چندین نوع “مقدار ساختیافته” دارد: آرایهها، توابع، اشارهگرها، ساختارها و اجتماعهای مجزا. همهٔ این موارد دارای برخی ویژگیهای مشترک هستند. هنگام ایجاد، تمام مقادیر سازندهٔ آنها مقداردهینشده هستند (مگر اینکه خلاف آن مشخص شده باشد). تلاش برای استفاده از یک مقدار مقداردهینشده منجر به خطای زمان کامپایل یا استثنای زمان اجرا خواهد شد.
آرایهها (Arrays):
- [E]
- یک آرایه (مبتنی بر صفر) با E عنصر ایجاد میکند. E باید نامنفی باشد.
- [E]{V,V,...,V}
- یک آرایه با E عنصر ایجاد میکند که با مقادیر V مقداردهی اولیه شدهاند. اگر تعداد مقادیر اولیه خیلی کم باشد، عناصر باقیمانده مقداردهینشده باقی خواهند ماند.
- [E]{V,V,...,V...}
- سهنقطهٔ دوم جزئی از نحو است، نه فرانحو. یک آرایه با E عنصر ایجاد میکند. عناصر ابتدایی آرایه مطابق با مقادیر V مقداردهی اولیه میشوند، و عناصر باقیمانده همان مقدار آخرین V را دریافت میکنند. این نحو را میتوان به روشی مشابه با هر یک از مقداردهیهای اولیهٔ آرایه در زیر به کار برد.
- [*]{V,V,...,V}
- یک آرایهٔ مقداردهیشده دقیقاً با همان تعداد عنصری که مقادیر اولیه داده شده است ایجاد میکند. باید حداقل یک مقدار اولیه وجود داشته باشد.
- [E,E,...,E] [*,*,...,*]
- آرایههای چندبعدی ایجاد میکند. عبارتهای صحیح و "*" را نمیتوان ترکیب کرد: ابعاد یک آرایه در تعریف بهطور کامل یا مشخص شدهاند یا نامشخص. این آرایهها را میتوان بهصورت مقداردهیشده نیز ایجاد کرد: برای نحو مقداردهی اولیه به بند بعدی مراجعه کنید.
- (T[E]) (T[E,E,...,E]) (T[E]){E,E,...,E}
- (T[E,E,...,E]){{E,...},...,{E,...}}
- نحو جایگزین برای ایجاد آرایههایی از نوع T. مقادیر اولیه در آکولاد اختیاری هستند. تعداد مقادیر اولیه باید کمتر یا مساوی با تعداد عناصر دادهشده در هر بعد باشد. برای آرایههای چندبعدی، آکولادهای اضافی به ازای هر بعد در مقداردهی اولیه الزامی هستند؛ این برخلاف C است که در آن اختیاری میباشند.
- (T[*]){E,E,...,E} (T[*,*,...,*]){{E,...},...,{E,...}}
- آرایههایی از نوع T ایجاد میکند، به طوری که اندازهٔ هر بعد با حداکثر تعداد مقادیر اولیه در هر زیرآرایه در آن بعد تعیین میشود.
اشارهگرها (Pointers):
- 0
- اشارهگر تهی (null)، در زمینههایی که اشارهگر مورد نیاز است.
- &V &A[E,E,...,E] &S.N
- اشارهگری به متغیر، عنصر آرایه یا عضو ساختار دادهشده ایجاد میکند. نوع اشارهگر *T خواهد بود، که در آن T نوع شیء اشارهشده است.
- *P
- مقداری که اشارهگر P به آن اشاره میکند. این مقدار را میتوان همانند C مشاهده یا اصلاح کرد.
توابع (Functions):
- (T func(){S;S;...S;}) (T func(T name,T name,...T name){S;S;...S;})
- عبارت تابع: بیانگر تابعی با صفر یا چند پارامتر صوری با انواع و نامهای دادهشده است که نوع نتیجهٔ مشخصشده را برمیگرداند. بدنهٔ تابع با فهرستی از دستورات محصور در آکولاد مشخص میشود. تمام انواع اختیاری هستند و بهطور پیشفرض poly در نظر گرفته میشوند. همانطور که در بالا اشاره شد، توابع کاملاً فراخوانی با مقدار (call-by-value) هستند: بهویژه، آرایهها و ساختارها کپی میشوند و ارجاع داده نمیشوند.
- T function name(T name,T name,...,T name){S;S;...S;}
- تابعی با
صفر یا چند
آرگومان
تعریف
میکند. شکر
نحوی (Syntactic sugar)
برای:
T(T,T,...T) name = (T func(T name,T name,...T name){S;S;...S;});
- T function name(T name, T name ...)
- سهنقطه در اینجا نحو است، نه فرانحو: اگر پس از آخرین آرگومان صوری یک تابع سه نقطه بیاید، میتوان تابع را با آرگومانهای واقعی بیشتری نسبت به آرگومانهای صوری فراخوانی کرد. تمام آرگومانهای واقعی “اضافی” در آرایهٔ صوری با نام دادهشده بستهبندی میشوند، و در برابر نوع اختیاری T آخرین آرگومان (پیشفرض poly) بررسی نوع میشوند.
ساختارها (Structures):
- (struct { T name; T name; ...T name; }){name = E; name = E; ...name=E;}
- مقداری از یک نوع ساختاریافته ایجاد میکند. فیلدهای نامگذاریشده با مقادیر دادهشده مقداردهی اولیه میشوند و باقی موارد مقداردهینشده میمانند. همانطور که مشخص شده است، مقداردهی اولیه بر اساس برچسب انجام میگیرد، نه موقعیتی مانند C.
اجتماعها (Unions): .IP (union { T name; T name; ...T name; }.name) E مقدار جدیدی از نوع union دادهشده با گونهٔ مشخصشده توسط .name و مقدار تعیینشده با E ایجاد میکند. نوع E باید با name سازگار باشد.
دستورها (STATEMENTS)
نحو دستورها بسیار شبیه به زبان C است. برخی نحوهای اضافی برای پشتیبانی از قابلیتهای تکمیلی Nickle اضافه شدهاند.
- E;
- عبارت را ارزیابی میکند.
- {S ... S}
- دستورهای محصورشده را به ترتیب اجرا میکند.
- if (E) S
- شرطی پایه.
- if (E) S
- اجرای شرطی.
- else S
- دستور else با نحو و معناشناسی معمول مجاز است. بهطور ویژه، یک else به نزدیکترین if() یا twixt() معتبر پیش از خود متصل میشود.
- while (E) S
- حلقهٔ while به سبک C.
- do S while (E);
- حلقهٔ do به سبک C.
- for (opt-E; opt-E; opt-E) S
- حلقهٔ for به سبک C.
- switch (E) { case E: S-list case E: S-list ... default: S-list }
- دستور case به سبک C. نیازی نیست که عبارتهای case عبارتهای ثابت باشند، بلکه میتوانند دلخواه باشند. اولین case که با آرگومان switch برابر ارزیابی شود انتخاب میشود؛ در غیر این صورت اگر default موجود باشد اجرا میگردد، وگرنه از بدنهٔ switch صرفنظر میشود.
- twixt(opt-E; opt-E) S
- twixt(opt-E; opt-E) S else S
- اگر عبارت آرگومان اول برابر با درستی (true) ارزیابی شود، بدنهٔ twixt() و سپس عبارت آرگومان دوم ارزیابی خواهند شد. اگر عبارت آرگومان اول نادرست (false) ارزیابی شود، دستور else در صورت وجود اجرا خواهد شد. در غیر این صورت، از کل دستور twixt() صرفنظر میشود.
دستور twixt() تضمین میکند که همهٔ این رویدادها به ترتیب مشخصشده رخ خواهند داد، صرفنظر از نحوهٔ ورود (از بیرون) به twixt() یا خروج از آن، شامل استثناها، continuationها و break. (با بند “finally” در Java مقایسه کنید.)
- try S;
- try S catch name (T name, ...) { S; ... };
- try S catch name (T name, ...) { S; ... } ... ;
- دستور اول S را اجرا میکند. اگر در حین اجرا استثنایی رخ دهد و نام آن با نام موجود در یک بلوک catch همخوانی داشته باشد، پارامترهای صوری در بلوک catch به پارامترهای واقعی استثنا مقید شده و بدنهٔ بلوک catch اجرا میشود. برای هر try میتواند چندین بلوک catch وجود داشته باشد. صفر بلوک catch گرچه معتبر است، اما عملاً بیفایده است. پس از اتمام یک بلوک catch، ادامهٔ اجرا بعد از عبارت try پی گرفته میشود. همانند else، یک catch به نزدیکترین بلوک try-catch معتبر متصل میشود.
- raise name(name, name, ..., name)
- ایجاد استثنای نامبرده با صفر یا چند آرگومان.
- ;
- دستور پوچ (null statement).
- break;
- توقف اجرای نزدیکترین دستور محصورکنندهٔ for/do/while/switch/twixt. هنگام خروج از دستور twixt، عبارت خروج (leave) اجرا خواهد شد.
- continue;
- انشعاب مستقیم به آزمون شرطیِ نزدیکترین دستور محصورکنندهٔ for/do/while.
- return E;
- بازگرداندن مقدار E از نزدیکترین تابع محصورکننده.
فضاهای نام (Namespaces):
همانند Java و C++، زبان Nickle نیز مفهومی از namespace (فضای نام) دارد؛ مجموعهای از نامها با دامنهٔ دید نسبتاً محدودشده. در Nickle، فضاهای نام با دستور namespace ایجاد میشوند.
- opt-P namespace N { S ... }
- تمام نامهای تعریفشده در دستورهای S را درون یک فضای نام با نام N قرار میدهد. توصیفکنندهٔ اختیاری P میتواند کلیدواژهٔ public باشد، اما توجه داشته باشید: این صرفاً نشان میدهد که خودِ نام N در جاهای دیگرِ حوزهٔ فعلی قابل مشاهده است و هیچ ارتباطی با دیدهشدن موارد درون فضای نام ندارد.
- extend namespace N { S ... }
- فضای نام N دادهشده را مجدداً باز میکند و آن را با نامهایی که بهصورت public در دستورهای S تعریف شدهاند گسترش میدهد.
- نامهای
تعریفشده
در داخل
فضای نام در
بیرون از آن
نامرئی
هستند، مگر
اینکه با
کلیدواژهٔ
public توصیف شده
باشند.
نامهای public
را میتوان
با استفاده
از
نمادگذاری
مسیر ارجاع
داد:
namespace::namespace::...::namespace::name
به نام دادهشده که درون مجموعهٔ فضاهای نام مشخصشده تعریف گردیده، اشاره میکند. نحو دونقطه-دوتایی ناخوشایند است، چرا که معنای آن اندکی با C++ تفاوت دارد، اما تمام نمادهای مناسب پیشتر استفاده شده بودند و این یک ویژگی مثبت تلقی میشود که جداکنندهٔ فضای نام از لحاظ نحوی با عملگر ساختار تفاوت دارد. برای مثال در Java، عبارت
name.name.name
از نظر نحوی مبهم است: نام میانی میتواند یک ساختار یا یک فضای نام باشد. - import N;
- نام N باید به یک فضای نام اشاره کند: تمام نامهای public در این فضای نام به حوزهٔ فعلی وارد میشوند (و نامهای دارای تداخل را از حوزه خارج میکنند).
توابع درونی (BUILTINS)
Nickle مجموعهای از توابع استانداردِ توکار دارد. برخی از این توابع در C نوشته شدهاند، اما بسیاری از آنها با Nickle نوشته شدهاند. چندین مجموعه از توابع دارای انواع دادههای درونیِ مرتبط هستند: فضاهای نام آنها، به همراه انواع دادهشان، باید به عنوان ADT (انواع داده انتزاعی) در نظر گرفته شوند.
توابع درونی سطح بالا (Top-Level Builtins):
- int printf(string fmt, poly args...)
- تابع File::fprintf(stdout, fmt, args ...) را فراخوانی کرده و نتیجهٔ آن را بازمیگرداند.
- string function gets ()
- تابع File::fgets(stdin) را فراخوانی کرده و نتیجهٔ آن را بازمیگرداند.
- string function scanf (string fmt, *poly args...)
- تابع File::vfscanf(stdin, fmt, args) را فراخوانی کرده و نتیجهٔ آن را بازمیگرداند.
- string function vscanf (string fmt, (*poly)[*] args)
- تابع File::vfscanf(stdin, fmt, args) را فراخوانی کرده و نتیجهٔ آن را بازمیگرداند.
- real imprecise(rational value)
- به توضیحات مربوط به نوع real در بالا مراجعه کنید.
- real imprecise(rational value, int prec)
- به توضیحات مربوط به نوع real در بالا مراجعه کنید.
- int string_to_integer(string s)
- int atoi(string s)
- آرگومان s یک رشتهٔ رقمی علامتدار است، و نتیجه عدد صحیحی است که بازنمایی میکند. اگر رشتهٔ s از نظر نحوی یک ثابت شانزدهشانزدهی (hexadecimal)، هشتهشتی (octal)، دودویی (binary) یا صراحتاً در مبنای ۱۰ باشد، با آن همانگونه رفتار میشود.
- int string_to_integer(string s, int base)
- int atoi(string s, int base)
- با s به عنوان رشتهای از ارقام در مبنای دادهشده رفتار میکند. مبنای 0 همانند حالتی است که آرگومان مبنا مشخص نشده باشد. در غیر این صورت، نحو مشخصکنندهٔ مبنا درون رشته نادیده گرفته میشود.
- int putchar(int c)
- نویسهٔ دادهشده را با استفاده از File::putc(c, stdout) در خروجی استاندارد قرار میدهد و نتیجهٔ آن را بازمیگرداند.
- int sleep(int msecs)
- تلاش میکند تا ریسهٔ (thread) فعلی را حداقل برای msecs میلیثانیه معلق کند. در صورت بازگشت زودهنگام 1 و در غیر این صورت 0 بازمیگرداند.
- int exit(int status)
- خروج از Nickle با کد وضعیت دادهشده. هیچ مقداری بازنمیگرداند.
- int dim(poly[*] a)
- با دریافت یک آرایهٔ یکبعدی a، تابع dim() تعداد عناصر a را بازمیگرداند.
- int[] dims(poly[] a)
- با دریافت یک آرایهٔ دلخواه a، تابع dims() آرایهای از اعداد صحیح بازمیگرداند که اندازهٔ هر بعد a را مشخص میکند. بنابراین، dim(dims(a)) تعداد ابعاد a است.
- *poly reference(poly v)
- با دریافت یک مقدار دلخواه v، آن مقدار را در حافظه «جعبهبندی» (box) کرده و اشارهگری به آن جعبه بازمیگرداند.
- rational string_to_real(string s)
- rational atof(string s)
- رشتهٔ ثابت حقیقی s را به عدد حقیقی مرتبط با آن تبدیل میکند.
- number abs(real v)
- قدر مطلق v را بازمیگرداند. نوع نتیجهٔ انتخابشده با زمینهٔ دادهشده مطابقت خواهد داشت.
- int floor(real v)
- بزرگترین عدد صحیح کوچکتر یا مساوی با v را بازمیگرداند. اگر v یک real باشد و دقت بسیار پایین باشد، این عملیات با شکست مواجه میشود.
- int ceil(real v)
- کوچکترین عدد صحیح بزرگتر یا مساوی با v را بازمیگرداند. اگر v یک real باشد و دقت بسیار پایین باشد، این عملیات با شکست مواجه میشود.
- int exponent(real v)
- نما (توان) عدد حقیقی نادقیق v را بازمیگرداند.
- rational mantissa(real v)
- مانتیس عدد حقیقی نادقیق v را به صورت یک کسر گویای m با شرط 0 <= m <= 0.5 بازمیگرداند.
- int numerator(rational v)
- صورت عدد گویای v را بازمیگرداند: یعنی اگر در شکل تحویلناپذیر v = n/d باشد، مقدار n را بازمیگرداند.
- int denominator(rational v)
- مخرج عدد گویای v را بازمیگرداند: یعنی اگر در شکل تحویلناپذیر v = n/d باشد، مقدار d را بازمیگرداند.
- int precision(real v)
- تعداد بیتهای دقت مانتیس عدد حقیقی نادقیق v را بازمیگرداند..IP "int sign(real v)" بسته به منفی یا نامنفی بودن v، مقدار -1 یا 1 را برمیگرداند.
- int bit_width(int v)
- تعداد بیتهای مورد نیاز برای نمایش داخلی abs(v) را برمیگرداند.
- int is_int(poly v)
- مسند نوع (Type predicate).
- int is_rational(poly v)
- مسندهای نوع عددی جامع هستند: برای نمونه is_rational(1) مقدار 1 را برمیگرداند.
- int is_number(poly v)
- مسند نوع.
- int is_string(poly v)
- مسند نوع.
- int is_file(poly v)
- مسند نوع.
- int is_thread(poly v)
- مسند نوع.
- int is_semaphore(poly v)
- مسند نوع.
- int is_continuation(poly v)
- مسند نوع.
- int is_array(poly v)
- مسند نوع.
- int is_ref(poly v)
- مسند نوع: نوع اشارهگر را بررسی میکند. این مورد احتمالاً یک ویژگی نامناسب (misfeature) است و ممکن است تغییر کند.
- int is_struct(poly v)
- مسند نوع.
- int is_func(poly v)
- مسند نوع.
- int is_void(poly v)
- مسند نوع.
- int gcd(int p, int q)
- بزرگترین مقسومعلیه مشترک (GCD) دو عدد p و q را برمیگرداند. نتیجه همواره مثبت است.
- int xor(int a, int b)
- مقدار a ^ b را برمیگرداند. این مورد بیشتر یادگاری از دوران پیش از افزودهشدن عملگر xor به Nickle است.
- poly setjmp(continuation *c, poly retval)
- توابع اولیهٔ setjmp() و longjmp() به همراه نوع continuation یک نوع دادهٔ انتزاعی (ADT) را تشکیل میدهند که برای انتقالهای تقریباً دلخواه در جریان کنترل کاربرد دارد. توابع توکار setjmp() و longjmp() مشابه همتایان خود در C هستند، با این تفاوت که محدودیت پرش رو به بالای همیشگی longjmp() برداشته شده است(!): یک continuation ذخیرهشده از طریق setjmp() در طول حیات برنامه هرگز نامعتبر نمیشود.
- تابع توکار setjmp() مکان و بافت جاری را در آرگومان اشارهگر continuation خود ذخیره کرده و سپس آرگومان دومش را برمیگرداند.
- void longjmp(continuation c, poly retval)
- تابع توکار longjmp() هرگز به محل فراخوانی بازنمیگردد، بلکه از همان setjmp() که continuation را ایجاد کرده بود بازمیگردد و مقدار بازگشتی آن برابر با آرگومان دوم longjmp() خواهد بود.
- string prompt
- اعلانی (prompt) که هنگام استفادهٔ تعاملی در سطح بالا (top-level) چاپ میشود. پیشفرض "> ". هنگام انتظار برای بقیهٔ یک دستور یا عبارت، و هنگام اشکالزدایی بهترتیب. مقادیر پیشفرض "> "، "+ " و "- " هستند.
- string prompt2
- اعلانی که هنگام استفادهٔ تعاملی و در هنگام انتظار برای ادامهٔ یک دستور یا عبارت چاپ میشود. پیشفرض "+ ".
- string prompt3
- اعلانی که هنگام استفادهٔ تعاملی و در زمان اشکالزدایی چاپ میشود. پیشفرض "- ".
- string format
- قالببندی printf() برای چاپ مقادیر سطح بالا. پیشفرض "%g".
- string version
- شماره نسخهٔ پیادهسازی Nickle که در حال حاضر در حال اجرا است.
- string build
- تاریخ ساخت پیادهسازی Nickle در حال اجرا به صورت "yyyy/mm/dd"، یا در صورتی که تاریخ ساخت به هر دلیلی نامشخص باشد، علامت "?".
- file stdin
- متصل به جریان ورودی استاندارد.
- file stdout
- متصل به جریان خروجی استاندارد.
- file stderr
- متصل به جریان خطای استاندارد.
استثناها (Exceptions):
تعدادی استثنای استاندارد بهطور پیشفرض اعلان شدهاند و در درون Nickle مورد استفاده قرار میگیرند.
- exception uninitialized_value(string msg)
- تلاش برای استفاده از یک مقدار مقداردهینشده.
- exception invalid_argument(string msg, int arg, poly val)
- آرگومان شمارهٔ arg در یک تابع توکار، مقدار نامعتبر val را داشته است.
- exception readonly_box(string msg, poly val)
- تلاش برای تغییر مقدار یک کمیت فقطخواندنی به val.
- exception invalid_array_bounds(string msg, poly a, poly i)
- تلاش برای دسترسی به آرایهٔ a در نمایهٔ خارج از محدودهٔ i.
- exception divide_by_zero(string msg, real num, real den)
- تلاش برای تقسیم num بر den در شرایطی که den == 0 باشد.
- exception invalid_struct_member(string msg, poly struct, string name)
- تلاش برای ارجاع به عضو name از شیء struct، در حالی که این عضو وجود ندارد.
- exception invalid_binop_values(string msg, poly arg1, poly arg2)
- تلاش برای ارزیابی یک عملگر دودویی با آرگومانهای arg1 و arg2، در حالی که حداقل یکی از این مقادیر نامعتبر است.
- exception invalid_unop_values(string msg, poly arg)
- تلاش برای ارزیابی یک عملگر یکانی با آرگومان نامعتبر arg.
فضاهای نام توکار (Builtin Namespaces):
- Math
- توابع ریاضی موجود در فضای نام Math به شیوهای پیادهسازی شدهاند که با کتابخانهٔ C سازگار باشند. لطفاً برای جزئیات بیشتر به راهنماهای مناسب مراجعه کنید.
- real pi
- ثابت غیردقیق نشاندهندهٔ نسبت محیط به قطر دایره با دقت پیشفرض ۲۵۶ بیت.
- protected real e
- ثابت غیردقیق نشاندهندهٔ پایهٔ لگاریتم طبیعی با دقت پیشفرض ۲۵۶ بیت. از آنجا که e حفاظتشده (protected) است، باید از طریق Math::e مورد ارجاع قرار گیرد تا از بروز تداخل با پنجمین حرف الفبا در سطح بالا (top level) جلوگیری شود.
- real function sqrt(real v)
- ریشهٔ دوم (جذر) v را برمیگرداند.
- real function cbrt(real v)
- ریشهٔ سوم (کعب) v را برمیگرداند.
- real function exp(real v)
- مقدار e**v را برمیگرداند.
- real function log(real a)
- مقدار v را چنان برمیگرداند که e**v == a باشد. اگر a نامثبت باشد، یک استثنای invalid_argument پرتاب میکند.
- real function log10(real a)
- مقدار v را چنان برمیگرداند که 10**v == a باشد. اگر a نامثبت باشد، یک استثنای invalid_argument پرتاب میکند.
- real function log2(real a)
- مقدار v را چنان برمیگرداند که 2**v == a باشد. اگر a نامثبت باشد، یک استثنای invalid_argument پرتاب میکند.
- real function pi_value(int prec)
- نسبت محیط به قطر دایره را با prec بیت دقت برمیگرداند.
- real function sin(real a)
- نسبت ضلع مقابل به وتر زاویهٔ a در یک مثلث قائمالزاویه را برحسب رادیان برمیگرداند.
- real function cos(real a)
- نسبت ضلع مجاور به وتر زاویهٔ a در یک مثلث قائمالزاویه را برحسب رادیان برمیگرداند.
- void function sin_cos(real a, *real sinp, *real cosp)
- مقادیر sin(a) و cos(a) را بهترتیب در مکانهای اشارهشده توسط sinp و cosp ذخیره میکند. اگر هر یک از اشارهگرها 0 باشد، مقداری در آن مکان ذخیره نمیشود. ممکن است اندکی سریعتر از فراخوانی جداگانهٔ هر دو تابع مثلثاتی باشد.
- real function tan(real a)
- نسبت ضلع مقابل به مجاور زاویهٔ a در یک مثلث قائمالزاویه را برحسب رادیان برمیگرداند. توجه داشته باشید که tan(pi/2) در حال حاضر خطا نیست: بلکه بسته به دقت ورودی، عدد بسیار بزرگی را برمیگرداند.
- real function asin(real v)
- مقدار a را چنان برمیگرداند که sin(a) == v باشد.
- real function acos(real v)
- مقدار a را چنان برمیگرداند که cos(a) == v باشد.
- real function atan(real v)
- مقدار a را چنان برمیگرداند که tan(a) == v باشد.
- real function atan2(real x, y)
- مقدار a را چنان برمیگرداند که tan(a) == x / y باشد. با وضعیت y == 0 بهدرستی رفتار میکند.
- real function pow(real a, real b)
- پیادهسازی عملگر **.
- File
- فضای نام File عملیاتهای مربوط به مقادیر پرونده را فراهم میکند.
- int function fprintf(file f, string s, ....)
- مقادیر قالببندیشده را همانند تابع fprintf() کتابخانهٔ stdio یونیکس درون یک فایل چاپ میکند. توابع fprintf() و printf() زیرمجموعهٔ معقولی از نسخهٔ کتابخانهٔ stdio را میپذیرند: %c، %d، %e، %x، %o، %f، %s و %g مطابق انتظار کار میکنند؛ همچنین %v برای چاپ هوشمند مقدار عمل میکند. اصلاحکنندههای قالببندی ممکن است بین علامت درصد و نویسهٔ قالب قرار گیرند تا قالببندی را تغییر دهند. باگهای شناختهشدهٔ زیادی در رابطه با قالببندی ورودی و خروجی وجود دارد.
نویسههای قالببندی (Format Letters): .IP %c به یک آرگومان عدد صحیح کوچک (0..255) نیاز دارد و آن را به عنوان یک نویسه ASCII قالببندی میکند.
- %d
- به یک آرگومان عدد صحیح نیاز دارد و آن را به صورت یک عدد صحیح قالببندی میکند.
- %x
- به یک آرگومان عدد صحیح نیاز دارد و آن را به صورت یک عدد صحیح در مبنای ۱۶ (هگزادسیمال) قالببندی میکند.
- %o
- به یک آرگومان عدد صحیح نیاز دارد و آن را به صورت یک عدد صحیح در مبنای ۸ (اکتال) قالببندی میکند.
- %e
- به یک آرگومان عددی نیاز دارد و آن را در نماد علمی قالببندی میکند.
- %f
- به یک آرگومان عددی نیاز دارد و آن را در نماد ممیز ثابت قالببندی میکند.
- %s
- به یک آرگومان رشتهای نیاز دارد و رشته را عیناً درج میکند.
- %g
- به یک عدد نیاز دارد و تلاش میکند نمایشی دقیق و خوانا را برای قالببندی آن برگزیند.
تغییردهندههای قالب:
- digits
- تمام نویسههای قالب یک تغییردهنده قالب عدد صحیح میپذیرند که نشاندهنده تعداد فاصلههای خالی در میدان قالب برای دادهٔ در حال قالببندی است. مقدار در این فضا به صورت راستچین چاپ خواهد شد.
- digits.digits
- قالبهای اعداد حقیقی یک جفت تغییردهنده قالب عدد صحیح میپذیرند که پهنای میدان و دقت (تعداد نویسههای پس از ممیز اعشار) مقدار قالببندیشده را مشخص میکنند. هر یک از این دو عدد صحیح را میتوان حذف کرد.
- -
- یک مقدار دقت که نشاندهنده دقت بینهایت است.
- *
- آرگومان بعدی fprintf() یک عدد صحیح است که پهنای میدان یا دقت مقدار قالببندیشده را تعیین میکند.
- file function string_write()
- فایلی را بازمیگرداند که مقادیر نوشتهشده را در یک رشته جمعآوری میکند.
- int function close(file f)
- فایل f را میبندد و نشانهای از موفقیتآمیز بودن عملیات بازمیگرداند.
- int function flush(file f)
- بافرهای فایل f را تخلیه (flush) کرده و نشانهای از موفقیتآمیز بودن بازمیگرداند.
- int function getc(file f)
- نویسه بعدی را از فایل f دریافت کرده و آن را بازمیگرداند.
- int function end(file f)
- در صورتی که فایل f در انتهای فایل (EOF) باشد مقدار true، و در غیر این صورت false بازمیگرداند.
- int function error(file f)
- در صورتی که خطایی روی فایل f در انتظار باشد مقدار true، و در غیر این صورت false بازمیگرداند.
- int function clear_error(file f)
- خطاهای در انتظار روی فایل f را پاک کرده و نشانهای از موفقیتآمیز بودن بازمیگرداند.
- file function string_read(string s)
- یک فایل مجازی بازمیگرداند که محتویات آن رشته s است.
- string function string_string(file f)
- رشتهای را که پیشتر در فایل f نوشته شده بازمیگرداند؛ این فایل باید توسط string_read() یا string_write() ایجاد شده باشد. رفتار روی سایر فایلها در حال حاضر تعریفنشده است.
- file function open(string path, string mode)
- فایل موجود در مسیر path دادهشده را با رشته حالت mode مشخصشده، مشابه fopen() در UNIX stdio، باز میکند. حالتهای مجاز همانند stdio عبارتند از: "r"، "w"، "x"، "r+"، "w+" و "x+".
- integer function fputc(integer c, file f)
- نویسه c را به فایل خروجی f میفرستد و نشانهای از موفقیتآمیز بودن بازمیگرداند.
- integer function ungetc(integer c, file f)
- نویسه c را مجدداً به درون فایل ورودی f برمیگرداند و نشانهای از موفقیتآمیز بودن بازمیگرداند.
- integer function setbuf(file f, integer n)
- اندازه بافر مرتبط با فایل f را روی n تنظیم کرده و n را بازمیگرداند.
- string function fgets (file f)
- یک خط ورودی از فایل f دریافت کرده و رشته حاصل را بازمیگرداند.
- file function pipe(string path, string[*] argv, string mode)
- برنامه موجود در مسیر path مشخصشده را راهاندازی میکند و فایلی را بازمیگرداند که یک سر pipe به فرایند مذکور است. آرگومان mode میتواند برای خواندن از pipe برابر "r" یا برای نوشتن در آن برابر "w" باشد. آرگومان argv آرایهای از رشتهها شامل آرگومانهایی است که به برنامه ارسال میشوند؛ طبق قرارداد، argv[0] نام برنامه است.
- int function print (file f, poly v, string fmt, int base, int width, int prec, string fill)
- مقدار v را در فایل f با قالب fmt و با مقادیر مشخصشده base، width، prec و fill چاپ میکند. به صورت داخلی توسط File::fprintf() استفاده میشود.
- int function fscanf(file f, string fmt, *poly args...)
- مکانهای اشارهشده توسط آرایه args را با مقادیر خواندهشده از فایل f با توجه به رشته fmt پر میکند. مشخصکنندههای قالب بسیار شبیه به scanf() در UNIX stdio هستند: مشخصکنندههای "%d"، "%e"، "%f"، "%c" و "%s" با تغییردهندههای مورد انتظار پشتیبانی میشوند.
- int function vfscanf (file f, string fmt, (*poly)[*] args)
- با دریافت فایل f، قالب fmt، و آرایه آرگومانهای args، عملیات fscanf() را به شکل مناسب انجام میدهد.
- Thread
- فضای نام Thread از عملیات مختلفی که برای برنامهنویسی با threads (نخها) مفید است پشتیبانی میکند؛ نخها جریان کنترل همروند را در فضای آدرس مشترک فراهم میکنند. یک ساختار دستوری ویژه مرتبط با نخها وجود دارد.
- fork(E)
- یک عبارت دلخواه را میپذیرد و آن را در یک نخ فرزند جدید ارزیابی میکند. نخ والد، نخ جدید را به عنوان مقدار حاصل از عبارت fork دریافت میکند.
- سایر توابع Thread نسبتاً استاندارد هستند.
- int function kill(thread list...)
- تمام نخهای در حال اجرا در آرایه list را متوقف میکند. بدون آرگومان، نخ در حال اجرای فعلی را متوقف میکند. تعداد نخهای متوقفشده را بازمیگرداند.
- int function trace(poly list...)
- وضعیت تمام نخهای در حال اجرا در آرایه list را نمایش میدهد. بدون آرگومان، تداوم پیشفرض (default continuation) را ردگیری میکند. تعداد نخهای ردگیریشده را بازمیگرداند.
- int function cont()
- اجرای هر یک از نخهای دچار وقفه شده را ادامه میدهد و تعداد نخهای ادامهیافته را بازمیگرداند.
- thread function current()
- نخ جاری را بازمیگرداند.
- int function list()
- نخهای در حال اجرای فعلی را در stdout گزارش میدهد.
- int function get_priority(thread t)
- اولویت نخ دادهشده t را گزارش میدهد.
- thread function id_to_thread(int id)
- نخ دارای id مشخصشده را در صورت پیدا شدن بازمیگرداند، و در غیر این صورت 0 را بازمیگرداند.
- poly function join(thread t)
- منتظر پایان یافتن نخ t میماند و هر آنچه را که آن نخ بازگرداند بازمیگرداند.
- int function set_priority(thread t, int i)
- تلاش میکند اولویت نخ t را روی سطح i تنظیم کند و اولویت جدید را بازمیگرداند. اولویتهای بزرگتر به معنای زمان اجرای بیشتر هستند: وظیفهای با اولویت بالاتر همیشه به جای وظیفهای با اولویت پایینتر اجرا خواهد شد. نخهایی با بالاترین اولویت برابر، به صورت قبضهکردنی (pre-emptively) چندوظیفهای اجرا خواهند شد.
- Semaphore
- فضای نام Semaphore عملیات مربوط به نوع داده انتزاعی توکار (built-in ADT) سمافور را کپسولهسازی میکند. یک سمافور برای همگامسازی نخها به کار میرود. هر عملیات signal() روی سمافور، قدیمیترین نخی را که روی آن سمافور در انتظار wait() بوده است بیدار میکند. مقدار “count” (شمارش) فرایندهای منتظر را میتوان در زمان ایجاد سمافور مشخص کرد.
- semaphore function new(int c)
- یک سمافور جدید با شمارش اولیه c از فرایندهای منتظر ایجاد میکند. اگر c مثبت باشد، بدین معناست که c نخ میتوانند روی سمافور منتظر بمانند پیش از آنکه نخی مسدود شود. اگر c منفی باشد، تعداد نخهایی را تعیین میکند که باید روی سمافور در انتظار باشند تا انتظارهای بعدی مسدود نشوند.
- semaphore function new()
- تابع semaphore(0) را فراخوانی کرده و نتیجه آن را بازمیگرداند.
- int signal(semaphore s)
- سمافور s را یکی افزایش میدهد. اگر s نامثبت باشد و نخی روی s مسدود شده باشد، قدیمیترین نخ مسدودشده را آزاد میکند. در صورت موفقیت 1 بازمیگرداند.
- int wait(semaphore s)
- سمافور s را یکی کاهش میدهد. اگر s منفی باشد، تا زمان آزاد شدن مسدود میشود. در صورت موفقیت 1 بازمیگرداند.
- int test(semaphore s)
- بررسی میکند که آیا اجرای wait() روی سمافور s باعث مسدود شدن نخ جاری میشود یا خیر. اگر چنین باشد 0 بازمیگرداند؛ در غیر این صورت، تلاش میکند s را کاهش دهد و در صورت موفقیت 1 بازمیگرداند.
- String
- فضای نام String شامل چند عملیات پایهای روی ADT رشته است.
- int function length(string s)
- تعداد نویسههای s را بازمیگرداند.
- string function new(int c)
- تکنویسه c را به صورت یک رشته بازمیگرداند.
- string function new(int cv[*])
- رشتهای متشکل از نویسههای cv را بازمیگرداند.
- int function index(string t, string p)
- شاخص (اندیس) عدد صحیح رشته الگوی p را در رشته هدف t بازمیگرداند، یا در صورتی که p زیررشتهای از t نباشد، -1 بازمیگرداند.
- string function substr(string s, int i, int l)
- زیررشتهای از رشته s را بازمیگرداند که از نویسه در آفست i (مبتنی بر صفر) شروع شده و در مجموع به طول l نویسه ادامه مییابد. اگر l منفی باشد، زیررشته به جای نویسههای پس از i، از نویسههای پیش از آن تشکیل خواهد شد.
- PRNG
- فضای نام PRNG امکان تولید و کار با اعداد شبهتصادفی را فراهم میکند. تولیدکننده اصلی، تولیدکننده رمز دنبالهای RC4 با مقداردهی اولیه مناسب (bootstrapped) است. این تولیدکننده جریانی از بیتهای شبهتصادفی امن از نظر رمزنگاری را با هزینه سرشکنشدهٔ معقول فراهم میکند. (اما توجه داشته باشید، مقداردهی اولیه تا حدی پرهزینه است.).IP "void function srandom(int s)" تولیدکننده را با استفاده از عدد صحیح (بهطور دلخواه بزرگ) به عنوان مقدار اولیه (seed) مقداردهی اولیه میکند.
- void function dev_srandom(int nbits)
- تولیدکننده را با استفاده از nbits بیت آنتروپی دریافتشده از یک منبع آنتروپی مناسب مقداردهی اولیه میکند. در سیستمهای UNIX، این منبع /dev/urandom است. درخواست آنتروپی اولیه بیش از آنچه سیستم در اختیار دارد، ممکن است یا به راهاندازی اولیه (مانند UNIX) یا به قفلشدن سیستم بینجامد، بنابراین با احتیاط استفاده کنید.
- int function randbits(int n)
- یک عدد شبهتصادفی n-بیتی در محدودهٔ 0..(2**n)-1 برمیگرداند. برای مواردی مانند RSA کاربردی است.
- int function randint(int n)
- یک عدد شبهتصادفی در محدودهٔ 0..n-1 برمیگرداند.
- void function shuffle(*(poly[*]) a)
- یک بُر زدن واقعی، کارآمد و درجا (ر.ک. کنوت) را روی آرایهٔ a انجام میدهد.
- Command
- فضاینام Command توسط دستورهای سطح بالا همانگونه که در زیر شرح داده شده، استفاده میشود. همچنین گهگاه بهخودیخود نیز مفید است.
- string library_path
- شامل مسیر جستجوی فعلی کتابخانههاست؛ فهرستی از دایرکتوریهای جداشده با دونقطه (colon) که برای یافتن فایلهای کتابخانه جستجو میشوند.
- int function undefine(string name)
- دستور سطح بالای undefine را پیادهسازی میکند. نام مشخصشده توسط رشتهٔ name را از فضاینام حذف میکند. این کار تمام تعریفهای قابلمشاهده از این نام را حذف میکند.
- int function undefine(string[*] names)
- تکتک نامهای موجود در آرایهٔ names را از فضاینام حذف میکند. این کار تمام تعریفهای قابلمشاهده از هر نام را حذف میکند.
- int function delete(string name)
- تلاش میکند دستور با نام رشتهای name دادهشده را از فهرست دستورهای سطح بالا حذف کند و در صورت موفقیت 1 برمیگرداند.
- int function lex_file(string path)
- تلاش میکند فایل موجود در path دادهشده را به منبع فعلی کدهای Nickle تبدیل کند و در صورت موفقیت 1 برمیگرداند. توجه داشته باشید که این کار عملاً با قرار دادن فایل بر روی پشتهای از فایلهای در حال پردازش، آن را درج (include) میکند.
- int function lex_library(string filename)
- مانند lex_file() عمل میکند، اما دایرکتوریهای مشخصشده توسط متغیر library_path را برای نخستین فایل با filename دادهشده جستجو میکند.
- int function lex_string(string code)
- تلاش میکند کد Nickle موجود در رشتهٔ code را ورودی بعدی قرار دهد.
- int function edit(string[*] names)
- دستور سطح بالای edit را پیادهسازی میکند. نامهای موجود در آرایه، مسیری از نامهای فضاینام هستند که به نام نماد (که آخرین مورد است) ختم میشوند.
- int function new(string name, poly func)
- تابع func را به رشتهٔ name دستور سطح بالا پیوند میدهد: یعنی آن را بخشی از واژگان دستورات سطح بالا میسازد.
- int function new_names(string name, poly func)
- تابع func را به رشتهٔ name دستور سطح بالا پیوند میدهد: یعنی آن را بخشی از واژگان دستورات سطح بالا میسازد. برخلاف new()، نامهای رشتهای که در سطح بالا به func داده میشوند بهصورت ارزیابینشده به عنوان یک آرایه از نامهای رشتهای یا به عنوان یک نام رشتهای منفرد ارسال میشوند.
- int function pretty_print(file f, string[*] names)
- دستور سطح بالای print را پیادهسازی میکند. هر یک از رشتههای نام ارسالشده جستجو شده و کد مربوطه در فایل f چاپ میشود.
- int function display(string fmt, poly val)
- از printf() برای نمایش مقدار val در قالب fmt استفاده میکند.
- History
- Nickle تاریخچهای از مقادیر سطح بالا را نگه میدارد که هنگام محاسبات به عنوان مکملی برای ویرایش در خط فرمان کاربردی است. فضاینام History شامل توابعی برای دسترسی به این تاریخچه است.
- int function show(string fmt)
- دستور سطح بالای history را بدون آرگومان پیادهسازی میکند. تازهترین مقادیر تاریخچه را با قالب fmt نمایش میدهد.
- int function show(string fmt, int count)
- دستور سطح بالای history را با یک آرگومان پیادهسازی میکند. آخرین count مقدار از تاریخچه را با قالب fmt نمایش میدهد.
- int function show(string fmt, int first, int last)
- دستور سطح بالای history را با دو آرگومان پیادهسازی میکند.
- poly function insert(poly val)
- مقدار val را در فهرست تاریخچه درج کرده و آن را برمیگرداند.
- Environ
- بسیاری از سیستمهای عامل مفهومی به نام «متغیرهای محیطی» دارند. فضاینام Environ شامل توابعی برای دستکاری آنهاست.
- int function check(string name)
- اگر متغیری با name دادهشده در محیط وجود داشته باشد 1 و در غیر این صورت 0 برمیگرداند.
- string function get(string name)
- تلاش میکند مقدار متغیر محیطی با name دادهشده را بازیابی کرده و برگرداند. در صورتی که متغیر در دسترس نباشد، یک استثنای invalid_argument ایجاد میکند.
- int function unset(string name)
- تلاش میکند متغیر محیطی با name دادهشده را لغو کند (unset) و نتیجهٔ موفقیت را برمیگرداند.
- string function set(string name, string value)
- تلاش میکند متغیر محیطی با name دادهشده را روی value دادهشده تنظیم کند و نتیجهٔ موفقیت را برمیگرداند.
دستورها (COMMANDS)
Nickle مجموعهای از دستورها دارد که میتوانند در سطح بالا اجرا شوند.
- quit
- خروج از Nickle.
- quit E
- خروج از Nickle با کد وضعیت صحیح E.
- undefine NAME {,NAME}
- حذف این نامها از سیستم.
- load E
- بارگذاری فایلی که نام آن با رشتهٔ E مشخص شده است.
- library E
- بارگذاری کتابخانهای که نام آن با رشتهٔ E مشخص شده است. بخش مربوط به متغیر محیطی NICKLEPATH در بخش «محیط (ENVIRONMENT)» در ادامه و توضیحات مربوط به Command::library_path در بالا را ببینید.
- E # E
- چاپ expr1 در مبنای expr2.
- print NAME
- نمایش نسخهٔ قالببندیشده از شیء مشخصشده با NAME. توضیحها و قالببندی اولیه از بین میروند. اگر NAME یک متغیر باشد، نوع متغیر به همراه مقدار آن چاپ میشود.
- edit NAME
- اجرای $EDITOR روی شیء مشخصشده و اعمال مجدد نتایج ویرایش. این دستور برای توابع بیشترین کاربرد را دارد.
- history
- نمایش ۱۰ مقدار چاپشدهٔ اخیر. دسترسی به آنها با استفاده از $n امکانپذیر است که در آن n عددی است که در سمت راست مقدار در این فهرست نشان داده شده است.
- history E
- نمایش E مقدار اخیر تاریخچه.
- history E,E
- نمایش مقادیر تاریخچه از عدد صحیح نخست E تا عدد دوم. هنگامی که یک استثنای مدیریتنشده در حین اجرا به بالاترین سطح (top level) میرسد، کاربر اعلانی به شکل خط تیره دریافت میکند که نشاندهنده فعال بودن حالت اشکالزدایی (debug mode) است. در این حالت، محیط خط فرمان همان محیطی است که استثنای مدیریتنشده در آن رخ داده است. علاوهبر این، تعدادی دستور اشکالزدایی در دسترس کاربر قرار دارد:
- trace
- دریافت ردپای پشته (stack backtrace) که وضعیت فعلی را نشان میدهد، همانند دستور where در GDB.
- up
- حرکت به سمت بالای پشته (یعنی به سمت عبارت سطح بالا)، مشابه GDB.
- down
- حرکت به سمت پایین پشته (یعنی به سمت زمینه فعلی)، مشابه GDB.
- done
- خروج از حالت اشکالزدایی و رها کردن اجرا.
- علاوهبر این، فضای نام Debug در حالت اشکالزدایی در دسترس (in scope) قرار میگیرد. این قابلیت عمدتاً برای اشکالزدایی خود Nickle کاربرد دارد.
- collect()
- اجرای زبالهروب (garbage collector).
- dump(function)
- چاپ بایتکد کامپایلشده برای تابع function.
محیط (ENVIRONMENT)
- EDITOR
- ویرایشگری که توسط دستور edit استفاده میشود و در بخش دستورات در بالا شرح داده شده است.
- NICKLERC
- مکان فایل .nicklerc کاربر، که در صورت امکان در ابتدای اجرای nickle بارگذاری خواهد شد.
- HOME
- برای یافتن فایل .nicklerc کاربر در صورتی که NICKLERC تنظیم نشده باشد، استفاده میشود.
- NICKLEPATH
- مسیری جداشده با دو نقطه (:) که عناصر آن دایرکتوریهای حاوی کدهای Nickle هستند. دستور library و پرچم -l که در بالا توضیح داده شدند، این مسیر را برای یافتن نام فایلی که با فایل دادهشده مطابقت دارد جستجو میکنند. مسیر پیشفرض کتابخانه در صورت عدم وجود این متغیر /usr/share/nickle است.
- NICKLESTART
- نام فایلی که باید هنگام راهاندازی Nickle به عنوان راهانداز اولیه (bootstrap) بارگذاری شود. پیشفرض در صورت عدم وجود این متغیر، بارگذاری /usr/share/nickle/builtin.5c است.
مثالها (EXAMPLES)
یک مثال (برگرفته از راهنمای bc):
real function exponent(real x) {
real a = 1;
int b = 1;
real s = 1;
int i = 1;
while (1) {
a = a * x;
b = b * i;
real c = a / b;
if (abs(c) < 1e-6)
return s;
s = s + c;
i++;
}
}
تابعی برای محاسبه مقدار تقریبی تابع نمایی e ** x تعریف میکند و
for (i = 1; i < 10; i++)
printf ("%g\n", exponent (i));
مقادیر تقریبی تابع نمایی را برای ده عدد صحیح اول چاپ میکند.
نسخه (VERSION)
این سند نسخه 1.99.2 از nickle و همچنین برخی از ویژگیهای جدیدتر را شرح میدهد. این سند همراه با نسخه “2.108” از nickle توزیع شده است.
گزارش باگها (BUGS)
به بحث مربوط به نوع عملگر توانرسانی ** در بالا مراجعه کنید.
به دلیل ابهام گرامری که برطرف کردن آن دشوار است، امکان استفاده از یک عبارت انتسابِ ساده (bare assignment) در مقداردهنده اولیه آرایه وجود ندارد: این مورد با مقداردهنده اولیه ساختار اشتباه گرفته میشود. برای مثال:
> int x = 0;
> (int[*]){x = 1}
-> (int[*]) { x = 1 }
Non array initializer
راهکار
موقت (workaround) این
است که
عبارت
انتساب را
داخل
پرانتز
قرار دهید:
> (int[*]){(x = 1)}
[1]{1}
از آنجا که
این مورد
بسیار
نادر، رفع
آن بسیار
دشوار، و
دور زدن آن
بسیار آسان
است، بعید
است این باگ
به این
زودیها
رفع شود.
باگهای شناختهشده زیادی در قالببندی ورودی و خروجی وجود دارد. موارد بدیهی کار میکنند، موارد دیگر کار نمیکنند.
معناشناسی (semantics) تقسیم متأسفانه با زبان C متفاوت است. مسلماً این به دلیل معیوب بودن C در این زمینه است: در حال حاضر هیچ راهحل واضحی برای آن متصور نیستیم. C اجازه تبدیل خودکار و ضمنی انواع ممیز شناور به انواع عدد صحیح را میدهد، اما ما این مورد را یک ویژگی نامناسب (misfeature) میدانیم.
پیادهسازی بهطور کامل آزمایش نشده است. Nickle اثر Keith Packard <keithp@keithp.com> و Bart Massey <bart_massey@iname.com> است.
نرمافزار
Nickle دارای
کپیرایت
۲۰۰۶-۱۹۸۸
متعلق به Keith Packard
و Bart Massey است.
کلیه حقوق
محفوظ است.
بدینوسیله به هر شخصی که نسخهای از این نرمافزار و فایلهای مستندات مربوطه («نرمافزار») را دریافت میکند، بدون دریافت هزینه، اجازه داده میشود که بدون محدودیت با نرمافزار رفتار کند؛ از جمله بدون محدودیت، حقوق استفاده، کپی، تغییر، ادغام، انتشار، توزیع، اعطای مجوز فرعی و/یا فروش نسخههای نرمافزار، و اجازه دادن به افرادی که نرمافزار برای آنها فراهم شده است تا با رعایت شرایط زیر چنین کنند:
اعلان کپیرایت فوق و این مجوزنامه باید در تمام نسخهها یا بخشهای عمدهای از نرمافزار گنجانده شود.
نرمافزار «به همان صورت که هست» (AS IS) و بدون هرگونه ضمانت، صریح یا ضمنی، شامل اما نه محدود به ضمانتهای تجاری بودن، مناسب بودن برای یک هدف خاص و عدم نقض حق ارائه میشود. در هیچ شرایطی نویسندگان در قبال هرگونه ادعا، خسارت یا مسئولیت دیگر، اعم از اقدام قراردادی، شبهجرم یا غیر آن، ناشی از نرمافزار، خارج از آن، یا در ارتباط با نرمافزار یا استفاده و سایر معاملات در آن، مسئولیتی نخواهند داشت.
بهجز مواردی که در این اعلان ذکر شده است، نام نویسندگان یا مؤسسات آنها نباید در تبلیغات یا موارد دیگر جهت ترویج فروش، استفاده یا سایر معاملات در این نرمافزار، بدون مجوز کتبی قبلی از نویسندگان استفاده شود.
| 2026-03-14 |