ساخت ماشین حساب با جاوااسکریپت

این کاریه که من به عنوان یه پروژه نسبتاً تفریحی انجام دادم و دوست داشتم که تجربیاتم رو با شما هم به اشتراک بذارم. ماجرا از این قراره که ما می‌خوایم یه سیستم (یا اصلا یه تابع!) درست کنیم که بتونه عبارت‌های ریاضی رو حساب کنه؛ مثلا اگه ما بهش بدیم ۲×۲ به ما ۴ رو برگردونه. در واقع یه همچین چیزی:

const answer = calculate(&quot2 * 2&quot)
console.log(answer) // 4

مرحله اول (و چالش‌برانگیز!): فهموندن عبارت به کامپیوتر

همون‌طور که توی مثال دیدید، چیزی که ما به تابع ورودی میدیم یه رشته‌ست، کامپیوتر هیچ درکی ازش نداره، نمی‌دونه مفهومش چیه. چالش اول و اصلی ما اینه که بتونیم از این رشته اطلاعات رو بکشیم بیرون. مثلا بتونیم از رشته‌ی 2 * 2 اینا رو بفهمیم:

[
  Number { value: 2 },
  Operator { type: '*', value: 2 },
  Number { value: 2 }
]

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

این کار (tokenizing) رو میشه با یه حلقه روی اون رشته انجام داد، اما کار دقیقیه، باید حواس‌جمع باشید موقع نوشتن! احتمالا به کلی flag نیاز دارید، و البته خوبه که کدتون بتونه از عبارت داده‌شده غلط بگیره و ارور بده.

مرحله بعد: به دست آوردن مقدار عددی

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

مرحله آخر: قابلیت‌های بیشتر

  • می‌تونید پرانتزها رو به طور بازگشتی حساب کنید.
  • می‌تونید حتی تابع اضافه کنید به ماشین حسابتون! مثلا اگه قبل از شروع پرانتز یه سری حروف اومده‌بود می‌تونیم نتیجه بگیریم که این‌جا منظور فلان تابع‌ست.
  • بعضی توابع خاص که از لحاظ نوشتاری متفاوتن رو هم می‌تونید به دلخواه خودتون پیاده کنید؛ مثل قدر مطلق یا ...

نتیجه‌ی کار

من همین کد رو نوشتم و توی گیت‌هاب منتشرش کردم. از npm می‌تونید دانلودش کنید و توی خط فرمان هم ازش استفاده کنید:

npm i -g @hkh12/node-calc
node-calc &quot2*2&quot // prints 4
node-calc &quot2*2&quot &quot2*3&quot // prints 4 and 6
node-calc // REPL!
حالت REPL
حالت REPL


و یه ربات تلگرام هم ساختم که ازش استفاده می‌کنه و می‌تونید توی تلگرام باهاش یه چیزایی رو محاسبه کنید، از همین عبارت‌ها کوئیز بسازید و کارای دیگه.

امیدوارم که مطلب مفیدی بوده‌باشه براتون؛ اگه بوده توی گیت‌هاب استار بدید! ممنون.