توابع داخلی
توابع داخلی در کوروش عملیاتهای خاصی هستند که توسط کامپایلر ارائه میشوند و امکان دستکاری حافظه در سطح پایین، دروننگری در زمان کامپایل، اشکالزدایی و کامپایل شرطی را فراهم میکنند. این توابع در دو شکل اصلی پیادهسازی میشوند: بلوک و تابع، با فازهای ارزیابی متفاوت که تعیین میکنند چه زمانی در طول کامپایل پردازش شوند.
اشکال توابع داخلی
توابع داخلی در کوروش میتوانند به دو شکل مجزا استفاده شوند:
شکل تابع (شکل عبارت)
توابع داخلی که به صورت فراخوانی تابع ظاهر میشوند و مقداری را برمیگردانند که میتواند در عبارات، انتسابها، یا به عنوان آرگومان به توابع دیگر استفاده شود.
مثالها:
const size = @sizeof(int32);
const line_num = @line();
const value = @cast(uint32, -1);
شکل بلوک (شکل دستور)
توابع داخلی که به صورت دستورات بلوکی برای کنترل جریان و کامپایل شرطی ظاهر میشوند. اینها میتوانند شامل چندین دستور و تعریف در محدوده خود باشند.
مثالها:
@debug() {
// کدی که فقط در حالت اشکالزدایی کامپایل میشود
const x = 10;
printf("حالت اشکالزدایی\n");
}
@release() printf("نماد اختصاری حالت انتشار");
خانوادههای توابع داخلی
خانواده ConstEval (ارزیابی در زمان کامپایل)
این توابع داخلی کاملاً در زمان کامپایل ارزیابی میشوند و مقادیر ثابتی تولید میکنند که میتوانند در عبارات ثابت استفاده شوند.
// همگی در زمان کامپایل ارزیابی میشوند
const type_size = @sizeof(int32); // مقدار ۴ را برمیگرداند
const alignment = @alignof(float64); // مقدار ۸ را برمیگرداند
const current_line = @line(); // شماره خط را برمیگرداند
const current_file = @file_name(); // نام فایل را به صورت رشته برمیگرداند
خانواده Intrinsic (عملیات کامپایلر)
این توابع داخلی عملیاتهای سطح پایینی هستند که مستقیماً توسط کامپایلر پیادهسازی شده و به کد ماشین کارآمد کامپایل میشوند.
// عملیات سطح پایین
@memcpy(&dest, &src, @sizeof(Data)); // کپی حافظه
@memset(&buffer, 0x00, 100); // تنظیم حافظه
const x = @cast(uint32, y); // تبدیل نوع
مرجع توابع داخلی
توابع داخلی اطلاعات منبع
@func_name()
نام تابع فعلی را به صورت یک رشته literal برمیگرداند.
import std::libc{printf};
pub fn main() {
printf("%s\n", @func_name()); // خروجی: main
}
@method_name()
زمانی که در داخل یک متد ساختار فراخوانی شود، نام متد فعلی را برمیگرداند.
struct Object {
pub fn my_method() {
printf("%s\n", @method_name()); // خروجی: my_method
}
}
@module_name()
نام ماژول فعلی را به صورت یک رشته literal برمیگرداند.
printf("%s\n", @module_name()); // خروجی: my_module_name
@file_name()
نام فایل منبع فعلی را به صورت یک رشته literal برمیگرداند.
printf("%s\n", @file_name()); // خروجی: main.cyrus
@line()
شماره خط فعلی را به صورت یک ثابت عدد صحیح برمیگرداند.
printf("خطا در خط %d\n", @line()); // خروجی: خطا در خط ۵
@column()
شماره ستون فعلی را به صورت یک ثابت عدد صحیح برمیگرداند.
printf("خطا در ستون %d\n", @column()); // خروجی: خطا در ستون ۱۰
توابع داخلی اطلاعات نوع
@sizeof(type)
اندازه بر حسب بایت از نوع داده شده را به عنوان یک ثابت زمان کامپایل برمیگرداند.
printf("%d ", @sizeof(int32)); // ۴
printf("%d ", @sizeof(int64)); // ۸
printf("%d ", @sizeof(float64)); // ۸
printf("%d ", @sizeof(bool)); // ۱
// با انواع تعریف شده توسط کاربر نیز کار میکند
struct MyStruct { a: int32, b: int32 }
printf("%d\n", @sizeof(MyStruct)); // ۸
@alignof(type)
نیازمندی ترازبندی بر حسب بایت از نوع داده شده را برمیگرداند.
printf("%d ", @alignof(int32)); // ۴
printf("%d ", @alignof(float64)); // ۸
printf("%d ", @alignof(struct { a: int32* })); // ۸
printf("%d\n", @alignof(struct { a: int32, b: int8 })); // ۴
@offsetof(type, field_name)
آفست بایت یک فیلد را در داخل یک نوع ساختار برمیگرداند.
struct Foo {
a: int32,
b: int32*
}
printf("%d ", @offsetof(Foo, "a")); // ۰
printf("%d\n", @offsetof(Foo, "b")); // ۸
@typeof(expression)
نوع عبارت داده شده را در زمان کامپایل برمیگرداند.
var x: @typeof('a'); // x از نوع char است
x = 'b';
printf("%c\n", x); // خروجی: b
var y: @typeof(42); // y از نوع int32 است
عملیات ذاتی
@cast(target_type, value)
تبدیل نوع را بین انواع سازگار انجام میدهد.
// تبدیل بین انواع عددی
var i8_val: int8 = 100;
var i32_val = @cast(int32, i8_val); // ۱۰۰
// تبدیل بین علامتدار و بدون علامت
var u32_val: uint32 = 4294967295;
var i64_val = @cast(int64, u32_val); // ۴۲۹۴۹۶۷۲۹۵
// تبدیل کاراکتر به rune
type rune = uint32;
const x = @cast(rune, 'x'); // ۱۲۰
@memcpy(dest, src, size)
یک بلوک حافظه را از مبدأ به مقصد کپی میکند.
struct Data {
id: int32,
score: float64,
flag: bool
}
var src = Data { id: 99, score: 99.5, flag: true };
var dst: Data;
@memcpy(&dst, &src, @sizeof(Data));
// اکنون dst شامل یک کپی از src است
@memset(dest, value, size)
یک بلوک حافظه را با مقدار مشخص شده پر میکند.
var x: int32 = 0;
@memset(&x, 0xAAAA, @sizeof(int32));
// x اکنون برابر ۰xAAAAAAAA است
توابع داخلی کنترل جریان
@assert(condition, message?)
تأیید میکند که یک شرط در زمان اجرا درست است، در صورت نادرست بودن با یک پیام اختیاری باعث وحشت (panic) میشود.
const x = 20;
@assert(x == 2, "x برابر ۲ نیست"); // با پیام باعث وحشت میشود
@panic(message?)
برنامه را با یک پیام اختیاری متوقف میکند.
@panic("خطای فatal رخ داد"); // با پیام خاتمه مییابد
@todo(message?)
کد را به عنوان کار انجامنشده علامتگذاری میکند و باعث وحشت در زمان کامپایل یا اجرا میشود.
@todo("این تابع را پیادهسازی کنید"); // با پیام TODO باعث وحشت میشود
@unimplemented(message?)
کد را به عنوان پیادهسازینشده علامتگذاری میکند و باعث وحشت در زمان کامپایل یا اجرا میشود.
@unimplemented("هنوز پیادهسازی نشده است");
@unreachable(message?)
کد را به عنوان غیرقابل دسترس علامتگذاری میکند و در صورت رسیدن به آن، باعث وحشت در زمان کامپایل یا اجرا میشود.
if (x) {
// کاری انجام بده
} else {
@unreachable("این شاخه هرگز نباید اجرا شود");
}
توابع داخلی کامپایل شرطی
@debug() { ... }
بلوک کد را فقط در ساختهای اشکالزدایی اجرا میکند. هم به صورت بلوک و هم به صورت دستور نماد اختصاری کار میکند.
// شکل بلوک
@debug() {
const x = 10;
printf("حالت اشکالزدایی: %d\n", x);
}
// شکل دستور نماد اختصاری
@debug() printf("خروجی فقط در حالت اشکالزدایی\n");
// متغیرهای تعریف شده در داخل بلوک اشکالزدایی فقط در حالت اشکالزدایی در دسترس هستند
@debug() {
const debug_var = 100; // فقط در ساختهای اشکالزدایی وجود دارد
}
printf("%d\n", debug_var); // در ساختهای انتشار خطا میدهد
@release() { ... }
بلوک کد را فقط در ساختهای انتشار اجرا میکند. هم به صورت بلوک و هم به صورت دستور نماد اختصاری کار میکند.
// شکل بلوک
@release() {
const x = 10;
printf("حالت انتشار: %d\n", x);
}
// شکل دستور نماد اختصاری
@release() printf("خروجی فقط در حالت انتشار\n");

