درس ۱ از ۴۹ · آغاز راه

نخستین برنامه

در این درس نخستین برنامه‌ی سلام را می‌نویسید و اجرا می‌کنید، با چند فرمانی که هر روز به کارشان می‌برید آشنا می‌شوید و شکل کلی کد سلام دستتان می‌آید.

سلام دنیا

هر برنامه‌ی سلام از تابع ریشه شروع می‌شود؛ یعنی نخستین کاری که هنگام اجرای برنامه انجام می‌شود. هر بلوک با دونقطه (:) باز و با پایان بسته می‌شود و تورفتگی خطوط درون بلوک، کد را خواناتر می‌کند. متن میان دو گیومه‌ی انگلیسی (") می‌آید و سرچاپ مقدارش را بدون پرانتز می‌گیرد.

نام این تابع همیشه ریشه است، نه «اصلی» یا main. اگر تابعی با نام دیگر بنویسید، برنامه کامپایل می‌شود ولی اجرا نمی‌شود و «نقطه‌ی ورود وجود ندارد» می‌بینید. برنامه به خط بسته هم نیازی ندارد.

hello.salam
تابع ریشه:
    سرچاپ "سلام دنیا!"
پایان
خروجیسلام دنیا!

اجرای برنامه

کد را در پرونده‌ای با پسوند .salam ذخیره کنید، مثلاً سلام.salam. با فرمان salam run سلام.salam برنامه ترجمه و بی‌درنگ اجرا می‌شود. اگر فایل اجرایی مستقل می‌خواهید، salam build سلام.salam را بزنید تا یک فایل اجرایی بومی کنار کدتان ساخته شود. بدون نصب هم می‌توانید همه‌ی نمونه‌ها را در ویرایشگر آنلاین اجرا کنید.

فرمانکارش
salam run سلام.salamبرنامه را ترجمه و اجرا می‌کند و چیزی به جا نمی‌گذارد
salam build سلام.salamفایل اجرایی بومی سلام را می‌سازد که بدون نصب سلام هم اجرا می‌شود
salam exec سلام.salamبرنامه را با مفسر اجرا می‌کند و به مترجم C نیازی ندارد
salam format سلام.salamپرونده را به چیدمان استاندارد مرتب می‌کند؛ با --check فقط گزارش می‌دهد
salam translate en سلام.salamنسخه‌ی انگلیسی برنامه را در سلام.en.salam می‌نویسد؛ translate fa برعکس کار می‌کند
salam new فروشگاهپوشه‌ی پروژه‌ی فروشگاه را با یک main.salam و یک salam.toml درونش می‌سازد؛ salam run در همان پوشه اجرایش می‌کند
salam add github.com/owner/repoبسته‌ای از گیت‌هاب را به پروژه می‌افزاید؛ remove، update و deps بقیه‌ی کار را می‌کنند (نگاه کنید به بسته‌ها)
salam versionنسخه‌ی مترجم را نشان می‌دهد
salam upgradeمترجم و کتابخانه‌ی استاندارد را به تازه‌ترین نسخه به‌روز می‌کند؛ با --check فقط می‌گوید نسخه‌ی تازه‌ای آمده است یا نه

چاپ خروجی

سرچاپ مقدارها را چاپ می‌کند و به خط بعد می‌رود و چاپ در همان خط می‌ماند. اگر چند مقدار را با ویرگول جدا کنید، سلام آن‌ها را با یک فاصله کنار هم می‌نویسد. ویرگول فارسی (،) و انگلیسی (,) هر دو پذیرفته می‌شوند.

start-print.salam
تابع ریشه:
    سرچاپ "سلام"، "دنیا"
    چاپ "بدون "
    چاپ "رفتن به خط بعد"
    سرچاپ ""
    سرچاپ "امروز", ۲۰, "درجه است"
پایان
خروجیسلام دنیا بدون رفتن به خط بعد امروز 20 درجه است

هر مقداری را می‌شود همان‌طور که هست چاپ کرد: عدد صحیح و اعشاری، درست و نادرست، حاصل یک محاسبه و حتی یک فهرست کامل. این هم یک رسید خرید کوچک:

start-values.salam
تابع ریشه:
    سرچاپ "رسید خرید"
    سرچاپ "دفتر"، ۳، "عدد، هر کدام"، ۴۵
    سرچاپ "خودکار"، ۲، "عدد، هر کدام"، ۱۲
    سرچاپ "جمع:"، ۳ * ۴۵ + ۲ * ۱۲
    سرچاپ "میانگین هر قلم:"، (۳ * ۴۵ + ۲ * ۱۲) / ۵.۰
    سرچاپ "پرداخت کامل:"، درست
    سرچاپ "قفسه‌ها:"، [۴، ۷]
پایان
خروجیرسید خرید دفتر 3 عدد، هر کدام 45 خودکار 2 عدد، هر کدام 12 جمع: 159 میانگین هر قلم: 31.8 پرداخت کامل: true قفسه‌ها: [4, 7]

عددها و مقدارهای منطقی با رقم‌ها و واژه‌های انگلیسی چاپ می‌شوند (159 و true)، حتی اگر در کد با رقم فارسی نوشته شده باشند. سه قاعده تقریباً همه‌ی اشتباه‌های چاپ را پوشش می‌دهد:

  • دور مقدارها پرانتز نگذارید: سرچاپ "سلام"، نه سرچاپ("سلام").
  • میان هر دو مقدار ویرگول بگذارید: سرچاپ "الف"، "ب". اگر ویرگول را جا بیندازید خطا می‌گیرید، نه دو رشته‌ی چسبیده.
  • سرچاپ همیشه مقدار می‌خواهد. برای یک خط خالی بنویسید سرچاپ "".

برای پیام‌های خطا از نادرست‌سرچاپ و نادرست‌چاپ استفاده کنید؛ این دو به خروجی خطا (stderr) می‌نویسند و خروجی عادی برنامه را شلوغ نمی‌کنند. اگر خروجی را با salam run برنامه.salam > خروجی.txt به پرونده بفرستید، خط‌های عادی در پرونده می‌روند و پیام‌های خطا همچنان روی صفحه دیده می‌شوند.

start-stderr.salam
تابع ریشه:
    سرچاپ "این پیام به خروجی عادی می‌رود"
    نادرست‌سرچاپ "این پیام به خروجی خطا می‌رود"
پایان
خروجیاین پیام به خروجی عادی می‌رود این پیام به خروجی خطا می‌رود

کد خروج

هر برنامه هنگام پایان یک عدد به سیستم‌عامل تحویل می‌دهد که به آن کد خروج می‌گویند. صفر یعنی کار با موفقیت تمام شد و هر عدد دیگری یعنی جایی مشکلی پیش آمده است؛ اسکریپت‌ها و ابزارهای ساخت از روی همین عدد تصمیم می‌گیرند که کار را ادامه بدهند یا نه. اگر برای ریشه گونه‌ی برگشتی صحیح بنویسید، هر عددی که با برگشت برگردانید کد خروج می‌شود. تابع ریشه: ساده‌ای که به پایان خودش برسد با کد صفر تمام می‌شود.

start-exit.salam
تابع ریشه: صحیح:
    فضای آزاد := ۸۲۰
    فضای لازم := ۵۰۰
    اگر فضای آزاد < فضای لازم:
        نادرست‌سرچاپ "فضا کافی نیست:"، فضای آزاد، "مگابایت آزاد است و"، فضای لازم، "مگابایت لازم است"
        برگشت ۱
    پایان
    سرچاپ "فضا کافی است، پشتیبان‌گیری شروع شد"
    برگشت ۰
پایان
خروجیفضا کافی است، پشتیبان‌گیری شروع شد

با ۸۲۰ مگابایت فضای آزاد بررسی قبول می‌شود و برنامه صفر برمی‌گرداند. اگر فضای آزاد را ۳۰۰ کنید، پیام به خروجی خطا می‌رود و برنامه با کد ۱ تمام می‌شود؛ در پوسته‌ی یونیکس بلافاصله پس از اجرا با echo $? می‌توانید این عدد را ببینید.

خواندن ورودی

ورودی یک خط از کاربر می‌خواند و آن را به شکل رشته برمی‌گرداند. مثل چاپ پرانتز نمی‌گیرد و همیشه یک پیام می‌خواهد که پیش از خواندن چاپ می‌شود. اگر پیامی نمی‌خواهید، ورودی "" بنویسید. چیزی که برمی‌گردد همیشه متن است؛ اگر عدد لازم دارید، آن را با به صحیح() (یا به اعشار() برای عدد اعشاری) تبدیل کنید. رقم‌های فارسی هم درست خوانده می‌شوند:

start-input.salam
تابع ریشه:
    نام := ورودی "نام شما: "
    تعداد := ورودی "چند بلیت می‌خواهید؟ "
    مبلغ := تعداد.به صحیح() * ۱۲۰۰۰۰
    سرچاپ "سپاس،"، نام
    سرچاپ "مبلغ کل:"، مبلغ، "تومان"
پایان

اگر کاربر چیزی غیر از عدد بنویسد، به صحیح() صفر برمی‌گرداند و برنامه را متوقف نمی‌کند؛ پس پیش از اعتماد به مقدار، آن را بررسی کنید. این نمونه منتظر کاربر پشت صفحه‌کلید می‌ماند و برای همین خروجی‌اش اینجا نیامده است.

توضیح‌ها

هر چیزی که پس از // بیاید تا پایان خط، و هر چیزی بین /* و */، توضیح است و اجرا نمی‌شود.

start-comments.salam
// این یک توضیح یک‌خطی است و اجرا نمی‌شود

/*
توضیح چندخطی:
هر چیزی بین این دو نشانه نادیده گرفته می‌شود.
*/

تابع ریشه:
    سرچاپ "توضیح‌ها در خروجی دیده نمی‌شوند" // این هم توضیح است
پایان
خروجیتوضیح‌ها در خروجی دیده نمی‌شوند

توضیح‌های چندخطی تودرتو می‌شوند: یک /* ... */ درون دیگری مشکلی ندارد، پس می‌توانید تکه‌کدی را که خودش توضیح چندخطی دارد موقتاً درون یک توضیح دیگر بگذارید و از کار بیندازید.

بلوک‌های یک‌خطی

اگر بدنه‌ی یک بلوک کوتاه است، می‌توانید همه‌ی آن را در یک خط بنویسید:

start-oneline.salam
تابع ریشه: سرچاپ "برنامه‌ی یک‌خطی" پایان
خروجیبرنامه‌ی یک‌خطی

ساختار یک برنامه

برنامه‌ی واقعی فقط ریشه نیست. پرونده‌ی کد از بالا به این ترتیب خوانده می‌شود: نخست خط‌های واردسازی برای کتابخانه‌ها، سپس پایاها، بعد متغیرهای سراسری، بعد گونه‌هایی که خودتان می‌سازید و در پایان تابع‌ها. تابع‌ها به هر ترتیبی می‌توانند همدیگر را صدا بزنند، پس ریشه می‌تواند بالای پرونده بنشیند و از تابع‌های کمکی پایین‌تر استفاده کند.

start-shape.salam
واردسازی رشته

پایا فروشگاه := "کتاب‌فروشی سلام"

تابع ریشه:
    سرچاپ فروشگاه
    سرچاپ خط جداکننده()
    سرچاپ سطر("شاهنامه"، ۲)
    سرچاپ سطر("گلستان"، ۱)
پایان

تابع خط جداکننده(): رشته:
    برگشت رشته.تکرار("-"، ۲۰)
پایان

تابع سطر(عنوان: رشته، تعداد: صحیح): رشته:
    برگشت عنوان + " × " + تعداد
پایان
خروجیکتاب‌فروشی سلام -------------------- شاهنامه × 2 گلستان × 1

واردسازی رشته کتابخانه‌ی رشته را می‌آورد و رشته.تکرار یکی از تابع‌های آن است؛ کتابخانه‌ها در درس بسته‌ها کامل آمده‌اند. اگر پایایی را پایین‌تر از یک تابع، یا واردسازی را پایین‌تر از یک پایا بنویسید، مترجم خطا می‌دهد و می‌گوید آن را به کجا ببرید.

وقتی مترجم ایراد می‌گیرد

سلام پیش از اجرا چیزهای زیادی را بررسی می‌کند و با پیامی فارسی دقیقاً خط و ستون اشکال و راه درست‌کردنش را نشان می‌دهد. این‌ها خطاهایی هستند که تازه‌کارها زودتر از همه می‌بینند:

نوشته‌ایدمترجم می‌گوید
سرچاپ("سلام")آرگومان‌های چاپ نباید داخل پرانتز قرار گیرند؛ پرانتز را حذف کنید
سرچاپ به تنهاییچاپ مقدار می‌خواهد: برای خط خالی بنویسید 'سرچاپ ""'
سرچاپ "الف" "ب"میان مقدارهایی که چاپ می‌شوند ',' انتظار می‌رفت
ع := ۵ و ع هیچ‌جا به کار نرفتهE059: متغیر استفاده‌نشده 'ع'
الف && ب'&&' عملگر سلام نیست؛ به جای آن 'و' بنویسید

همیشه نخستین پیام را اول بخوانید: یک اشتباه ممکن است چند خطای دیگر هم پشت سرش بسازد که معمولاً با درست‌شدن اولی از بین می‌روند. درس قواعد مترجم بررسی‌های سخت‌گیرانه‌تر و فایده‌ی آن‌ها را توضیح می‌دهد.

سلام زبانی دوزبانه است: همین برنامه‌ها را می‌توانید با واژه‌های انگلیسی هم بنویسید. جدول کامل واژه‌ها در درس واژه‌نامه آمده است.