Bagian pertama dengan persyaratan fungsional ada di
sini .
Diklaim sebagai bahasa pemrograman dengan memperhatikan keandalan.
Secara Alfabet - Oberon Aktif, Ada, BetterC, IEC 61131-3 ST, Safe-C.
Seketika, penafian (alasan) tidak berarti kampanye "semua di sisi kiri", dan ulasannya agak akademis - bahasanya mungkin tidak hanya memiliki lingkungan pengembangan modern yang didukung secara aktif, tetapi bahkan kompiler untuk platform Anda.
Di sisi lain, untuk bahasa yang dimaksud ada kompiler open source, dan dengan tingkat pengembangan perangkat lunak saat ini - dengan minat, sintaksis yang tidak terlalu rumit memungkinkan Anda membuat kompiler pribadi dan mengintegrasikan ke dalam beberapa jenis Eclipse dengan backlight dan parser.
Sebagai indikator kejelasan bahasa, saya memilih implementasi tugas multi-utas Dijkstra yang terkenal tentang para filsuf makan. Implementasinya ada di buku teks pada bahasa dan di forum, yang memfasilitasi pekerjaan saya - tetap hanya untuk beradaptasi. Misalnya,
artikel habr terbaru tentang C ++ modern berisi implementasi di C ++ 17 untuk perbandingan.
Active Oberon (2004)
Itu dibuat dengan mata untuk pengalaman Pascal, Modula, Oberons sebelumnya sejak tahun 1988, Java, C #, Ada, serta pengalaman praktis dalam aplikasi. Ini memiliki implementasi dalam bentuk
OS A2 , yang dapat bertindak sebagai runtime di atas * nix atau Windows.
Sumber A2 dan kompiler untuk tautan .
Ada juga proyek
Oberon2 ke C Compiler (OOC) yang tidak terikat dengan lingkungan Oberon. Ini adalah dialek yang sedikit berbeda, perbedaannya dijelaskan di bawah ini.
Fitur utama Oberon adalah singkatnya spesifikasi. Ini adalah 16 halaman di pangkalan Oberon-2 plus 23 halaman pada ekstensi aktif multi-utas.
Sintaks yang sederhana dan jelas yang tidak termasuk kesalahan yang jelas.
Pengidentifikasi peka terhadap huruf besar-kecil.
OOP dengan benda di heap dengan pengumpul sampah (GC).
Ini berbeda dari pendahulunya dalam sintaks OOP yang lebih akrab dalam bentuk Instance.Method (dulu Metode (Instance)) dan dukungan untuk multithreading dengan sinkronisasi primitif.
Tidak ada pengiriman dinamis dalam implementasi OOP, yang dapat dengan mudah menyebabkan situasi - mereka lupa menambahkan pemrosesan untuk tipe baru.
Streaming dapat diberikan prioritas dan tinggi / waktu nyata mereka tidak terganggu oleh GC. String dalam bentuk array UTF-8.
Rantime (Oberon System) memberikan peluang menarik untuk memulai kembali prosedur / modul / utas yang gagal jika terjadi kesalahan runtime - pengalamatan memori, atau, misalnya, integer overflow.
Kerugiannya adalah kurangnya RAII, dan penanganan kesalahan yang mudah - semua melalui kode pengembalian, dengan pengecualian opsi di bawah ini.
Oberon-2 OOC
Ini lebih nyaman untuk eksperimen, karena Oberon tidak memerlukan OS - itu dikompilasi dalam ANSI C dan tidak ada masalah interoperabilitas. Perbedaan dari versi Aktif - tidak ada bahasa multithreading bawaan - sebaliknya ada modul untuk bekerja dengan PThreads, tetapi ada UTF16, modularitas hirarkis dan modul sistem untuk bekerja dengan pengecualian.
Modul 3
Ada juga kerabat dari cabang pengembangan yang sedikit berbeda dalam bentuk Modula-3. Itu dibuat atas dasar Oberon yang bertentangan dengan Ada yang terbelakang.
Implementasinya ada di sini .
Dibandingkan dengan Active Oberon, generik dan pengecualian ditambahkan, ada perpustakaan untuk pekerjaan praktis dengan Unicode, GUI, dan bahkan Postgress. Integrasi yang disederhanakan dengan C. Semantik multithreading lainnya. RAII sebagai DENGAN (mirip dengan menggunakan dalam C #).
Tetapi tampaknya pengembangan Modula 3 berhenti pada 2010.
Penafian. Setelah meluncurkan WinAOS, saya mengalami TRAPs (alias batalkan / stacktrace atau runtime error) tiba-tiba - bahkan task manager tidak berfungsi dengan benar, dan meskipun sistem / runtime tidak crash - tetapi hanya aplikasinya, saya ragu bahwa keandalan ditentukan oleh bahasa. pemrograman = (
Juga, AOC cukup mandiri, dengan pendekatannya terhadap pembangunan.
Sumber untuk Filsuf MakanMODULE Philo; IMPORT Semaphores := Example8, Out; CONST NofPhilo = 5; VAR fork: ARRAY NofPhilo OF Semaphores.Semaphore; i: LONGINT; TYPE Philosopher = OBJECT VAR first, second: LONGINT; PROCEDURE & Init(id: LONGINT); BEGIN IF id # NofPhilo-1 THEN first := id; second := (id+1) ELSE first := 0; second := NofPhilo-1 END END Init; PROCEDURE Think; BEGIN Out.Int(first); Out.String(".... Think...."); Out.Ln; END Think; PROCEDURE Eat; BEGIN Out.Int(first); Out.String(".... Eat...."); Out.Ln; END Eat; BEGIN LOOP Think; fork[first].P; fork[second].P; Eat; fork[first].V; fork[second].V END END Philosopher; VAR philo: ARRAY NofPhilo OF Philosopher; BEGIN FOR i := 0 TO NofPhilo DO NEW(fork[i], INTEGER(i)); NEW(philo[i], i); END; END Philo. Philo.Philo1 ~
Ada (1980, standar terakhir 2016 yang valid)
Sebenarnya, pada pandangan pertama ada semua yang saya inginkan.
Dan bahkan sedikit lagi - ada angka dengan perhitungan floating-point yang tepat. Misalnya, ada penjadwal thread realtime, pertukaran lintas-thread, dan subset resmi dari bahasa SPARK. Dan masih banyak lagi.
Saya berpikir bahwa jika keandalan Ada membutuhkan yang bertanduk, itu akan dilampirkan dengan instruksi untuk memanggil dalam situasi yang sulit =)
Implementasi -
GNUTaya Ada , berkembang, terstandarisasi ISO / IEC.
Standar memberikan implementasi dengan GC, tetapi untuk opsi yang dikompilasi sering tidak diimplementasikan. Manajemen memori manual diperlukan - dan di sini kesalahan pemrogram dimungkinkan. Namun, bahasa diarahkan untuk menggunakan tumpukan default dan ada konsep tipe yang dikelola dengan destruktor. Anda juga dapat menentukan implementasi GC, pelepasan otomatis, atau penghitungan referensi untuk setiap tipe data.
Ada Referensi Manual 2012 berisi 950 halaman.
Kerugian Ada, selain kompleksitas, adalah verbositasnya yang berlebihan, yang, bagaimanapun, disusun demi keterbacaan. Karena kekhususan model keamanan bahasa, integrasi dengan perpustakaan asing menjadi sulit.
Situs
Ada-ru memiliki artikel terjemahan ulasan yang bagus - tautan pertama.
Sumber untuk Filsuf Makan BetterC (dlang subset 2017, original D - 2001, D 2.0 - 2007)
Implementasi paling modern dari yang dipertimbangkan. Deskripsi lengkap bahasanya cukup panjang - 649 halaman -
lihat situs aslinya .
Sebenarnya, ini adalah bahasa D, tetapi dengan pembatasan dengan saklar -betterC. Kenapa begitu ?!
Karena perpustakaan standar D adalah Phobos, yang dikembangkan oleh Alexandrescu dan ternyata sangat licik, sepenuhnya dibangun di atas templat. Kunci dari topik ini adalah Phobos tidak terkendali dalam hal konsumsi memori.
Hal paling penting yang hilang dalam mode BetterC adalah multithreading, GC, string, kelas (struktur tetap - fungsionalitasnya dekat - hanya di stack) dan pengecualian (RAII dan coba-akhirnya tetap).
Namun dimungkinkan untuk menulis bagian dari program dalam D penuh, dan bagian penting dalam D-BetterC. Ada juga fungsi atribut sistem untuk mengontrol tidak digunakannya efek berbahaya: pure
safe @nogc.
Pembenaran rezim dari pencipta bahasa.
Dan
kemudian pemerasan - apa yang terputus dan apa yang tetap tersedia.
String terkandung dalam Phobos - dan upaya untuk menggunakannya dalam BetterC menghasilkan kesalahan inferansi instantiasi templat pada operasi dasar seperti menghasilkan string ke konsol atau penggabungan. Dan dalam mode D penuh, garis-garis pada heap juga tidak berubah, oleh karena itu operasi dengan mereka menyebabkan kekacauan memori.
Saya harus menemui keluhan tentang bug di kompiler beberapa kali. Namun, yang tidak mengejutkan untuk bahasa yang bersaing dalam kompleksitas dengan C ++. Saat menyiapkan artikel, saya juga harus menghadapi 4 kesalahan - dua muncul ketika mencoba membangun dlangide dengan kompiler baru dan pasangan saat porting masalah filsuf (misalnya, crash ketika menggunakan beginthreadex).
Mode ini baru saja muncul dan kesalahan yang disebabkan oleh pembatasan mode BetterC sudah keluar pada tahap penautan. Untuk mengetahui hal ini sebelumnya, fitur bahasa apa yang dipangkas dengan tepat - seringkali harus melakukannya secara langsung.
Sumber untuk Filsuf Makan Sebagai perbandingan, sumbernya penuh D.Pada roset Anda juga dapat melihat opsi untuk bahasa lain.
IEC 61131-3 ST (1993, standar terbaru 2013)
Bahasa pemrograman khusus untuk mikrokontroler. Standar menyiratkan 5 opsi pemrograman, tetapi menulis aplikasi misalnya dalam logika tangga masih merupakan petualangan. Oleh karena itu, kami fokus pada satu opsi - teks terstruktur.
Teks standar GOST R IEC 61131-3-2016 - 230 halaman.
Ada implementasi untuk PC / x86 dan ARM - dan yang komersial, yang paling terkenal adalah
CODESYS (sering juga disublisensikan dengan nama yang berbeda) dan siaran
terbuka - Beremiz melalui C.
Karena ada integrasi dengan C, sangat mungkin untuk menghubungkan perpustakaan yang diperlukan untuk pemrograman terapan. Di sisi lain, di bidang ini diterima bahwa logika berputar secara terpisah dan hanya berfungsi sebagai server data untuk program atau sistem lain - antarmuka dengan operator atau DBMS yang sudah dapat ditulis pada apa pun - tanpa persyaratan waktu nyata atau bahkan sementara secara umum ...
Pemrograman multithread untuk program pengguna telah muncul relatif baru - di mikrokontroler ini tidak diperlukan sebelumnya.
Tipe casting sebagian besar hanya eksplisit (santai dalam standar terbaru). Tetapi kontrol overflow tergantung implementasi.
Dalam edisi standar terbaru, OOP muncul. Penanganan kesalahan dilakukan oleh penangan interupsi kustom.
Kita dapat mengatakan bahwa tidak ada alokasi memori dinamis untuk pengguna. Ini secara historis terjadi - jumlah data yang diproses oleh mikrokontroler selalu konstan terbatas dari atas.
Sumber (tidak diverifikasi) Philo_2: Philosopher; Philo_3: Philosopher; Philo_4: Philosopher; Philo_5: Philosopher; END_VAR RESOURCE Station_1 ON CPU_1 TASK Task_1 (INTERVAL := T#100MS, PRIORITY := 1); TASK Task_2 (INTERVAL := T#100MS, PRIORITY := 1); TASK Task_3 (INTERVAL := T#100MS, PRIORITY := 1); TASK Task_4 (INTERVAL := T#100MS, PRIORITY := 1); TASK Task_5 (INTERVAL := T#100MS, PRIORITY := 1); PROGRAM Life_1 WITH Task_1: Philo_1(Name := 'Kant', 0, 1, Forks); PROGRAM Life2 WITH Task_2: Philo_2(Name := 'Aristotel', 1, 2, Forks); PROGRAM Life3 WITH Task_3: Philo_3(Name := 'Spinoza', 2, 3, Forks); PROGRAM Life4 WITH Task_4: Philo_4(Name := 'Marx', 3, 4, Forks); PROGRAM Life5 WITH Task_5: Philo_5(Name := 'Russel', 4, 0, Forks); END_RESOURCE END_CONFIGURATION FUNCTION_BLOCK Philosopher; USING SysCpuHandling.library; VAR_INPUT Name: STRING; Left: UINT; Right: UINT; END_VAR VAR_IN_OUT Forks: USINT; END_VAR VAR Thinking: BOOL := TRUE; Hungry: BOOL; Eating: BOOL; HaveLeftFork: BOOL; TmThink: TON; TmEating: TON; END_VAR TmThink(In := Thinking; PT := T#3s); TmEating(In := Eating; PT := T#5s); IF Thinking THEN Thinking := NOT TmThink.Q; Hungry := TmThink.Q; ELSIF Hungry IF HaveLeftFork IF SysCpuTestAndSetBit(Address := Forks, Len := 1, iBit := Right, bSet := 1) = ERR_OK THEN Hungry := FALSE; Eating := TRUE; ELSE RETURN; END_IF ELSIF IF SysCpuTestAndSetBit(Address := Forks, Len := 1, iBit := Left, bSet := 1) = ERR_OK THEN HaveLeftFork := TRUE; ELSE RETURN; END_IF END_IF ELSIF Eating IF TmEating.Q THEN Thinking := TRUE; Eating := FALSE; HaveLeftFork := FALSE; SysCpuTestAndSetBit(Address := Forks, Len := 1, iBit := Right, bSet := 0); SysCpuTestAndSetBit(Address := Forks, Len := 1, iBit := Left, bSet := 0); END_IF END_IF END_FUNCTION_BLOCK
Safe-C (2011)
Eksperimental C dengan menghilangkan chip berbahaya dan dengan penambahan modularitas dan multithreading.
Situs proyekDeskripsi sekitar 103 halaman. Jika Anda menyoroti perbedaan dari C -
sangat sedikit, sekitar 10 .
Bekerja dengan array dan pointer adalah memori dinamis dan aman dengan penghitungan referensi otomatis - dengan rilis rilis ganda dan tautan menggantung.
Pustaka standar memiliki sekumpulan fungsi minimal untuk GUI, multithreading, fungsi jaringan (termasuk server http).
Tetapi - implementasi ini hanya untuk Windows x86. Meskipun kompiler dan kode perpustakaan terbuka.
Sebagai bagian dari tugas penelitian lain, saya mengumpulkan tata letak server Web yang mengumpulkan data dari sensor IoT: modul eksekutif 75 Kb, dan set memori parsial <1 MB.
Sumber untuk Filsuf Makan from std use console, thread, random; enum philos (ushort) { Aristotle, Kant, Spinoza, Marx, Russell, }; const int cycles = 10; const ushort NUM = 5; uint lived = NUM; packed struct philosopher // 32-bit { philos name; byte left, right; } philosopher philo_body[NUM]; SHARED_OBJECT forks[NUM]; void philosopher_life(philosopher philo) { int age; for (age = 0; age++ < cycles; ) { printf("%s is thinking\n", philo.name'string); delay((uint)rnd(1, 100)); printf("%s is hungry\n", philo.name'string); enter_shared_object(ref forks[philo.left]); enter_shared_object(ref forks[philo.right]); printf("%s is eating\n", philo.name'string); delay((uint)rnd(1, 100)); leave_shared_object(ref forks[philo.right]); leave_shared_object(ref forks[philo.left]); } printf("%s is leaving\n", philo.name'string); InterlockedExchange(ref lived, lived-1); } void main() { philos i; assert philosopher'size == 4; philo_body[0] = {Aristotle, 0, 1}; philo_body[1] = {Kant, 1, 2}; philo_body[2] = {Spinoza, 2, 3}; philo_body[3] = {Marx, 3, 4}; philo_body[4] = {Russell, 0, 4}; for (i = philos'first; i <= philos'last; i++) { assert run philosopher_life(philo_body[(uint)i]) == 0; } while (lived > 0) sleep 0;
Akhirnya -
tabel ringkasan kepatuhan dengan persyaratan fungsional.
Tentunya saya ketinggalan atau salah mengartikan sesuatu - jadi perbaiki.
Sumber dari artikel di github .