日本語版
最新ニュース
科学&テクノロジー

aartaka/pretty.c: C を ✨Pretty✨ と Lua/Lisp/Python 風の外観にする

Pretty C は、C と互換性のある新しいスクリプト言語です。Pretty C は、動的型付け、汎用反復、リソース追跡、その他の優れた機能によってプログラムを強化します。また、C およびそのすべてのライブラリと下位互換性があります。 Lua、Python、JavaScript、Lisp からインスピレーションを受けています。素朴な再実装方法は次のとおりです head Pretty C のユーティリティは次のようになります。 #include "pretty.h" int main (int argc, string argv[]) { if (argc above 1) with (fclose, f, fopen(argv[1], "r")) fortimes (line, 10) with (free, buf, vector(200,…

aartaka/pretty.c: C を ✨Pretty✨ と Lua/Lisp/Python 風の外観にする

1729746375
2024-10-24 03:01:00

Pretty C は、C と互換性のある新しいスクリプト言語です。Pretty C は、動的型付け、汎用反復、リソース追跡、その他の優れた機能によってプログラムを強化します。また、C およびそのすべてのライブラリと下位互換性があります。 Lua、Python、JavaScript、Lisp からインスピレーションを受けています。素朴な再実装方法は次のとおりです head Pretty C のユーティリティは次のようになります。

#include "pretty.h"

int main (int argc, string argv[])
{
    if (argc above 1)
        with (fclose, f, fopen(argv[1], "r"))
            fortimes (line, 10)
                with (free, buf, vector(200, char, 0))
                    when (fgets(buf, 200, f))
                        then print(buf)
                        otherwise 0;
    else
        println("Please provide an input file");
    return EXIT_SUCCESS;
}

Pretty C の目標は次のとおりです。

  • C 開発者に糖尿病による心臓発作を引き起こすほど大量の糖衣構文を提供します。
  • Lua、Python、JavaScript、Ruby、その他多数の言語を非推奨にします。Pretty C は究極のスクリプト言語ですが、超高速で強力に型指定されているためです。
  • ヘッダーを 1 つだけ含めます (はい、Pretty C はヘッダーのみのライブラリです)
    #include– 任意の C ファイルから使用可能!)、あらゆるコードベースを初心者に優しいコードベースに変えることができます。

リポジトリをチェックアウトする

git clone https://github.com/aartaka/pretty.c

または単にコピーするだけです pretty.h ファイル – Pretty C はヘッダーのみのライブラリであるため、

ドロップしたディレクトリ内の任意のファイルから pretty.h に。または、実際には任意のファイルから、Pretty C へのパスをインクルードとして指定した場合 (-I) パス。

ここでは、C ヒップを再び作るための美しい変更をすべて紹介します。

付属の標準ヘッダー

  • stdbool.h かなりのブール値の場合: truefalse、 そして bool
  • stdint.h のような固定幅整数型の場合 uint64_t
  • iso646.h 通常の演算子に代わる読みやすい代替演算子: and のために && そして or のために ||。きちんとした!

これらは誰もが定義しているので、なぜそれらを提供しないのでしょうか?

  • max そして min 2 つの数字の。
  • len 配列の長さの場合。
  • default フォールバック値を提供するため。
  • limit 適切な値の範囲を確保するため。
  • between 数値が範囲内にあるかどうかを確認します。
  • divisible 数値が別の数値で割り切れるかどうかを確認します。

タイプエイリアス:

  • string == char*
  • byte == char
  • bytes == char*
  • any == void*
  • 整数のショートカット:
    • uchar
    • ushort
    • uint
    • ulong

主に Lua と Lisp をモデルにしています:

  • eq、 なぜなら iso646.h しか持っていない not_eq
  • bitnot そして bitxor 以前は一貫性なく呼び出されていた操作 (compl そして xor それぞれ) iso646.h
  • belowaboveupto、 そして downto 比較演算子。
  • evenoddpositivenegativezero、 そして empty 数値/データの述語として。
  • nil のために NULL
  • until 否定されたものに対して while
  • elif のために else if
  • ifnt のために if(!...)
  • repeat Lua のエイリアスとして do
  • done そして pass のエイリアスとして break そして continue、 それぞれ。
  • always、無限(イベント?サーバー?)ループを作成できるようにします
always println("After all this time?");
  • そして never そして comment 1 つのキーワードだけで一部のコードをコメントアウトし、コンパイラーによる分析/最適化を可能にします ( クロージュア comment 形状):
never println("This never runs, but never gets outdated, because compiler will shout at you if it does.");

型推論 (GCC、Clang、または C23+)

はい、できます

var t = time(0);
let lt = localtime(&t);
local at = asctime(lt);
println(at);

プリティCさんと。

print フィードしたものは何でも印刷します。 println の後に改行を追加します。

println(3.1);
print("Hello world!n");

いろいろ比較してみよう!

equal("NA", line); // true
equal(0.3, 0.2 + 0.1); // true

