به Factor خوش آمدید! Factor یک زبان الحاقی است: بهجای فراخوانی توابعی مثل square(add(2, 3))، یک ردیف واژه را از چپ به راست مینویسید، مثل 2 3 + square، که مقادیر را از طریق یک پشتهی دادهی مشترک به یکدیگر میرسانند. تصور کنید پشتهای از جعبههای بار روی اسکله است که تازهترین جعبه بالای آن قرار دارد.
یک ! یک کامنت خطی را شروع میکند: Factor هر چیزی را از ! تا پایان خط نادیده میگیرد. مثالهای زیر از ! برای توضیح کاری که کد انجام میدهد استفاده میکنند.
هر مقداری که در کد مینویسید به بالای پشته میرود. کد از چپ به راست خوانده میشود.
1 2 3 ! stack (bottom → top): 1 2 3
هر واژه ورودیهایش را از بالای پشته میخواند و خروجیهایش را دوباره همانجا مینویسد. . بالاترین مقدار را از پشته برمیدارد و چاپ میکند؛ .s کل پشته را بدون آنکه چیزی مصرف کند چاپ میکند، که برای دیدن اینکه یک قطعه از کد چه چیزی از خود به جا گذاشته به کار میآید.
هر واژه با یک اثر پشته به شکل ( inputs -- outputs ) مستند میشود. این قرارداد آن واژه است: واژه ورودیها را از بالای پشته برمیدارد و خروجیها را به جای آنها میگذارد. نامهای داخل آن برای انسانهاست؛ خود پشته موقعیتی است و نامی ندارد. بالای پشته همان نام سمت راست است.
: تعریف یک واژه را شروع میکند، سپس اثر پشته میآید، بعد بدنه و در پایان ; آن را تمام میکند. کامپایلر Factor بررسی میکند که بدنه واقعاً همان چیزی را به جا میگذارد که اثر پشته اعلام کرده است.
: restow ( a b -- b a ) swap ;
این واژههای kernel بالای پشته را بدون انجام هیچ محاسبهی حسابی جابهجا میکنند؛ آنها فقط جعبهها را اینور و آنور میبرند:
dup ( x -- x x ) ! copy the top crate
drop ( x -- ) ! remove the top crate
swap ( x y -- y x ) ! flip the top two
over ( x y -- x y x ) ! copy the second crate onto the top
nip ( x y -- y ) ! remove the second crate
rot ( x y z -- y z x ) ! roll the third crate up to the top
وقتی یک جعبه باید دو واژه را تغذیه کند سراغ dup بروید؛ برای دور انداختن یک جعبه drop؛ وقتی دو جعبهی بالایی ترتیب نادرستی دارند swap؛ برای کار با جعبهی زیرین over یا nip؛ و برای آوردن یک جعبهی مدفون به بالای پشته rot.
خانوادهی گستردهتر (-rot، dupd، swapd، 2dup، …) از همین ایده پیروی میکند. با آن واژهها بعداً آشنا خواهید شد.
واژههایی که پشت سر هم نوشته میشوند از چپ به راست اجرا میشوند: هر واژه روی پشتهای عمل میکند که واژهی پیش از خود به جا گذاشته است. در ادامه میبینید که swap nip با پشتهی 1 2 (از پایین → به بالا)، یک واژه در هر گام، چه میکند:
1 2 ! 1 2 the starting crates
swap ! 2 1 swap flipped the top two
nip ! 1 nip dropped the 2nd-from-top crate (the 2)
و این هم dup rot روی همان جعبههای اولیه، باز هم یک واژه در هر گام:
1 2 ! 1 2 the starting crates
dup ! 1 2 2 dup copied the top crate
rot ! 2 2 1 rot rolled the 3rd-from-top crate up to the top
واژهها از lowercase-kebab-case استفاده میکنند: حروف کوچک که با خط تیره به هم میپیوندند.
فرض کنید کارگر عرشهاید و روی اسکله دارید جعبههای بار را از نو میچینید. هر وظیفه یک «واژه» است که بدنهاش فقط از واژههای جابهجایی استفاده میکند، بدون هیچ محاسبهای.
واژهی swap-crates را تعریف کنید. این واژه دو جعبه را از «پشته» برمیدارد و آنها را به ترتیب معکوس برجای میگذارد.
1 2 swap-crates .s
! 2
! 1
واژهی clear-spill را تعریف کنید. این واژه سه جعبه را از پشته برمیدارد، دو جعبهی زیرین را برجای میگذارد و جعبهی بالایی را دور میریزد.
1 2 3 clear-spill .s
! 1
! 2
واژهی peek-under را تعریف کنید. این واژه دو جعبه را از پشته برمیدارد، آنها را برجای میگذارد و یک کپی از جعبهی زیرین را رویشان میگذارد.
1 2 peek-under .s
! 1
! 2
! 1
واژهی tidy-deck را تعریف کنید. این واژه سه جعبه را به ترتیب x y z از پشته برمیدارد و z z y را برجای میگذارد: جعبهی زیرین را دور میریزد، سپس دو کپی از جعبهی بالایی را زیر جعبهی میانی میگذارد.
1 2 3 tidy-deck .s
! 3
! 3
! 2