مقدمة
منذ عام 2016 (مع انقطاع) لقد قمت بتطوير لغتي البرمجة الخاصة. اسم هذه اللغة هو "Ü". لماذا Ü؟ لأنني أردت اسمًا مؤلفًا من حرف واحد ، وجميع الرسائل من مجموعة AZ مأخوذة بالفعل.
هذه المقالة مهمة تعريف الجمهور بهذه اللغة ، لإعطاء فكرة عامة عنها. لا تنوي المقالة وصف اللغة بالكامل ، وسيتم تقديم وصف أكمل للغة ، إذا لزم الأمر ، في المقالات التالية.
لماذا نحتاج إلى لغة أخرى؟
لقد درست عددًا من اللغات المكتوبة بشكل ثابت والتي تم تجميعها بلغات أكثر أو أقل شهرة ، وتوصلت إلى استنتاج مفاده أن أيا منها لا يناسبني تمامًا. كل منهم لديهم عيوب "قاتلة".
نقاط محددة:
- ج - مستوى منخفض جدا وغير آمن
- C ++ - ورثت العديد من العيوب منخفضة المستوى ، وطرق جديدة لاطلاق النار على نفسك ، والافتقار إلى التفكير
- د - جامع القمامة ، أنواع مرجعية منفصلة
- جافا هي جامع للقمامة ، ويتم الرجوع إلى جميع الأنواع المركبة ، ومرفق قوي بجهاز ظاهري. ينطبق الكثير من هذا أيضًا على اللغات المعتمدة على JVM.
- عيوب C # تشبه إلى حد كبير جافا
- الصدأ - الحاجة إلى أخذ الروابط بشكل صريح وإلغاء تحديدها صراحةً (ذاتيًا) خطر اتباع نهج عندما يكون كل شيء تعبيرًا وإرجاع نتيجة ، وجود مؤشر صريح على الامتثال للبروتوكول ، عدم وجود الميراث
- الذهاب - جامع القمامة ، وعدم وجود قوالب
- سويفت - أنواع المراجع ، الحاجة إلى الإشارة صراحة إلى الامتثال للبروتوكول
بعد اكتشاف النقص في جميع اللغات المذكورة أعلاه ، قررت إنشاء لغتي الخاصة ، خالية من العيوب ، كما يبدو لي.
معلومات عامة
Ü هي لغة مترجمة ومكتوبة بشكل ثابت مع كتابة قوية. تحتوي اللغة على وظائف وهياكل وفصول وطرق للهياكل وفصول مجانية. الأنواع الحالية من الأنواع - أساسية ، هيكلية (هياكل ، فئات) ، مصفوفات ذات حجم ثابت ، tuples ، أعداد ، مؤشرات إلى وظائف. يمكن للفصول المشاركة في الميراث ولها وظائف افتراضية. تدعم اللغة القوالب ، وهناك قوالب للفئات والهياكل ، والأسماء المستعارة للأنواع والوظائف والأساليب. هناك الكثير من الوظائف والمشغلين (مع بعض القيود).
اللغة تدعم المدمرات للفئات والهياكل. تستخدم المدمرات لإدارة الموارد ، بما في ذلك الذاكرة.
ما هو بالفعل هناك
نفذت مترجم LLVM مقرها. المترجم يدعم جميع الأنظمة الأساسية التي تدعم LLVM. المترجم لا يعرف بعد كيفية إنشاء ملفات قابلة للتنفيذ بحتة ، لكنه يمكن أن تولد ملفات الكائنات ، رمز المجمع ، رمز llvm ثنائي أو نص. من الممكن التواصل مع C code ، وهناك أداة مساعدة تسهل كتابة رؤوس for لمكتبات C.
الأهداف والغايات
يتم إنشاء اللغة بطريقة لجذب أكبر عدد ممكن من الأخطاء النموذجية في مرحلة الترجمة. يتم اتخاذ القرارات المتعلقة بتصميم اللغة في المقام الأول على أساس هذه المهمة. الهدف الثاني هو سهولة (نسبية) كتابة البرامج وسهولة قراءتها.
لا تحتوي اللغة على تصميمات قد تؤدي إلى إثارة كتابة التعليمات البرمجية الخاطئة ، كما أنها لا تحتوي على ميزات قد تعقد بشكل كبير فهم ما يحدث في البرنامج.
على الرغم من النقاط أعلاه ، لا يمكن تجاهل مشكلة الأداء. لذلك ، على حساب الأداء ، لا يتم اتخاذ قرارات تصميم اللغة.
لذا ، دعونا نلقي نظرة على ما هي اللحظات التي تتوافق مع الأهداف المعلنة.
اكتب النظام
بخلاف C ++ ، في Ü لا توجد مؤشرات ومراجع كنوع. لا توجد مؤشرات على الإطلاق ، هناك ارتباطات ، ولكن فقط كروابط مكدس ، وسيطات مرجع دالة ، وحقول مرجعية. أيضًا ، لا تعد معدّلات mut / imut جزءًا من نوع ما ، ولكنها جزء من متغير وسيطة أو مرجع أو دالة أو مجال.
بفضل هذا التبسيط ، هناك فهم أكبر للمكان الذي يوجد فيه هذا النوع ، خاصةً في كود boilerplate. لا توجد أي شكوك حول ما إذا كان سيتم الإعلان عن ارتباط أو متغير ، شكوك نتيجة typeof (تناظرية dectype من C ++) ، شكوك حول ثابت / غير ثابت.
الجانب الآخر من هذا التبسيط هو الحاجة إلى معالجة منفصلة للتناسق والروابط في القوالب. على الرغم من ذلك ، يضيف هذا الوضوح عند تمرير معلمة الثبات إلى القالب كوسيطة منفصلة بشكل صريح.
المهيآت
من المستحيل التصريح عن متغير وعدم تهيئته. يجب تهيئة أي بايت من المتغير المعلن.
تتطلب الأنواع الأساسية (وبعضها الآخر) التهيئة الإلزامية:
var i32 x= 22, y(12345);
:
struct Vec{ f32 x; f32 y; }
...
var Vec v{ .x= -56.1f, .y= 42.0f };
var Vec v_uninit; //
, :
struct Vec
{
f32 x; f32 y;
fn constructor()
( x= 0.0f, y= 0.0f )
{}
}
...
var Vec v; //
, .
, :
struct Vec
{
f32 x= 0.0f;
f32 y= 0.0f;
}
, [] , :
var [ i32, 4 ] a[ 1, 1, 3, 4 ];
var tup[ i32, f32 ] t[ 8, 0.5f ];
var [ f32, 16 ] a_uninit; // , .
var[ i32, 3 ] aa[ 0, 1 ]; // ,
C++, , . , , — .
. , , — . this, - /, :
struct Vec
{
f32 x; f32 y;
fn constructor()
( x= y, y= 0.0f ) // , «y»
{}
fn constructor( f32 val )
( x= val, y= x ) // . «x» «y»
{}
}
. , , . .
:
var i32 mut x= 0;
var i32 &mut ref0= x;
++x; // ,
var i32 &imut ref1= x; // , , . .
:
var i32 mut x= 0;
var i32 &imut ref0= x;
var i32 &mut ref1= x; // , ,
:
var i32 mut x= 0;
var i32 &mut ref0= x;
var i32 &mut ref1= ref0; // , . . ,
:
fn Mutate( i32 &mut x, i32 &mut y );
...
var i32 mut x= 0;
Mutate( x, x ); // ,
. C++
std::vector<int> vec;
vec.push_back(1);
int& ref= vec.front();
vec.push_back(2); // , ref
Ü :
var ust::vector</i32/> mut vec;
vec.push_back(1);
var i32 &imut ref= vec.front();
vec.push_back(2); // , vec,
( ). — polymorph, interface, abstract . . , .
:
- . , , .
:
class A interface
{
fn virtual pure Foo(this);
}
- . . . , this, , . . . abstract call, , , C++.
:
class A abstract
{
fn virtual pure Foo(this);
fn virtual Bar(this){}
i32 x= 0;
}
- . . . - , .
:
class A interface
{
fn virtual pure Foo(this);
}
class B : A
{
fn virtual override Foo(this){}
}
- . , , .
. .
fn virtual pure Foo(this); // . , , .
fn virtual Foo(this){} // . , .
fn virtual override Foo(ths){} // , . , .
fn virtual final Foo(this){} // , . , . - , .
2019— , , Ü . . , , , , .
:
fn Foo( i32 mut x ) : i32
{
while(x < 100 )
{
x+= 10;
continue;
x+= 20; // ,
}
return x;
++x; // ,
}
:
fn Foo( i32 x ) : i32
{
if( x < 10 ) { return 0; }
else if( x > 100 ) { return 1; }
// ,
}
else , return .
, - , halt ( ). , , , return.
. , (. ). () .
:
struct CallableObject
{
i32 &mut x;
op()( mut this )
{
++x;
}
}
...
var i32 mut x= 0;
var CallableObject mut obj{ .x= x };
auto thread= ust::thread_create( move(obj) );
++x; // , «x», «thread»
++ obj.x; //
- , , - , .
(mutable C++), . . . , - , .
, ? — shared_ptr_mt . , , lock_mut() lock_imut(), . « , ».
:
struct Incrementer
{
ust::shared_ptr_mt_mut</ i32 /> ptr;
op()( mut this )
{
auto mut lock= ptr.lock_mut(); // «lock»
++lock.get_ref();
}
}
...
var ust::shared_ptr_mt_mut</ i32 /> ptr(0);
var size_type mut i(0);
var ust::vector</ ust::thread</Incrementer/> /> mut threads;
while( i < size_type(64) )
{
var Incrementer incrementer{ .ptr= ptr };
threads.push_back( ust::thread_create(incrementer) );
++i;
}
threads.clear(); // .
halt if( ptr.lock_imut().get_ref() != 64 ); // , ,
, , . . «shared». , , , - , «shared».
. , , constexpr . , .
, Ü, - , C.
C++, (=, +=, *= . .) , , . ++ –.
:
if( x = 0 ) {}
x++; // ++
x += x += x; // , +=
x+= x++ + ++x; //
. void, .
, , . :
auto a = select( condition ? x : y );
select .
. . . .
? , - :
- . - , , .
- . . - NullPointerException - , - . , , . . .
- . , , , . - - , . , .
- . , , .
, , ?
, . . «» , , std::optional/std::variant C++ Option/Result Rust.
, -, , halt. ( Ü ) , , , .
, - . , import, , . C++, , .
. , *.cpp *.hpp C++.
, , , .
, , . , , , . , - , .
→
→
, , .
→
.
, . . , .