三項は恐ろしいので、プレーンテキストを追加しても問題はありません。 if そして else が採用されていますが、Python/Lisp によく似た適切な言語代替手段があります。

return when some_condition
       then do_something()
       other do_something_else();

以下は三項です。

  • when 空の文字列に展開され、読みやすくするためにのみ提供されます。
    • unless に拡大します not ~のネガティブバージョンになる when
  • then に拡大します ?
  • other / otherwise に拡大します :

それもあります only いつのために otherwise 句は不要です:

return when done()
       then 42 only;

そして otherwhen 次の条件に向けて

return when c is 'A'
       then 'a'
       otherwhen c is 'B'
       then 'b' only;

これらのマクロは特定のエイリアスです for ループ パターン。それぞれが頻繁に発生するパターンの一部を抽象化します。 for ループを使用します。

foreach (var, type, length, ...)

これは、可変長引数式に初期化された配列またはメモリ領域を調べます。それを繰り返すたびに、 var は、それぞれの配列要素へのポインタに設定されます。はい、ポインターです。これにより、必要に応じて要素をその場で変更できます。

foreach (i, int, 10, vector(10, int, 1, 2, 3, 3, 4, 5))
        println(*i);

の使用法も示しています vector

forthese (var, type, ...)

提供された可変引数を反復処理し、それぞれをバインドします。 type-d
var。上記のループは次のように変換できます。

forthese (i, int, 1, 2, 3, 3, 4, 5)
        println(i);

0 から何らかの正の数に変化するケースがよくあります。かなりの時間を節約できます

for (int i = 0; i  28; i++)
        println(i+1);

それをシンプルに変える

fortimes (i, 28)
        println(i+1);
println("28 stab wounds, you didn't want to leave him a chance, huh?");

forrange (var, init, target)

以下の範囲の数値を反復処理します。 init
target。パイソン風。これは摂氏から華氏への変換ループです。 forrange:

forrange (c, -10, 20)
        printf("Celsius %i = Fahrenheit %fn", c, (32 + (c * 1.8)));

ご了承ください init そして target は、符号付きまたは符号なしの任意の整数です。そして init よりも大きいかもしれない target この場合、反復ステップによって変数が減少します。

forrangeby (var, type, init, target, by)

反復する type-d var から itertarget、ステップバイ by 毎回。パイソン風。

forrangeby (x, double, 1.0, 10.0, 0.5)
        println(x);

これらにより、典型的なパターンに対して迅速な割り当てが可能になります。主に C++ をモデルにしています。

C++ new 演算子は優れているので、C で同様のものがあっても問題はありませんね?これ以上質問する必要はありません。

struct ListNode {
        int val;
        struct ListNode *next;
};

struct ListNode *node = new(struct ListNode, 2, new(struct ListNode, 1, nil));

または、必要に応じて、さらに構文を上に追加することもできます。

#define cons(val, ...) new(struct ListNode, val, __VA_ARGS__)
cons(2, cons(1, nil));

vector (length, type, ...)

またC++。 std::vector は非常に便利で多用途なデータ構造であり、推論が簡単です。このマクロは、C++ のマクロほど機能が優れているわけではありませんが、「これだけの要素とこれらの内容を含む配列を割り当てる」というよくあるパターンを簡素化します。

double *vec = vector(10, double, 1, 2, 3, 4, 5);

気に入らない場合に備えて freeリソースを -ing し、より派手な C++ 名を優先します。

それ以外は同じ free

これらは、新しいローカル バインディングを確立し、遅延計算を保証するか、またはその後のブロックに作用します。

lambda (ret, name, ...) (GCC、Clang、または C++)

ネストされた関数/ラムダ/クロージャが C に登場!

int *arr = vector(10, int, 23423, 23423, 234, 5233, 6, 4, 34, 643, 3, 9);
lambda (int, cmp, int *a, int *b) {
        return *a - *b;
};
qsort(arr, 10, sizeof(int), cmp);
// arr becomes {3, 4, 6, 9, 34, 234, 643, 5233, 23423, 23423}

これにより、解放手順 (close)事前に。特に動的に割り当てられたオブジェクトやファイル指定子に役立ちます。

with (fclose, file, fopen("hello.txt", "w"))
        fprintf(file, "Hello world!n");

欠点の 1 つは、バインドされていることです。 var です void *したがって、使用する前に型を強制する必要があるかもしれません。

次のブロックの後に実行されるコードをオフロードします。 Go のように関数の最後ではありません。 不可能 C で実装するのは難しい。それでもかなりの C defer 十分役に立ちます。

派手なエラー処理が C になりました。リファクタリングされた例 エラー番号参照:

try log(0.0);
catch (NOERR)
        println("No error.");
catch (EDOM, ERANGE)
        println("Math error!");

NOERR そして NOERROR エラースイッチケースの便宜のために、Pretty C によっても提供されています。

#aartakapretty.c #を #Pretty #と #LuaLispPython #風の外観にする

執筆者について: nipponese

Nipponese News編集部は、国内外のニュースを日本語で分かりやすくお届けします。