{"id":37976663,"url":"https://github.com/ab25cq/neo-c","last_synced_at":"2026-01-16T18:31:10.636Z","repository":{"id":62293691,"uuid":"186356105","full_name":"ab25cq/neo-c","owner":"ab25cq","description":"neo-c is C + GC compiler. It has reffrence count GC with memory leak detector. self-hosted with zero memory leaks.  It can outputs the code depends on standard C libraries only.","archived":false,"fork":false,"pushed_at":"2026-01-11T08:22:33.000Z","size":143151,"stargazers_count":104,"open_issues_count":0,"forks_count":7,"subscribers_count":3,"default_branch":"master","last_synced_at":"2026-01-11T08:30:06.683Z","etag":null,"topics":["c","compiler","oop","programming-language"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/ab25cq.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2019-05-13T06:10:19.000Z","updated_at":"2026-01-11T08:22:36.000Z","dependencies_parsed_at":"2026-01-08T22:08:39.520Z","dependency_job_id":null,"html_url":"https://github.com/ab25cq/neo-c","commit_stats":null,"previous_names":["ab25cq/neo-c"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/ab25cq/neo-c","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ab25cq%2Fneo-c","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ab25cq%2Fneo-c/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ab25cq%2Fneo-c/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ab25cq%2Fneo-c/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/ab25cq","download_url":"https://codeload.github.com/ab25cq/neo-c/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/ab25cq%2Fneo-c/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28480886,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-16T11:59:17.896Z","status":"ssl_error","status_checked_at":"2026-01-16T11:55:55.838Z","response_time":107,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["c","compiler","oop","programming-language"],"created_at":"2026-01-16T18:31:10.334Z","updated_at":"2026-01-16T18:31:10.620Z","avatar_url":"https://github.com/ab25cq.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# neo-c\n\nThis has Rerfference Count GC, and includes the generics collection libraries.\n\nリファレンスカウントGCがありコレクションライブラリを備えてます。\n\nversion 0.8.3\n\n``` C\n#include \u003cneo-c.h\u003e\n\nclass sData\n{\n    int a;\n    int b;\n    \n    void show()\n    {\n        printf(\"a %d b %d\\n\", self.a, self.b);\n    }\n};\n\nclass sData2 extends sData\n{\n    int c;\n    \n    void show()\n    {\n        printf(\"a %d b %d c %d\\n\", self.a, self.b, self.c);\n    }\n};\n\nint main() \n{\n    var data = new sData2 { a:123, b:234, c:345 };\n    \n    data.show();  // a 123 b 234 c 345\n    \n    puts(\"HO!\" * 3);             // HO!HO!HO!\\n\n\n    return 0;\n}\n```\n\n```\n#include \u003cneo-c.h\u003e\n\nint main(int argc,char** argv)\n{\n    \"ABC\".scan(\".\"); // [A,B,C]\n    \"ABC\".index_regex(\"b\", -1, ignore_case:true); // 1\n    \"fooBAR\".match(\"bar\", ignore_case:true); // true\n    \"a1b2c3\".split(\"\\\\d+\"); // [a,b,c]\n    \"Hello\".sub(\"l+\", \"L\"); // HeLo\n    \"ABCABC\".sub_block(\"ABC\") { string(\"X\") }; // XX\n    \"123 456 789\".scan_block(\"[0-9][0-9][0-9]\") { it.substring(0, 1) }; // [1,4,7]\n\n    return 0;\n}\n```\n\nneo-c outputs c source with standard C libraries only. So you can use this for micro computer or other system working c language.\n\n# インストール\n\nsh fast_build.sh will automatically install the necessary packages.\n\nSupports Linux, MacOS (Darwin), raspberry pi, and baremetal.\n\nsh fast_build.shとすると自動的に必要なパッケージがインストールされます。\n\nLinuxとMacOS(Darwin), raspberry pi, ベアメタルをサポートしています。\n\nsudoとgitとwhichは事前にインストールしてください。\n\nPlease install sudo , git and which before the build.\n\n```\ngit clone https://github.com/ab25cq/neo-c\ncd neo-c\nsh fast_build.sh\nsh clean-self-host.sh\n```\n\nTo install a vi clone called vin, a string processing interpreter called zed, a console filer called mf, and an original shell called shsh, do the following:\n\nvinというviクローン、zedという文字列処理インタプリタ、mfというコンソールファイラ、shshというオリジナルのシェルをインストールするには以下のようにします。\n\n```\nsh all_build.sh\n```\n\n# Histories\n\n```\n0.8.3.0 tested on PICO\n0.8.2.5 CPP has been wrritten by codex. And more compatibilities C lang. Almost C header can be work.\n0.8.2.1 Refactoring\n0.8.2.0 remove GC heap area. This system use calloc and free only. So you can debug with valgrind.\n0.8.1.6 GC algorithm bug has been fixed. Some code can't be work maybe, but more properly heap algorith has come.\n0.8.1.5 Compiletime Reflection\n0.8.1.4 Compiletime Reflection\n0.8.1.3 More readable output c source. And encount a bug fixed.\n0.8.1.2 no type check field, variable, and function. More optimized the output C source\n0.8.1.1 clang like option implemented.\n0.8.1 Object initializer and number object initializer\n0.8.0 Tested on x86 Fedora. There are some bugs. Fixed it.\n0.7.5 Tested on some linux distributeion. all worked.\n0.7.2 Linux(amd64, x86_64) tested.\n0.7.1 Linux tested. Atomic supported. -std=c11 supported\n0.7.0 more c compatiblities, array, pointer.\n0.6.0 more c compatiblities, array, pointer.\n0.5.5 more c compatiblities\n0.5.2 more c compatiblities\n0.5.1 more c compatiblities\n0.5.0 Reborn\n```\n\n# Sample\n\n```\n#include \u003cneo-c.h\u003e\n\nint main(int argc, char** argv)\n{\n    int a[5] = { 3, 2, 1, 2, 5 };\n    \n    var li = new list\u003cint\u003e.initialize_with_values(5, a);\n    \n    var li2 = li.sort_with_lambda(int lambda(int left, int right) {\n        if(left == right) {\n            return 0;\n        }\n        else if(left \u003c right) {\n            return -1;\n        }\n        else {\n            return 1;\n        }\n    });\n    \n    var li3 = li.filter { it \u003c 3 }.sort().map { it.to_string() + \"0\" }.join(\"+\").split(\"\\\\\\+\");\n    \n    li3.to_string().puts();\n    \n    \"A,B,C\".split(\",\").join(\"\\n\").puts();\n    \n    \"A,B,C,D,E\".split(\",\").add(s\"F\").join(\"+\").to_string().puts();\n    \n    [1,2,3,4,5].add(6).add(3).add(2).add(10).add(9).sort().map { it.to_string() }.join(\"\\n\").to_string().puts();\n    \n    \"ABCDEFGJHI\".scan(\".\").map { it * 5 }.join(\"\\n\").puts();\n    \n    return 0;\n}\n```\n\n# Language specifications\n\nThe syntax is almost the same as C language. It may not be POSIX compliant. If you do not #include \u003cneo-c.h\u003e, you can use it as a normal C compiler.\n\n文法はC言語とほとんど一緒です。POSIXに準拠しているとは言えないかもしれません。#include \u003cneo-c.h\u003eをしないと普通のCコンパイラとして使えます。\n\n# HELLO WORLD\n\n```\n\u003e vim a.c\n#include \u003cstdio.h\u003e\n\nint main()\n{\n    puts(\"HELLO WORLD\");\n    return 0;\n}\n\u003e neo-c a.c\n\u003e ./a\nHELLO WORLD\n```\n\n# grammar\n\nIt is not POSIX compliant, but is compatible with the C language. I think most C header files can be included as is.\n\nPOSIXには準拠していませんが、C言語と互換性があります。大抵のCヘッダーファイルはそのままincludeできると思います。\n\n# Libraries\n\nThe grammar library includes list, map, tuple, buffer, and string. \n\nライブラリにはlist, map, tuple, buffer, stringがあります。\n\n# list\n\n```\n#incldue \u003cneo-c.h\u003e\n\nint main(int argc, char** argv)\n{\n    list\u003cchar*\u003e*% li = [\"AAA\", \"BBB\", \"CCC\", \"DDD\", \"EEE\"];\n    \n    foreach(it, li.sublist(0,3)) {   // \"AAA\"\\n\"BBB\"\\n\"CCC\"\n        puts(it);\n    }\n    \n    li.add(\"FFF\").add(\"GGG\");\n    \n    foreach(it, li) {   // \"AAA\"\\n\"BBB\"\\n\"CCC\"\\n\"DDD\"\\n\"EEE\"\\n\"FFF\"\\n\"GGG\"\\n\n        puts(it);\n    }\n    \n    return 0;\n}\n```\n\nli.each { puts(it); } can also access all list elements, but break, continue, and return cannot be used. It is more efficient to use foreach. foreach takes the first argument as the name of the variable containing the element, and the second argument as the list.\n\nforeach is implemented as a macro.\n\nli.each { puts(it); }としても全てのリストの要素にアクセスできますが、break, continu, returnが使えません。foreachを使った方が効率的にもいいです。foreachは第一引数が要素が入った変数の名前、第二引数がリストとなります。\n\nBelow is an explanation of all methods.\n\n以下は全メソッドの解説です。\n\n```C\nlist\u003cT\u003e*% initialize(list\u003cT\u003e*% self);\n```\n\nA constructor. It will be called by typing new list\u003cint\u003e();. Internally this is new list\u003cint\u003e.initialize();\nIt is an abbreviation of\n\nThe constructor must add a % to the first argument and add 1 to the reference count. If you do not add %, it will be determined that the heap can be freed and will be automatically freed. The return value must also be marked with a % to prevent it from being released.\n\nWrite return self; at the end of the constructor. It cannot be omitted.\n\nYou can easily write constructors by using the class function described later.\n\nコンストラクタです。new list\u003cint\u003e();とすれば呼び出されます。これは内部的にはnew list\u003cint\u003e.initialize();\nの略です。\n\nコンストラクタは第一引数に%をつけてリファレンスカウントを＋１しなければなりません。%をつけてないと解放していいヒープだと判断されて自動的にfreeされます。戻り値も%をつけて解放されないようにしないといけません。\n\nコンストラクタの最後にはreturn self;と書いてください。略することはできません。\n\n後述するclass機能を使えば、簡単にコンストラクタなどが記述できます。\n\n```C\nvar li = new list\u003cint\u003e.initialize();\nli.add(1).add(2).add(3);\n\nvar li2 = new list\u003cint\u003e();\nli2.add(1).add(2).add(3);\n```\n\n```C\nlist\u003cT\u003e*% initialize_with_values(list\u003cT\u003e*% self, int num_value, T\u0026* values) \n```\n\nCreates a list initialized with an array.\n\n配列で初期化されたリストを作成します。\n\n```C\nint values[3] = { 1, 2, 3 };\n\nvar li = new list\u003cint\u003e.initialize_with_values(3, values);\n```\n\n```C\nvoid finalize(list\u003cT\u003e* self) \n```\n\nIt's a destructor. Called when automatically deleted or manually deleted.\n\nデストラクターです。自動的に消去される場合、手動でdeleteする場合に呼ばれます。\n\n```C\nlist\u003cint\u003e* li = borrow gc_inc(new list\u003cint\u003e());\nli.add(1).add(2).add(3);\ndelete li;  // finalize is called. finalizeが呼ばれる\n```\n\ngc_inc increments the heap reference count by 1. borrow removes the heap from being automatically released and allows it to be assigned to a variable without a %. In this case the heap is managed manually and memory leaks will occur if you don't delete it. If a memory leak occurs When you run the program, the number of memory leaks will be displayed. If you compile with the -cg option, the stack frame at the location of the source file where the heap was generated will be displayed. I think it's easy to debug.\n\ngc_incはヒープのリファレンスカウントを+1します。borrowはヒープの自動解放対象から外し、%をつけない変数に代入できるようにします。この場合ヒープは手動で管理されて、deleteしないとメモリリークが発生します。 メモリリークが発生した場合プログラムを実行するとメモリリークの回数が表示されます。-cgオプションをつけてコンパイルするとヒープが生成されたソースファイルの位置のスタックフレームが表示されます。デバッグも容易だと思います。\n\n```C\nlist\u003cT\u003e*% clone(list\u003cT\u003e* self)\n```\n\n```C\nvar li = [1,2,3,4,5];\nvar li2 = clone li;   // cloneがよばれる\n```\n\nclone is a deep copy. Elements are also recursively cloned to duplicate memory. Since li and li2 have a reference count of 1, they will be automatically deleted when they exit the scope.\n\nIf you don't want to deep copy, follow the steps below.\n\ncloneはディープコピーです。要素も再起的にcloneされて、メモリが複製されます。liとli2はリファレンスカウントが1のためスコープを抜けると自動的に消去されます。\n\nディープコピーしたくない場合は以下です。\n\n```C\nvar li = [1,2,3,4,5];\nvar li2 = li;\n```\n\nli2 refers to the same thing as li. The heap of [1,2,3,4,5] has a reference count of 2, so when li and li2 exit the scope, the reference count is -2 and becomes 0, and [1,2,3,4,5 ] will be released.\n\nli2はliと同じものを指しています。[1,2,3,4,5]のヒープはリファレンスカウントが２のためliとli2がスコープを抜けるとその時リファレンスカウントが-2されて0になり、[1,2,3,4,5]は解放されます。\n\n```C\nvar li = [1,2,3,4,5];\nlist\u003cint\u003e* li2 = li;\n```\n\nIn this case, li and li2 refer to the same thing, but if li2 is accessed after li is released, a segmentation fault will occur.\n\nIn most cases, you can just add a % to the pointer. Reference count GC handles this well.\n\nこの場合もliとli2は同じものをさしていますが、liが解放された後にli2にアクセスするとセグメンテーションフォルトを起します。\n\nたいていの場合はポインタに%をつけておけば大丈夫です。リファレンスカウントGCがうまく対処してくれます。\n\n```C\nlist\u003cT\u003e* add(list\u003cT\u003e* self, T item)\n```\n\n```C\nvar li = [s\"ABC\", s\"DEF\", s\"GHQ\"]:\nli.add(s\"OPQ\");\n```\n\ns\"ABC\" is a string type character string and is allocated on the heap. The same is true for string(\"ABC\"). string is defined as typedef char*% string; and can also be treated as a simple char type array. So, putting(s\"ABC\"); will output ABC\\n. In this case, the generated string will be automatically freed.\n\nli is list\u003cstring\u003e*%. The reference count of s\"OPQ\" in li.add(s\"OPQ\"); is incremented by 1 and it is correctly stored in li. The stored s\"ABC\", s\"DEF\", s\"GHQ\", and s\"OPQ\" are correctly freed when li is freed.\n\ns\"ABC\"はstring型の文字列でヒープに確保されます。string(\"ABC\")としても同じです。stringはtypedef char*% string;と定義されていて、単なるchar型の配列としても扱えます。なのでputs(s\"ABC\");とするとABC\\nが出力されます。この場合生成された文字列は自動的にfreeされます。\n\nli is list\u003cstring\u003e*%. The reference count of s\"OPQ\" in li.add(s\"OPQ\"); is incremented by 1 and it is correctly stored in li. The stored s\"ABC\", s\"DEF\", s\"GHQ\", and s\"OPQ\" are correctly freed when li is freed.\n\nliはlist\u003cstring\u003e*%です。li.add(s\"OPQ\");のs\"OPQ\"はリファレンスカウントが+1されて、正しくliに格納されます。liが解放されるとき格納された、s\"ABC\", s\"DEF\", s\"GHQ\", s\"OPQ\"は正しくfreeされます。\n\n```C\nT pop_front(list\u003cT\u003e* self) \n```\n\nDelete the beginning of the list. If the heap is stored, the element will be freed. If it is a non-heap pointer such as \"ABC\", it will not be freed.\n\nリストの先頭を削除します。ヒープが格納されていた場合要素がfreeされます。ヒープでなく\"ABC\"などヒープでないポインタの場合はfreeされません。\n\n```C\nlist\u003cT\u003e* push_back(list\u003cT\u003e* self, T item)\n```\n\nSame as add.\n\naddと同じです。\n\n```C\nstring to_string(list\u003cT\u003e* self)\n```\n\n```C\n    var li = [\"ABC\", \"DEF\", \"GHQ\"];\n    puts(li.to_string());\n```\n\n[ABC,DEF,GHQ] will be output. to_string is executed on all elements. \n\nli is list\u003cchar*\u003e*%, which stores string pointers. The stored element will not be freed because it is not char*%.\n\n[ABC,DEF,GHQ]が出力されます。要素の全てにto_stringが実行されます。\n\nliはlist\u003cchar*\u003e*%で文字列のポインタが格納されています。char*%ではないため格納された要素はfreeされません。\n\n```C\nT\u0026 begin(list\u003cT\u003e* self) \nT\u0026 next(list\u003cT\u003e* self) \nbool end(list\u003cT\u003e* self) \n```\n\nDefined for foreach. Use this if you want to access all elements.\n\nforeachのため定義されてます。すべての要素にアクセスしたい場合使います。\n\n```C\nlist\u003cT\u003e* each(list\u003cT\u003e* self, void* parent, void (*block)(void*, T\u0026,int,bool*)) \n```\n\n```C\n    var li = [\"ABC\", \"DEF\", \"GHI\"];\n    \n    li.each {\n        puts(it);\n    }\n```\n\nABC\\nDEF\\nGHI\\n will be output. Method block arguments are stored in it, it2, and it3. In this case, it contains each element. Unlike foreach, break, continue, and return cannot be executed. Returning just escapes from the method block.\n\nABC\\nDEF\\nGHI\\nが出力されます。メソッドブロックはit,it2,it3にメソッドブロックの引数が格納されます。この場合itは各要素が入っています。foreachと違い、break, continue, returnは実行できません。returnするとメソッドブロックから脱出するだけです。\n\n```C\nT item(list\u003cT\u003e* self, int position, T default_value) \n```\n\n```C\n    var li = [\"ABC\", \"DEF\", \"GHI\"];\n    puts(li.item(0, null)); // ABC\n    puts(li.item(-1, null)); // GHI\n    puts(li.item(-9999, \"\")); // \"\"\n```\n\ndefault_value is the value returned in case of out-of-range access. If \u003c0, the elements counted from the back are returned.\n\ndefault_valueは範囲外アクセスの場合その値が返されます。\u003c0の場合は後方から数えた要素が返されます。\n\n```C\nint length(list\u003cT\u003e* self)\n```\n\n```C\n    var li = [1,2,3];\n    puts(li.length().to_string()); // 3\n```\n\nReturns the number of elements.\n\n要素の数が返されます。\n\n```C\nlist\u003cT\u003e* insert(list\u003cT\u003e* self, int position, T item)\n```\n\n```C\n    var li = [1,2,3];\n    \n    li.insert(1@position, 5@item); // [1,5,2,3]\n```\n\nAdd element to position. @postion is an annotation and is treated as a comment.\n\nli should be [1,5,2,3].\n\n要素をpositionに追加します。@postionはアノテーションでコメントとして扱われます。\n\nliは[1,5,2,3]となるはずです。\n\n```C\nlist\u003cT\u003e* reset(list\u003cT\u003e* self) \n```\n\n```C\n    var li = [1,2,3];\n    \n    li.reset();\n    \n    li.length().to_string().puts(); // 0\n```\n\nClears the element. 0 will be output.\n\n要素をクリアします。0が出力されます。\n\n```C\nlist\u003cT\u003e* remove(list\u003cT\u003e* self, T item) \n```\n\n```C\n    var li = [1,2,3];\n    \n    li.remove(3); // [1,2]\n    \n    li.to_string().puts();\n```\n\nDelete items that match item and equals.\nli is [1,2].\n\nitemとequalsがマッチするものを削除します。\nliは[1,2]です。\n\n```C\nlist\u003cT\u003e* delete(list\u003cT\u003e* self, int head, int tail)\n```\n\n```C\n    var li = [1,2,3,4,5];\n    \n    li.delete(3,-1); // [1,2,3]\n    li.delete(0,1); // [2,3];\n```\n\nDelete what is in the range. -1 is the tail.\nli is [1,2,3].\n\n範囲に入っているものを削除します。-1は末尾です。\nliは[2,3]です。\n\n```C\nlist\u003cT\u003e* replace(list\u003cT\u003e* self, int position, T item)\n```\n\n```C\n    var li = [1,2,3,4,5];\n    \n    li.replace(1, 7); // [1,7,3,4,5]\n```\n\nReplace the item.\nli is [1,7,3,4,5]. If the element is a heap, the reference count of the replaced element will be -1, and if the reference count is 0, it will be deleted.\n\nアイテムを置き換えます。\nliは[1,7,3,4,5]です。要素がヒープの場合置き換える要素はリファレンスカウントが-1されて、リファレンスカウントが0なら削除されます。\n\n```C\nint find(list\u003cT\u003e* self, T\u0026 item, int default_value) \n```\n\n```C\n    var li = [1,2,3,4,5];\n    \n    li.find(3, -1@default_value); // 2\n```\n\nReturns the position from the beginning of the element matched by equals. In this case it is 2. default_value is the value if not found.\n\nequalsがマッチする要素の先頭からの位置を返します。この場合2です。default_valueは見つからなかった場合の値です。\n\n```C\nbool equals(list\u003cT\u003e* left, list\u003cT\u003e* right)\n```\n\n```C\n    [1,2,3].equals([1,2,3]).to_string().puts(); // true\n```\n\nChecks whether the object has the same argument and content. Equals is executed for each element and returns true if it is true for all elements.\n\nオブジェクトが引数と内容が一緒か確認します。要素ごとにequalsが実行されすべての要素で真ならtrueを返します。\n\n```C\nlist\u003cT\u003e*% sublist(list\u003cT\u003e* self, int begin, int tail) \n```\n\n```C\n    [1,2,3,4,5].sublist(0,2); // [1,2]\n    [1,2,3,4,5].sublist(3,-1); // [4,5]\n    [1,2,3,4,5].sublist(3,-2); // [4]\n```\n\n\n```C\nT operator_load_element(list\u003cT\u003e* self, int position) \n```\n\n```C\n    var li = [1,2,3,4,5];\n    \n    printf(\"%d\\n\", li[3]); // 4\n    printf(\"%d\\n\", li[-1]); // 5\n    printf(\"%d\\n\", li[-9999]); // 0\n```\n\nIf the index is not found, 0 clear value returned.\n\nもしインデックスが見つからないなら0clearされた値が返されます。\n\n```C\nvoid operator_store_element(list\u003cT\u003e* self, int position, T item) \n```\n\n```C\n    var li = [1,2,3,4,5];\n    \n    li[0] = 123; // [123,2,3,4,5]\n```\n\n```C\nlist\u003cT\u003e*% operator_load_range_element(list\u003cT\u003e* self, int begin, int tail) \n```\n\n```C\n    var li = [1,2,3,4,5];\n    \n    li[0..2].to_string().puts(); // [1,2]\n    li[3..-1].to_string().puts(); // [4,5]\n```\n\n```C\nbool operator_equals(list\u003cT\u003e* self, list\u003cT\u003e* right) \n```\n\n```C\n    [1,2,3] === [1,2,3]; // true\n    [1,2,2] === [1,2,3]; // false\n```\n\nequals is called for each element.\n\n各要素にequalsが呼ばれます。\n\n```C\nbool operator_not_equals(list\u003cT\u003e* left, list\u003cT\u003e* right) \n```\n\n```C\n    [1,2,3] !== [1,2,3]; // false\n    [1,2,2] !== [1,2,3]; // true\n```\n\n```C\nbool contained(list\u003cT\u003e* self, T item) \n```\n\n```C\n    [1,2,3].contained(3); // true\n    [1,2,3].contained(4); // false\n```\n\n```C\nlist\u003cT\u003e*% merge_list_with_lambda(list\u003cT\u003e* left, list\u003cT\u003e* right, int (*compare)(T\u0026,T\u0026)) \nlist\u003cT\u003e*% merge_sort_with_lambda(list\u003cT\u003e* self, int (*compare)(T\u0026,T\u0026)) \nlist\u003cT\u003e*% sort_with_lambda(list\u003cT\u003e* self, int (*compare)(T\u0026,T\u0026)) \n```\n\n```C\n    [3,7,2,5].sort_with_lambda(int lambda(int left, int right) {\n        if(left \u003c right) {\n            return -1;\n        }\n        else if(left \u003e right) {\n            return 1;\n        }\n        else {\n            return 0;\n        }\n        \n        return 0;\n    }); // [2,3,5,7]\n```\n\nSort by lambda expression.\n\nlambda式でソートします。\n\n```C\nlist\u003cT\u003e*% merge_list(list\u003cT\u003e* left, list\u003cT\u003e* right) \nlist\u003cT\u003e*% merge_sort(list\u003cT\u003e* self) \nlist\u003cT\u003e*% sort(list\u003cT\u003e* self) \n```\n\n```C\n    [3,7,2,5].sort(); // [2,3,5,7]\n```\n\n```C\ntemplate\u003cR\u003e list\u003cR\u003e*% map(list\u003cT\u003e* self, void* parent, R (*block)(void*, T\u0026))\n```\n\n```C\n    [\"1\",\"2\",\"3\"].map { atoi(it) }  // [1,2,3]\n```\n\nExecutes an expression on each element and returns a list of results. \n\n各要素に式を実行して、その結果のリストを返します。\n\n```C\nlist\u003cT\u003e*% reverse(list\u003cT\u003e* self) \n```\n\n```C\n    [1,2,3].reverse(); // [3,2,1]\n```\n\n```C\nlist\u003cT\u003e*% uniq(list\u003cT\u003e* self) \n```\n\n```C\n    [8,8,2,2,3,3].uniq(); // [8,2,3]\n```\n\nDelete adjacent identical elements. It may not work unless you use sort().\n\n隣あった同じ要素を削除します。sort()しないとダメかもしれません。\n\n```C\nlist\u003cT\u003e*% filter(list\u003cT\u003e* self, void* parent, bool (*block)(void*, T\u0026))\n```\n\n```C\n    [1,2,3,4,5].filter { it \u003e 2 };  // [3,4,5]\n```\n\n```C\nlist\u003cT\u003e*% operator_add(list\u003cT\u003e*% left, list\u003cT\u003e*% right) \n```\n\n```C\n    [1,2,3] + [4,5]; // [1,2,3,4,5]\n```\n\n```C\nlist\u003cT\u003e*% operator_mult(list\u003cT\u003e* left, int right) \n```\n\n```C\n    [1,2,3] * 2; // [1,2,3,1,2,3]\n```\n\n```C\nstring join(list\u003cT\u003e* self, char* sep=\" \") \n```\n\n```C\n    [1,2,3].join(\"+\");    // 1+2+3\n```\n\n# map\n\nmap is a dictionary.\n\nmapは辞書です。\n\n```\n#include \u003cneo-c.h\u003e\n\nint main(int argc, char** argv)\n{\n    map\u003cchar*, int\u003e*% ma = new map\u003cchar*, int\u003e();\n    \n    ma.insert(\"AAA\", 1);\n    ma.insert(\"BBB\", 2);\n    ma.insert(\"CCC\", 3);\n    \n    foreach(it, ma) {\n        int item = ma[it];\n        \n        printf(\"element %s %d\\n\", it, item);\n    }\n    \n    return 0;\n}\n```\n\n```C\nmap\u003cT,T2\u003e*% initialize(map\u003cT,T2\u003e*% self)\n```\n\n```C\nvar ma = new map\u003cchar*,int\u003e();\nma.insert(\"AAA\", 1);\nma.insert(\"BBB\", 2);\nma.insert(\"CCC\", 3).insert(\"DDD\", 4);\n```\n\n```C\nmap\u003cT,T2\u003e*% initialize_with_values(map\u003cT,T2\u003e*% self, int num_keys, T\u0026* keys, T2\u0026* values) \n```\n\n```\n    char* keys[] = { \"AAA\", \"BBB\", \"CCC\", \"DDD\" };\n    int values[] = { 1, 2, 3, 4 };\n    \n    var ma = new map\u003cchar*,int\u003e.initialize_with_values(4, keys, values);\n```\n\n```C\nvoid finalize(map\u003cT,T2\u003e* self)\n```\n\n```C\nmap\u003cT, T2\u003e*% clone(map\u003cT, T2\u003e* self)\n```\n\n```\n    var ma = [\"AAA\":1, \"BBB\":2, \"CCC\":3];\n    var ma2 = clone ma;\n```\n\n\n```C\nstring to_string(map\u003cT,T2\u003e* self)\n```\n\n```\n    [\"AAA\":1, \"BBB\":2, \"CCC\":3].to_string().puts();   // [AAA:1,BBB:2,CCC:3]\n```\n\nAll elements and keys must implement to_string(). All basic types of neo-c have to_string() implemented. Struct will automatically define to_string method.\n\nすべての要素とキーにto_string()が実装されている必要があります。neo-cの基本的な型はすべてto_string()が実装されてます。to_stringは構造体の場合自動的に定義されます。\n\n```C\nT2 at(map\u003cT, T2\u003e* self, T\u0026 key, T2 default_value) \n```\n\n```\n    [\"AAA\":1, \"BBB\":2, \"CCC\":3].at(\"AAA\", -1).to_string().puts();  // 1\n```\n\nTakes value by key. This is the value if default_value is not found.\n\nキーで値をとります。default_valueが見つからない場合の値です。\n\n```C\nmap\u003cT,T2\u003e* remove(map\u003cT, T2\u003e* self, T\u0026 key) \n```\n\n```\n    var ma = [\"AAA\":1, \"BBB\":2, \"CCC\":3].remove(\"AAA\");\n    ma.to_string().puts();   // [BBB:2, CCC:3]\n```\n\nDelete value by key.\n\nキーで値を削除します。\n\n```C\nT\u0026 begin(map\u003cT, T2\u003e* self)\nT\u0026 next(map\u003cT, T2\u003e* self) \nbool end(map\u003cT, T2\u003e* self) \n```\n\nIt is for foreach. To access all keys:\n\nforeachのためにあります。すべてのキーにアクセスするには以下のようにします。\n\n```\n    var ma = [\"AAA\":1, \"BBB\":2, \"CCC\"];\n    \n    foreach(key, ma) {\n        var item = ma[key];\n        \n        printf(\"%s %d\\n\", key, item);\n    }\n```\n\nThe output is AAA 1\\nBBB 2\\n CCC 3\\n.\nforeach(key, [\"AAA\":1, \"BBB\":2, \"CCC\":3]) is not possible. Because foreach is a macro, it has meaning.\nMaybe include foreach in the language specification instead of a macro.\n\n出力はAAA 1\\nBBB 2\\n CCC 3\\nです。\nforeach(key, [\"AAA\":1, \"BBB\":2, \"CCC\":3])とはできません。foreachはマクロのため,が意味を持つためです。\nちょっとforeachをマクロでなく言語仕様に含めるかもしれません。\n\n```C\nvoid rehash(map\u003cT,T2\u003e* self) \n```\n\nFor internal use.\n\n内部的に使用します。\n\n```C\nmap\u003cT,T2\u003e* insert(map\u003cT,T2\u003e* self, T key, T2 item)\n```\n\n```\n    var ma = [\"AAA\":1].insert(\"BBB\",2).insert(\"CCC\",3);\n    ma.to_string().puts(); // [AAA:1,BBB:2,CCC:3]\n```\n\n```C\nT2 operator_load_element(map\u003cT, T2\u003e* self, T\u0026 key) \n```\n\n```\n    var ma = [\"AAA\":1,\"BBB\":2,\"CCC\":3];\n    var item = ma[\"AAA\"];\n    item.to_string().puts(); // 1\n```\n\nIf the key is not found, zero clear value is returned.\n\nキーが見つからない場合0クリアされた値が返されます。\n\n```C\nvoid operator_store_element(map\u003cT, T2\u003e* self, T key, T2 item) \n```\n\n```\n    var ma = [\"AAA\":1, \"BBB\":2];\n    ma[\"CCC\"] = 3;\n    ma.to_string().puts(); // [AAA:1,BBB:2,CCC:3]\n```\n\n```C\nbool equals(map\u003cT, T2\u003e* left, map\u003cT, T2\u003e* right)\n```\n\n```\n    [\"AAA\":1,\"BBB\":2,\"CCC\":3].equals([\"AAA\":1,\"BBB\":2,\"CCC\":3]); // true\n    [\"AAA\":1].equals([\"BBB\":2]); // false\n```\n\n```C\nbool operator_equals(map\u003cT, T2\u003e* left, map\u003cT,T2\u003e* right) \n```\n\n```\n    [\"AAA\":1,\"BBB\":2,\"CCC\":3] === [\"AAA\":1,\"BBB\":2,\"CCC\":3]; // true\n    [\"AAA\":1] === [\"BBB\":2]; // false\n```\n\n```C\nbool operator_not_equals(map\u003cT, T2\u003e* left, map\u003cT,T2\u003e* right) \n```\n\n```\n    [\"AAA\":1,\"BBB\":2,\"CCC\":3] !== [\"AAA\":1,\"BBB\":2,\"CCC\":3]; // false\n    [\"AAA\":1] !== [\"BBB\":2]; // true\n```\n\n```C\nbool find(map\u003cT, T2\u003e* self, T\u0026 key) \n```\n\n```\n    [\"AAA\":1, \"BBB\":2].find(\"AAA\"); // true;\n    [\"AAA\":1, \"BBB\":2].find(\"CCC\"); // false;\n```\n\nReturns true if the key is included.\n\nキーが含まれればtrueを返します。\n\n\n```C\nmap\u003cT,T2\u003e*% operator_add(map\u003cT,T2\u003e* left, map\u003cT,T2\u003e* right) \n```\n\n```\n    ([\"AAA\":1] + [\"BBB\":2]).to_string().puts(); // [AAA:1,BBB:2]\n```\n\n```C\nmap\u003cT,T2\u003e*% operator_mult(map\u003cT,T2\u003e* left, int right) \n```\n\n```\n    ([\"AAA\":1] * 2).to_string().puts(); // [AAA:1,AAA:1]\n```\n\n```C\nlist\u003cT\u003e*% keys(map\u003cT, T2\u003e* self)\n```\n\n```\n    [\"AAA\":1, \"BBB\":2, \"CCC\":3].keys().to_string().puts();  // [AAA,BBB,CCC]\n```\n\n```C\nlist\u003cT2\u003e*% values(map\u003cT, T2\u003e* self) \n```\n\n```\n    [\"AAA\":1, \"BBB\":2, \"CCC\":3].values().to_string().puts();  // [1,2,3]\n```\n\n# tuple\n\nA tuple is a collection of elements of different types. It may be called a simple structure.\n\nタプルは型の違う要素を持つコレクションです。簡易的な構造体と呼べるかもしれません。\n\n```\n#include \u003cneo-c.h\u003e\n\nint main(int argc, char** argv)\n{\n    tuple3\u003cint, int, char*\u003e*% tu = new tuple3\u003cint, int, char*\u003e(1, 2, \"ABC\");\n    \n    printf(\"%d %d %s\\n\", tu.v1, tu.v2, tu.v3);\n    \n    return 0;\n}\n```\n\nUp to 5 tuples are defined.\n\ntupleは5つまで定義されてます。\n\n```\n    tuple5\u003cint,int,int,string,char*\u003e*% tu = (1,2,3,s\"ABC\",\"DEF\");\n    \n    tu.to_string().puts(); // (1,2,3,ABC,DEF)\n```\n\nint, bool have the same meaning as tuple2\u003cint, bool\u003e*%. Used to return multiple values. When you want to store multiple values in each variable, you can use var a,b = div(1,1); Int is placed in a and bool is placed in b.\n\nTo access the element, use v1 etc.\n\nint, boolはtuple2\u003cint, bool\u003e*%と同じ意味です。複数の値を返すために使います。複数の値を各変数に格納したい時、個の場合はvar a,b = div(1,1);とすればいいです。aにint, bにboolが入ります。\n\n要素にアクセスするにはv1などとします。\n\n```\n    var tu = (1,2,\"ABC\");\n    \n    tu.v1 === 1; // true\n    tu.v2 === 2; // true\n    tu.v3 === \"ABC\"; // true\n```\n\ntup: int, stringはtuple2\u003cint,string\u003e*%と同じです。list\u003ctuple2\u003cint,string\u003e*%\u003e*%の代わりにlist\u003cint, string\u003e*%は使えませんが、list\u003ctup:int,string\u003e*%は使えます。\n\ntup: int, string is the same as tuple2\u003cint,string\u003e*%. You cannot use list\u003cint, string\u003e*% instead of list\u003ctuple2\u003cint,string\u003e*%\u003e*%, ​​but you can use list\u003ctup:int,string\u003e*%.\n\n# buffer\n\nBuffer is memory that can be appended. Expression of buffer is b\"\".\n\nbufferは追記できるメモリーです。\n\nbufferの値の表現はb\"\"です。\n\n```\n#include \u003cneo-c.h\u003e\n\nint main(int argc, char** argv)\n{\n    buffer*% buf = new buffer();\n    \n    buf.append_str(\"ABC\");\n    buf.append_str(\"DEF\");\n    \n    puts(buf.to_string()));\n    \n    buffer*% buf2 = new buffer();\n    \n    buf2.append_int(1);\n    buf2.append_int(2);\n    buf2.append_int(3);\n    \n    int* p = buf2.head_pointer();\n    \n    printf(\"%d\\n\", *p);  // 1\n    p++;\n    printf(\"%d\\n\", *p);  // 2\n    p++;\n    printf(\"%d\\n\", *p);  // 3\n    \n    return 0;\n}\n```\n\n```C\nbuffer*% buffer*::initialize(buffer*% self);\n```\n\n```\n    var buf = new buffer();\n```\n\n```C\nvoid buffer*::finalize(buffer* self);\n\nbuffer*% buffer*::clone(buffer* self);\n```\n\n```\n    var buf = new buffer();\n    buf.append_int(1);\n    buf.append_int(2);\n    buf.append_int(3);\n    \n    var buf2 = clone buf;\n```\n\n```C\nint buffer*::length(buffer* self);\n```\n\n```\n    var buf = new buffer();\n    buf.append_char('a');\n    buf.append_char('b');\n    buf.append_char('c');\n    \n    buf.length().to_string().puts(); // 3\n```\n\nReturns the number of bytes of memory.\n\nメモリーのバイト数を返します。\n\n```C\nvoid buffer*::reset(buffer* self);\n```\n\n```\n    var buf = new buffer();\n    \n    buf.append_char('a');\n    buf.append_char('b');\n    buf.append_char('c');\n    \n    buf.reset();\n    \n    buf.length().to_string().puts(); // 0\n```\n\nClear memory.\n\nメモリーをクリアします。\n\n```C\nvoid buffer*::trim(buffer* self, int len);\n```\n\nDelete trailing memory by len.\n\nlenだけ末尾のメモリを削除します。\n\n```\n    var buf = new buffer();\n    \n    buf.append_str(\"ABCDEFG\");\n    buf.trim(3);\n    buf.to_string().puts(); // ABCD\n```\n\n```C\nbuffer* buffer*::append(buffer* self, char* mem, size_t size);\n```\n\nAdd memory by mem size.\n\nmemのsizeだけメモリを追加します。\n\n```\n    var buf = new buffer();\n    buf.append(\"ABCDEFG\", 2);\n    \n    buf.to_string().puts(); // AB\n```\n\n```C\nbuffer* buffer*::append_char(buffer* self, char c);\nbuffer* buffer*::append_str(buffer* self, char* str);\nbuffer* buffer*::append_nullterminated_str(buffer* self, char* str);\nbuffer* buffer*::append_int(buffer* self, int value);\nbuffer* buffer*::append_long(buffer* self, long value);\nbuffer* buffer*::append_short(buffer* self, short value);\n```\n\nAdd memory.\n\nメモリーを追加します。\n\n```C\nbuffer* buffer*::alignment(buffer* self);\n```\n\nAlign memory.\n\nメモリーのアライメントを取ります。\n\n```C\nint buffer*::compare(buffer* left, buffer* right);\n```\n\nCompare the buffer sizes. \u003c0 means smaller on the left, \u003e0 means smaller on the right. == 0 and have the same size.\nUsed in sort.\n\nbufferの大きさを比べます。\u003c0で左が小さい、\u003e0で右が小さい。== 0で同じ大きさです。\nsortで使います。\n\n```C\nbuffer*% string::to_buffer(char* self);\nbuffer*% char*::to_buffer(char* self);\n```\n\nConvert string to buffer.\n\n文字列をbufferに変換します。\n\n```\n    var buf = \"ABCDEFG\".to_buffer();\n    buf.append_str(\"HIJ\");\n    \n    buf.to_string().puts(); // ABCDEFGHIJ\n```\n\n```C\nstring buffer*::to_string(buffer* self);\n```\n\nConvert buffer to string.\n\nbufferを文字列に変換します。\n\n```C\nstatic inline buffer*% char[]::to_buffer(char* self, size_t len) ;\nstatic inline buffer*% short[]::to_buffer(short* self, size_t len) ;\nstatic inline buffer*% int[]::to_buffer(int* self, size_t len) ;\nstatic inline buffer*% long[]::to_buffer(long* self, size_t len) ;\nstatic inline buffer*% float[]::to_buffer(float* self, size_t len) ;\nstatic inline buffer*% double[]::to_buffer(double* self, size_t len) ;\n```\n\n```C\n    char a[4] = { 'A', 'B', 'C', '\\0' };\n    \n    var buf = a.to_buffer(4);\n    \n    puts(buf.to_string()); // ABC\n```\n\n```C\nstatic inline list\u003cchar\u003e*% char[]::to_list(char* self, size_t len) ;\nstatic inline list\u003cshort\u003e*% short[]::to_list(short* self, size_t len) ;\nstatic inline list\u003cint\u003e*% int[]::to_list(int* self, size_t len) ;\nstatic inline list\u003clong\u003e*% long[]::to_list(long* self, size_t len) ;\nstatic inline list\u003cfloat\u003e*% float[]::to_list(float* self, size_t len) ;\nstatic inline list\u003cdouble\u003e*% double[]::to_list(double* self, size_t len) ;\n```\n\n```C\n    int a[3] = { 3, 2, 1 };\n    \n    a.to_list(3).sort().each {\n        printf(\"%d\\n\", it);\n    }\n```\n\n```C\nstatic inline size_t char[]::length(char* self, size_t len) ;\nstatic inline size_t short[]::length(short* self, size_t len) ;\nstatic inline size_t int[]::length(int* self, size_t len) ;\nstatic inline size_t long[]::length(long* self, size_t len) ;\nstatic inline size_t float[]::length(float* self, size_t len) ;\nstatic inline size_t double[]::length(double* self, size_t len) ;\n```\n\n```C\n    int a[3] = { 3, 2, 1 };\n    \n    printf(\"%d\\n\", a.length(3));\n```\n\n# string \n\n```\n#include \u003cneo-c.h\u003e\n\nint main(int argc, char** argv)\n{\n    puts(xsprintf(\"%d\", 1 + 1));     // ==\u003e 2\n    puts(string(\"ABC\").substring(0, 1));  // ==\u003e \"A\"\n    \n    return 0;\n}\n```\n\n```C\nint string::length(char* str);\n```\n\n```\n    s\"ABC\".length(); // 3\n```\n\n```C\nint char*::length(char* str);\n```\n\n```\n    \"ABC\".length(); // 3\n```\n\n```C\nstring char*::substring(char* str, int head, int tail);\nstring string::substring(char* str, int head, int tail);\n```\n\n```\n    \"ABC\".substring(0,2); // AB\n```\n\n```C\nstring string::operator_load_range_element(char* str, int head, int tail);\nstring char*::operator_load_range_element(char* str, int head, int tail);\n```\n\n```\n    \"ABC\"[0..2]; // AB\n```\n\n```C\nstring char*::reverse(char* str) ;\nstring string::reverse(char* str) ;\n```\n\n```\n    \"ABC\".reverse();   // CBA\n```\n\n```C\nstring xsprintf(char* msg, ...);\n```\n\n```\n    var str = xsprintf(\"%d+%d+%d\", 1,2,3); // 1+2+3\n```\n\n```C\nstatic inline string string::xsprintf(char* self, char* msg, ...)\nstatic inline string char*::xsprintf(char* self, char* msg, ...)\n```\n\n```\n    s\"ABC\".xsprintf(\"[%s]\").puts(); // [ABC]\n```\n\n```C\nstatic inline string int::xsprintf(int self, char* msg, ...)\n```\n\n```\n    [1,2,3,4,5].item(0, -1).xsprintf(\"[%d]\\n\").puts();  // [1]\n```\n\n```C\nstring char*::delete(char* str, int head, int tail) ;\nstring string::delete(char* str, int head, int tail);\n```\n\n```\n    var str = s\"ABCDEFG\".delete(0,1); // CDEFG\n```\n```C\nlist\u003cstring\u003e*% string::split_char(char* self, char c) ;\nlist\u003cstring\u003e*% char*::split_char(char* self, char c);\n```\n\n```C\n    s\"A,B,C\".split_char(','); // [A,B,C]\n```\n\npath related wrapper\n\npathの関連のラッパー\n\n```C\nstring xrealpath(char* path);\n```\n\nstring version of realpath(3)\n\nrealpath(3)のstring版\n\n```C\nxrealpath(\"/aaa/../bbb\"); // /bbb\n```\n\nMaybe.\n\n多分。\n\n```C\nstring xbasename(char* path);\n```\n\nstring version of basename(3)\n\nbasename(3)のstring版\n\n```C\nstring xextname(char* path);\n```\n\nreturn extension\n\n拡張子を返す\n\n```C\nstring xdirname(char* path);\n```\n\nreturn directory\n\nディレクトリを返す\n\n```C\nstring xnoextname(char* path);\n```\n\nReturns the file name without the extension.\n\n拡張子をとったファイル名を返す。\n\n```C\nint FILE*::write(FILE* f, char* str);\n```\n\n```\n    FILE* f = fopen(\"AAA\", \"a\");\n    \n    f.write(\"ABC\");\n    \n    f.fclose();\n```\n\nI just made it object oriented.\n\nオブジェクト指向っぽくしただけ。\n\n```C\nstring FILE*::read(FILE* f);\n```\n\nsimilar\n\n同様\n\n```C\nint FILE*::fclose(FILE* f) ;\n```\n\nsimilar\n\n同様。\n\n```C\nint* FILE*::fprintf(FILE* f, const char* msg, ...);\n```\n\n```\n    FILE* f = fopen(\"AAA\", \"a\"9;\n    \n    f.fprintf(\"%d\\n\", 1+1);\n    \n    f.close();\n```\n\nsimilar\n同様\n\n```C\nlist\u003cstring\u003e*% FILE*::readlines(FILE* f);\n```\n\n```\n    \"AAA\\nBBB\\nCCC\\n\".write(\"FILE\", append:true);\n    \n    FILE* f = fopen(\"FILE\", \"r\");\n    \n    var li = f.readlines();\n    \n    li[0].puts(); // AAA\n    li[1].puts(); // BBB\n    li[2].puts(); // CCC\n```\n\n```C\nint string::write(char* self, char* file_name, bool append=false);\nint char*::write(char* self, char* file_name, bool append=false) ;\n\nstring char*::read(char* file_name) ;\nstring string::read(char* file_name) ;\n```\n\n```C\n    \"ABC\".write(\"FILE-NAME\", append:true);\n    \"ABC\".write(\"FILE-NAME\", append:true);\n    \"ABC\".write(\"FILE-NAME\", append:true);\n    \n    \"FILE-NAME\".read().puts(); // ABC\\nABC\\nABC\n```\n\nIf append:false, no appending will be done. append:false is the parameter label. Easy to view source files.\nIt is also good to use true@append and annotations.\n\nappend:falseだと追記なし。append:falseはパラメーターラベル。ソースファイルが見やすい。\ntrue@appendとアノテーションを使うのもいい。\n\n# Default parameters, parameter labels\n\n``` C\n#include\u003cstdio.h\u003e\n\nint fun(int x = 123, int y = 345, int z = 456) \n{\n    printf(\"x %d y %d z %d\\n\", x, y, z);\n}\n\nstruct sData \n{\n    int x;\n    int y;\n    int z;\n};\n\nint sData*::fun(sData* self, int x = 123, int y = 345, int z = 456)\n{\n    self.x = x;\n    self.y = y;\n    self.z = z;\n}\n\nvoid sData*::show(sData* self)\n{\n    printf(\"x %d y %d z %d\\n\", self.x, self.y, self.z);\n}\n\nint main(int argc, char** argv) \n{\n    fun();           // x 123 y 345 z 456 are outputed\n    fun(y:2);        // x 123 y 2 z 456\n    \n    fun(y:1, x:3);   // x 3 y 1 z 456\n    \n    fun(1);          // x 1 y 345 z 456\n    fun(1,2);        // x 1 y 2 z 456\n    \n    sData data;\n    (\u0026data).fun(1,2,3);\n    (\u0026data).show();   // x 123 y 345 z 456\n    \n    (\u0026data).fun(y:2); // x 123 y 2 z 456\n    (\u0026data).show();   // x 123 y 2 z 456\n    \n    (\u0026data).fun(1);\n    (\u0026data).show();   // x 1 y 345 z 456\n    \n    return 0;\n}\n```\n\n# operator overloads\n\n``` C\nstring char*::operator_mult(char* str, int n);\nstring string::operator_mult(char* str, int n);\nbool char*::operator_equals(char* left, char* right);\nbool string::operator_equals(char* left, char* right);\n\n    \"ABC\" * 3  // =\u003e \"ABCABCABC\"\n    [1,2] * 3  // =\u003e [1,2,1,2,1,2]\n    \"ABC\" === \"ABC\" // =\u003e true\n    \"ABC !== \"DEF\" // =\u003e true\n    [1,2] + [3] // =\u003e [1,2,3]\n    \n    auto ma1 = [\"AAA\":1, \"BBB\":2]\n    \n    xassert(\"map test\", ma1[\"AAA\"] == 1)\n    ma1[\"CCC\"] = 3\n```\n\n``` C\n+ operator_add\n- operator_sub\n* operator_mult\n/ operator_div\n% operator_mod\n=== operator_equals\n!== operator_not_equals\n\u003e operator_gt\n\u003e= operator_gteq\n\u003c operator_le\n\u003c= operator_leeq\n[x] = y operator_store_element\n[x]  operator_load_element\n! operator_logical_denial\n\u003c\u003c operator_left_shift\n\u003e\u003e operator_right_shift\n\u0026 operator_and\n^ operator_xor\n| operator_or\n~ operator_commplement\n```\n\n# mixin-layers system\n\n``` C\n#include \u003cstdio.h\u003e\n\nint fun(char* str) version 1\n{\n    puts(str);\n    return 1;\n}\n\nint fun(char* str) version 2\n{\n    int n = inherit(str);\n\n    return n + 1;\n}\n\nint fun(char* str) version 3\n{\n    int n = inherit(str);\n\n    return n + 1;\n}\n\nint main()\n{\n    if(fun(\"HELLO MIXIN-LAYERS\") == 3) {\n        puts(\"OK\");\n    }\n\n    return 0;\n}\n```\n\n# Annotation\n\n``` C\nint fun(bool flag) \n{\n    if(flag) {\n        puts(\"TRUE\");\n    }\n    else {\n        puts(\"FALSE\");\n    }\n}\n\nint main()\n{\n    fun(false@flag);\n\n    return 0;\n}\n```\n\n@[a-zA-Z][a-zA-Z_0-9]* is a comment of expression.\n\n# multiple assign\n\n``` C\n#include \u003cneo-c.h\u003e\n\nint, string fun(int n, string m) \n{\n    return (n, m);\n}\n\nint main(int argc, char** argv)\n{\n    var n, m = fun(1, string(\"AAA\"));\n    \n    printf(\"n %d m %s\\n\", n, m);\n    \n    return 0;\n}\n```\n\n# Interface\n\n``` C\n#include \u003cneo-c.h\u003e\n\ninterface sBase\n{\n    void show();\n};\n\nstruct sChildA\n{\n    int x;\n    int y;\n    int z;\n    string str;\n}\n\nsChildA*% sChildA*::initialiize(sChildA*% self)\n{\n    self.x = 1;\n    self.y = 2;\n    self.z = 3;\n    self.str = string(\"ABC\");\n    \n    return self;\n}\n\nvoid sChildA*::show(sChildA* self)\n{\n    printf(\"x %d y %d z %d str %s\\n\", self.x, self.y, self.z, self.str);\n}\n\nstruct sChildB\n{\n    int X;\n    int Y;\n    int Z;\n};\n\nsChildB*% sChildB*::initialize(sChildB*% self)\n{\n    self.X = 111;\n    self.Y = 222;\n    self.Z = 333;\n    \n    return self;\n}\n\nvoid sChildB*::show(sChildB* self)\n{\n    printf(\"X %d Y %d Z %d\\n\", self.X, self.Y, self.Z);\n}\n\nint main(int argc, char** argv)\n{\n    list\u003csBase*%\u003e*% li = new list\u003csBase*%\u003e();\n    \n    li.add(new sChildA() implements sBase);\n    li.add(new sChildB() implements sBase);\n    \n    foreach(it, v) {\n        it.show();\n    }\n    \n    return 0;\n}\n\n```\n\n# Using C\n\n``` C\n    int main(int argc, char** argv)\n    {\n        using c { int a = (1,2); }     // no error. It's comma operator and blace\n        \n        int a = (1,2);  // error. It's tuple\n        \n        return 0;\n    }\n```\n\n``` C\n\u003e vin a.h\nstatic inline int fun()\n{\n    return (1,2);\n}\n\u003e vin a.c\nusing C\n{\n#include \"a.h\"\n}\n\nint main(int argc, char** argv)\n{\n    return fun();   // no error. It's comma operator and brace\n}\n```\n\n# Emmbeded expression string\n\n```\nint main(int argc, char* argv)\n{\n    string a = s\"abc\";\n    \n    puts(a);          // abc\n    \n    string b = S\"def\";\n    \n    puts(b);          // def\n    \n    int c = 123;\n    \n    puts(s\"c == \\{c}\");   // c == 123;\n    \n    puts(s\"1 + 1 == \\{1+1}\");   // 1+1 == 2;\n    \n    return 0;\n}\n```\n\n# System call errro handling like perl\n\nand or or is like perl\n\n# Here document\n\n```C\n#include \u003cneo-c.h\u003e\n\nint main(int argc, char** argv)\n{\n    int a = 123;\n    printf(\"\"\"\nAAA\n\\{a}\nBBB\nCCC\n    \"\"\");\n    \n    return 0;\n}\n```\n\nif head of charactor is '#', require quote.\n\n# method block\n\n```\n#include \u003cneo-c.h\u003e\n\nint main(int argc, char** argv)\n{\n    3.times {\n        printf(\"%d\\n\", it);\n    }\n    \n    return 0;\n}\n```\n\n```\n#include \u003cneo-c.h\u003e\n\nint main(int argc, char** argv)\n{\n    [\"1\", \"2\", \"3\"].map { atoi(it) }.filter { it \u003e 1 }.each { it. printf(\"%d\\n\"); }\n    \n    return 0;\n}\n```\n\n```\n#include \u003cneo-c.h\u003e\n\nint main(int argc, char** argv)\n{\n    3.times {\n        printf(\"%d\\n\", it);\n    }\n    \n    return 0;\n}\n```\n\n# String libraries\n\nSEE neo-c.h\n\nsample\n\n``` C\n#include \u003cneo-c.h\u003e\n\nint main()\n{\n    xassert(\"char_match test\", \"ABC\".match(\"A\"));\n    xassert(\"char_index test\", \"ABC\".index(\"B\", -1) == 1);\n    xassert(\"char_rindex test\", \"ABCABC\".rindex(\"B\", -1) == 4);\n    xassert(\"char_index_regex\", \"ABC\".index_regex(\"B\", -1) == 1);\n    xassert(\"char_rindex_regex\", \"ABCABC\".rindex_regex(\"B\", -1) == 4);\n\n    string str = string(\"ABC\");\n\n    str.replace(1, 'C');\n\n    xassert(\"char_replace\", str === \"ACC\"))\n    xassert(\"char_multiply\", \"ABC\".multiply(2) === \"ABCABC\");\n\n    xassert(\"char_sub\", \"ABC\".sub(\"B\", \"C\" === \"ACC\");\n\n    auto li = \"ABC\".scan(\".\");\n\n    xassert(\"char_scan\", li[0] === \"A\" \u0026\u0026 li[1] === \"B\" \u0026\u0026 li[2] === \"C\");\n\n    auto li2 = \"A,B,C\".split(\",\");\n\n    xassert(\"char_split\", li2[0] === \"A\" \u0026\u0026 li2[1] === \"B\" \u0026\u0026 li2[2] == \"C\");\n\n    auto li3 = \"A,B,C\".split_char(',');\n\n    xassert(\"char_split_char\", li3[0] === \"A\" \u0026\u0026 li3[1] === \"B\" \u0026\u0026 li3[2] === \"C\");\n    \n    auto li4 = \"A,,B,,C\".split_str(\",,\");\n\n    xassert(\"char_split_str\", li4[0] === \"A\" \u0026\u0026 li4[1] === \"B\" \u0026\u0026 li4[2] === \"C\");\n    \n    xassert(\"char_delete\", \"ABC\".delete(0,1) === \"BC);\n\n    xassert(\"wchar_substring\", wstring(\"ABC\").substring(0,1) === wstring(\"A\"));\n    \n    auto li6 = \"A,B,C\".split_str(\",\");\n    \n    xassert(\"join\", li6.join(\" \") === \"A B C\");\n    \n    auto li7 = \"A,B,C\".split(\",\");\n    \n    xassert(\"split test\", li7[0] === \"A\" \u0026\u0026 li6[1] === \"B\" \u0026\u0026 li7[2] === \"C\");\n    xassert(\"rindex_regex test\", \"ABCABC\".rindex_regex(\"CBA\", -1) == 5);\n    xassert(\"sub_block test\", \"ABCABCABC\".sub_block(\"ABC\") { string(\"X\"); } === \"XXX\");\n    xassert(\"scan_block test\", \"123 456 789\".scan_block(\"[0-9][0-9][0-9]\") { it.substring(0, 1); }.join(\"\") === \"147\");\n    \n    auto li8 = \"ABC\".scan(\".\");\n    \n    xassert(\"scan test\", li8[0] === \"A\" \u0026\u0026 li8[1] === \"B\" \u0026\u0026 li8[2] === \"C\");\n    \n    var bufX = \"ABC\".to_buffer();\n    bufX.append_str(\"DEF\");\n    \n    xassert(\"to_buffer test\", bufX.to_string() === \"ABCDEF\");\n    xassert(\"split block test\", \"ABC,DEF,GHI\".split_block(\",\") { it.substring(0,1); }.join(\"\") === \"ADG\");\n    xassert(\"regex test\", \"ABC\".scan(\".\").join(\"\") === \"ABC\");\n    \n    xassert(\"regex equals test\", \"aaa\" === \"aaa\");\n    \n    return 0;\n}\n```\n\n# stackfame\n\n```C\n\u003e vin a.c\n#include \u003cneo-c.h\u003e\n\nint fun()\n{\n    stackframe();\n    return 0;\n}\n\nint fun2()\n{\n    return fun();\n}\n\nint main(int argc, char** argv)\n{\n    fun2();\n    \n    return 0;\n}\n\u003e neo-c -cg a.c\n\u003e ./a\na.c 5\na.c 11\na.c 16\n```\n\nfor debugging.\nrequire -cg option.\n\n```C\n#include \u003cneo-c.h\u003e\n\nrecord void fun()\n{\n    stackframe();\n}\n\nint main(int argc, char** argv)\n{\n    fun();\n    return 0;\n}\n```\n\nappend record attribute to show stackframe. It's not required -cg option\n\n# Template\n\n```C\ntemplate\u003cR\u003e R fun(R x, R y)\n{\n    return x + y;\n}\n\nint main(int argc, char** argv)\n{\n    fun(1,2).printf(\"%d\\n\");\n    \n    return 0;\n}\n```\n\ntype inference is works.\n\n```C\n#include \u003cneo-c.h\u003e\n\nint main(int argc, char** argv)\n{\n    [1,2,3].map { it.to_string() }.each { puts(it); }\n    \n    return 0;\n}\n```\n\n# Memory leak detector\n\n```c \n#include \u003cneo-c.h\u003e\n\nvoid fun()\n{\n    var a = gc_inc(new int);\n    *a = 123;\n\n    stackframe();\n                        \n    printf(\"%d\\n\", *a);\n}\n                            \nint main(int argc, char** argv) \n{\n    fun();\n                                    \n    return 0;\n}\n~/neo-c # neo-c a.c\n~/neo-c # ./a\n123\n1 memory leaks. 1 alloc, 0 free.If you require debugging, copmpile with -cg option\n~/neo-c # neo-c -cg a.c\n~/neo-c # ./a\na.c 9\na.c 16\n123\n#1 (int): a.c 16, a.c 5, \n1 memory leaks. 1 alloc, 0 free.\n~/neo-c # \n```\n\n# Class\n\n```C\n#include \u003cneo-c.h\u003e\n\nclass sData\n{\n    int x;\n    int y;\n    \n    new(int x, int y)\n    {\n        self.x = x;\n        self.y = y;\n    }\n    \n    void show()\n    {\n        printf(\"x %d y %d\\n\", self.x, self.y);\n    }\n};\n\nint main(int argc, char** argv)\n{\n    sData*% data = new sData(111, 222);\n    \n    data.show();\n    \n    return 0;\n}\n```\n\n```C\n#include \u003cneo-c.h\u003e\n\nclass sData\n{\n    int x;\n    int y;\n    \n    new(int x, int y)\n    {\n        self.x = x;\n        self.y = y;\n    }\n    \n    void show()\n    {\n        printf(\"x %d y %d\\n\", self.x, self.y);\n    }\n};\n\nclass sData2 extends sData\n{\n    int z;\n   \n    new(int x, int y, int z)\n    {\n        self.x = x;\n        self.y = y;\n        self.z = z;\n    }\n};\n\ninterface sDataRun\n{\n    void show();\n};\n\nint main(int argc, char** argv)\n{\n    sData*% data = new sData(111, 222);\n    \n    data.show();\n    \n    sData2*% data2 = new sData2(1, 2, 3);\n    \n    data2.show();\n    \n    sDataRun*% inf = new sData2(1,2,3) implements sDataRun;\n    \n    inf.show();\n    \n    return 0;\n}\n\n```\n\n```C\n#include \u003cneo-c.h\u003e\n\nclass sData\n{\n    int x;\n    int y;\n    \n    new(int x, int y)\n    {\n        self.x = x;\n        self.y = y;\n    }\n    \n    void show()\n    {\n        printf(\"x %d y %d\\n\", self.x, self.y);\n    }\n};\n\nclass sData2 extends sData\n{\n    int z;\n    \n    new(int x, int y, int z)\n    {\n        self.super(x,y);\n        self.z = z;\n    }\n    \n    void show()\n    {\n        self.super();\n        \n        printf(\"z %d\\n\", self.z);\n    }\n};\n```\n\n```C\n#include \u003cneo-c.h\u003e\n\nclass sData\n{\n    new(int x, int y)\n    {\n        int self.x = x;\n        int self.y = y;\n    }\n    \n    void show()\n    {\n        printf(\"x %d y %d\\n\", self.x, self.y);\n    }\n};\n\nint main(int argc, char** argv)\n{\n    sData*% data = new sData(111, 222);\n    \n    data.show();\n    \n    return 0;\n}\n```\n\n# Module\n\n```\n#include \u003cneo-c.h\u003e\n\nmodule MModule\u003cT\u003e\n{\n    T a;\n    T b;\n}\n\nclass sData\n{\n    include MModule\u003cint\u003e;\n    \n    new(int a, int b) {\n        self.a = a;\n        self.b = b;\n    }\n    \n    void show() {\n        printf(\"%d %d\\n\", self.a, self.b);\n    }\n}\n\nint main(int argc, char** argv)\n{\n    var data = new sData(111, 222);\n    \n    data.show();\n    \n    return 0;\n}\n```\n\n# uniq\n\n```\n\u003e vin a.h\nusing c\n{\n#include \u003cstdio.h\u003e\n}\n\nextern int gGlobalVar;\n\nuniq int gGlobalVar = 777;\n\nuniq void fun()\n{\n    printf(\"%d\\n\", gGlobalVar);\n}\n\u003e vin a.c\n#include \"a.h\"\n\nint main(int argc, char** argv)\n{\n    fun();\n    \n    return 0;\n}\n\u003e vin b.c\n#include \"a.h\"\n\nvoid fun2()\n{\n    fun();\n}\n\u003e neo-c -c b.c\n\u003e neo-c a.c b.c.o\n\u003e ./a\n777\n```\n\nuniq function and global variable added to main module.\nIn other module, not defined contents.\n\n# Output of standard c targeted C Source\n\nDon't include neo-c-net.h and neo-c-pthread.h. Inlucde neo-c.h only. It depends standard c library only. If you get c source depends standard c library only, use to \"neo-c -s\" or \"neo-c -S\"\n\n# Extra libraries\n\nPlease use the C language extension library. The strength of neo-c is that the C library can be used as is.\n\n拡張ライブラリはC言語のものを使ってください。neo-cの強みはCライブラリがそのまま使える点です。\n\n# Net libraries\n\nSee libneo-c-net.c and neo-c-net.h\n\nwith -net option to comandline.\n\n# Omit return statment\n\n```C\n[1,2,3].map { return it.to_string(); }.each { puts(it); } \n    \u003c=\u003e [1,2,3].map { it.to_string() }.each { puts(it); ]\n```\n\nOmitting semicolon at the function block end means return statment.\n\n# Pattern Matching\n\n```C\n#include \u003cneo-c.h\u003e\n\nint main(int argc, char** argv)\n{\n    strcmp(\"A\", \"B\").case {\n        (Value \u003c 0) { puts(\"Lesser\");  }\n        (Value == 0) { puts(\"Equal\"); }\n        (Value \u003e 0) { puts(\"Greater\"); }\n    }\n    strcmp(\"A\", \"A\").case {\n        (Value == 0) puts(\"Equal\"); }\n        else puts(\"Not Equal\");\n    }\n    \n    return 0;\n}\n```\n\n```C\n#include \u003cneo-c.h\u003e\n\nchar*% fun(int a)\n{\n    if(a == 0) {\n        return null;\n    }\n    else {\n        return xsprintf(\"%d\", a);\n    }\n}\n\nint main(int argc, char** argv)\n{\n    fun(0).elif {\n        puts(\"null\");\n    }\n    \n    return 0;\n}\n```\n\n```C\n#include \u003cneo-c.h\u003e\n\nchar*% fun(int a)\n{\n    if(a == 0) {\n        return null;\n    }\n    else {\n        return xsprintf(\"%d\", a);\n    }\n}\n\nint main(int argc, char** argv)\n{\n    fun(1).if {\n        puts(Value);\n    }\n    \n    return 0;\n}\n```\n\n```C\n#include \u003cneo-c.h\u003e\n\nint fun()\n{\n    return 0;\n}\n\nint fun2()\n{\n    return -1;\n}\n\nint main(int argc, char** argv)\n{\n    fun().less {\n        puts(\"ERR\");\n        return 1;\n    }\n    fun2().less {\n        puts(\"ERR\");\n        return 1;\n    }\n    \n    return 0;\n}\n```\n\nPattern matching can't have any block result value.\n\n# Reflection\n\n```\ndefined(ID)\nis_static(ID)\nis_heap(ID)\nis_const(ID)\nis_uniq(ID)\nis_type(ID)\ntype(ID)\nparam_types(ID, NUM)\nnum_param_types(ID)\nnum_fields(ID)\nfield_types(ID, NUM)\ntype(ID)\nputs(STR)\nis_inline(ID)\nis_struct(ID)\nis_union(ID)\nis_enum(ID)\nis_interface(ID)\nis_generics(ID)\nis_module(ID)\nundef(ID)\n```\n\n```\n#include \u003cstdio.h\u003e\n#include \u003cstdlib.h\u003e\n\nint fun()\n{\n    puts(\"aaa\");\n}\n\nvoid fun2()\n{\n    puts(\"bbb\");\n}\n\nstatic int fun4(int a, char* b)\n{\n    return 1;\n}\n\nstatic const int gUHO;\n\nstruct sData\n{\n    int a;\n    char* b;\n};\n\nif(num_param_types(fun4) == 2) {\n    if(param_types(fun4, 0) == int) {\n        int a = 888;\n    }\n}\nelif (num_fields(sData) == 2) {\n    if(field_types(sData, 0) == int) {\n        int a = 7;\n    }\n    else {\n        int a = 999;\n    }\n}\nelif (defined(fun2) \u0026\u0026 defined(fun)) {\n    int a = 3;\n}\nelse {\n    int a = 2;\n}\n\nint main(void) {\n    printf(\"a %d\\n\", a);\n    return 0;\n}\n```\n\n```\n#include \u003cstdio.h\u003e\n\nvar a = \"int a;\"\nvar b = \"int b;\"\nvar c = \"1\"\n\nif($c * 5 == 5){\n    int c;\n}\nif($c . 1 == 11){\n    int d;\n}\n\neval \"long \\{$a . $b}\"\n\nint main(int argc, char** argv)\n{\n    printf(\"a %d b %d c %d d %d\\n\", a, b, c, d);\n    \n    return 0;\n}\n```\n\n```\n#include \u003cstdio.h\u003e\n\nvar a = \"int a;\"\nvar b = \"int b;\"\nvar c = \"1\"\n\nstruct sData\n{\n    int a;\n    int b;\n    int c;\n};\n\nif($c * 4 == 4){\n    int c;\n}\nif($c . 1 == 11){\n    int d;\n}\n\nstatic int** aaaa[128];\n\nputs(is_static(type(aaaa)));\n\nputs(\"HELLO REFLECTION\");\nputs(sizeof(sData));\n\nint funX() { }\nputs(result_type(funX));\n\neval \"long \\{$a . $b}\"\n\nint main(int argc, char** argv)\n{\n    printf(\"a %d b %d c %d d %d\\n\", a, b, c, d);\n    printf(\"size %ld\\n\", sizeof(struct sData));\n    \n    return 0;\n}\n```\n\n# Object initializer\n\n```C\n#include \u003cneo-c.h\u003e\n\nstruct sData\n{\n    int a;\n    int b;\n};\n\nint main(int argc, char** argv)\n{\n    var data = new sData { a:123, b:234 };\n    \n    data.to_string().puts(); // new sData {a:123,b:234}\n    \n    return 0;\n}\n```\n\n# Thread, Channel\n\n```C\n#include \u003cneo-c.h\u003e\n#include \u003cneo-c-pthread.h\u003e\n\nint fun(int a, int b)\n{\n    printf(\"%d %d\\n\", a, b);\n    \n    return 3;\n}\n\nint main(int argc, char** argv)\n{\n    int@ a = __channel__;\n    int@ b = __channel__;\n    \n    var thread = come {\n        fun(1, 2);\n        a \u003c- 111;\n        a \u003c- 222;\n    }\n    \n    b \u003c- 222;\n    \n    come_join(thread);\n    \n    come_poll {\n        a {\n            printf(\"a %d\\n\", \u003c-a);\n        }\n        \n        b {\n            printf(\"b %d\\n\", \u003c-b);\n        }\n    }\n    \n    return 0;\n}\n```\n\n```\n#include \u003cneo-c.h\u003e\n#include \u003cneo-c-pthread.h\u003e\n\nint main(int argc, char** argv)\n{\n    int@ a = __channel__;\n    int@ b = __channel__;\n    \n    var thread = come {\n        a \u003c- 111;\n        a \u003c- 222;\n    }\n    var thread2 = come {\n        b \u003c- 333;\n        b \u003c- 444;\n    }\n    \n    while(1) {\n        come_poll {\n            a {\n                printf(\"a %d\\n\", \u003c-a);\n            }\n            b {\n                printf(\"b %d\\n\", \u003c-b);\n            }\n            else {\n                break;\n            }\n        }\n    }\n    \n    come_join(thread);\n    come_join(thread2);\n    \n    return 0;\n}\n```\n\nスレッド間のデータのやり取りはグローバル変数やローカル変数で行わず全てチャネル経由で行ってください。\nグローバル変数やローカル変数でやり取りするとデータの競合が起こります。\n\nWhen exchanging data between threads, do not use global or local variables, but rather use channels.\nExchanging data using global or local variables will result in data conflicts.\n\nuse mutex to prevent from conflicts.\n\n```\n#include \u003cneo-c.h\u003e\n#include \u003cneo-c-pthread.h\u003e\n\nint main(int argc,char** argv)\n{\n    var li = new come_mutex\u003clist\u003cint\u003e*%\u003e([1,2,3]);\n    \n    var thread2 = come {\n        li.sync() {\n            it.to_string().puts();\n        }\n        sleep(1);\n        li.sync() {\n            it.to_string().puts();\n        }\n    }\n    \n    var thread = come {\n        li.sync() {\n            it.add(4);\n        }\n        li.sync() {\n            it.add(5);\n        }\n    }\n    \n    come_join(thread);\n    come_join(thread2);\n    \n    return 0;\n}\n```\n\n```\n#include \u003cneo-c.h\u003e\n#include \u003cneo-c-pthread.h\u003e\n\nint main(int argc,char** argv)\n{\n    var li = new come_mutex\u003clist\u003cint\u003e*%\u003e([1,2,3]);\n    \n    var thread2 = come {\n        sleep(3);\n        var it = li.lock();\n        \n        it.to_string().puts();\n        \n        li.unlock();\n    }\n    \n    var thread = come {\n        li.sync() {\n            it.add(4);\n        }\n        li.sync() {\n            it.add(5);\n        }\n    }\n    \n    come_join(thread);\n    come_join(thread2);\n    \n    return 0;\n}\n```\n\n```\n#include \u003cneo-c.h\u003e\n#include \u003cneo-c-pthread.h\u003e\n\nint main(int argc,char** argv)\n{\n    var li = new come_mutex\u003clist\u003cint\u003e*%\u003e([1,2,3]);\n    \n    var thread2 = come {\n        li.lock().to_string().puts();\n        \n        sleep(3);\n        \n        li.lock().to_string().puts();  // on_drop call unlock()\n    }\n    \n    var thread = come {\n        li.lock().add(4); // on_drop call unlock()\n        li.lock().add(5); // on_drop call unlock()\n    }\n    \n    come_join(thread);\n    come_join(thread2);\n    \n    return 0;\n}\n```\n\n```\n#include \u003cneo-c.h\u003e\n#include \u003cneo-c-pthread.h\u003e\n\nint main(int argc,char** argv)\n{\n    var li = new come_mutex\u003clist\u003cint\u003e*%\u003e([1,2,3]);\n    \n    var thread2 = come {\n        for(int i=0; i\u003c10; i++) {\n            li.lock().to_string().puts();\n            sleep(1);\n        }\n    }\n    \n    var thread = come {\n        for(int i=0; i\u003c3; i++) {\n            li.lock().add(4);\n            sleep(1);\n            li.lock().add(5);\n            sleep(1);\n            li.lock().add(6);\n            sleep(1);\n            li.lock().add(7);\n            sleep(1);\n        }\n    }\n    \n    come_join(thread);\n    come_join(thread2);\n    \n    return 0;\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fab25cq%2Fneo-c","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fab25cq%2Fneo-c","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fab25cq%2Fneo-c/lists"}