% eval(read("news.data")) %>
Ring は画期的で実用性豊かなマルチパラダイム汎用プログラミング言語です。 命令型、手続き型、オブジェクト指向、入れ子構造による宣言型、関数型、メタ、および自然言語のプログラミング・パラダイムに対応しています。 移植性 (Windows, Linux, macOS, Android など) があり、小規模、柔軟かつ高速な設計です。 コンソール、GUI、ウェブ、ゲーム、およびモバイルアプリケーションを作成できます。
日付 | 概要 |
---|---|
<%= aNews[x][1] %> | <%= aNews[x][2] %> |
Ring には自然言語プログラミング、宣言型プログラミングに関する最良の支援機能があります。パラダイムには最先端のオブジェクト指向プログラミング、関数型プログラミングの実用的な新技法により対応しています。コンパイラや構文解析などの事前知識は不要です。短時間でドメイン特化言語を作成・構築できる言語構成要素を標準装備しています。
Ring の記事 (CodeProject) シンタックスの柔軟性 (CodeProject) 宣言型手法 (CodeProject) 自然言語プログラミング (CodeProject) 自然言語プログラミング・ライブラリ (CodeProject)Ring ライブラリ (StdLib, WebLib, 自然言語ライブラリ、ゲームエンジンなど)、および Ring 統合開発環境 (Ring ノートパッド、フォームデザイナーなど) は Ring で記述しました。 Ring は製品開発の即戦力であり、開発者の生産性を改善します。
Ring は簡明、違和感の排除、組織化の奨励、および透過性とビジュアル実装からなるプログラミング言語です。 簡潔なシンタックス、そして自然なインタフェースの作成を可能にする機能群、さらに少しの時間で構築できる宣言型問題解決特化言語があります。 非常に小規模、高速なスマートガベージコレクターがあり、メモリをプログラマの制御下に置くことができます。
また、多種多様なプログラミングパラダイムに対応しており、インストール直後からすぐ使える業界標準の実用的なライブラリが付属しています (Allegro, FreeGLUT, cURL, LibUV, MySQL, ODBC, OpenGL, OpenSSL, PostgreSQL, Qt, RayLib, SDL, SQLite などに対応)。
この言語は生産性と拡張性に優れた高品質な解決方法の開発のために設計されています。 → 理由
see "Hello, World!"Main 関数はオプション扱いであり、ステートメントの後に実行されるため、ローカルスコープで有用です。 → 理由
func main see "Hello, World!"動的型付け、およびレキシカルスコープを使用しています。変数名の先頭に $ は不要です! → 理由
nCount = 10 # グローバル変数 func main nID = 1 # ローカル変数 see "Count = " + nCount + nl + " ID = " + nID
see "Enter your name ? " give name see "Hello " + Name # Name は name と同じです。リストのインデックス (添字番号) は 1 から開始します (Ring 1.11 以降は ZeroLib を使用することで 0 から始めることもできます)。 → 理由
aList = ["one","two","three"] see aList[1] # one を表示定義前に関数を呼び出すには
one() two() three() func one see "One" + nl func two see "two" + nl func three see "three" + nl代入演算子は深いコピーを使用します (この操作は参照ではありません)。 → 理由
aList = ["one","two","three"] aList2 = aList aList[1] = 1 see alist[1] # 1 を表示 see aList2[1] # one を表示数値と文字列は値渡しですが、リストとオブジェクトは参照渡しです。
func main aList = [1,2,3] update(aList) see aList # one two three を表示 func update aList for x in aList switch x on 1 x = "one" on 2 x = "two" on 3 x = "three" off next定義するときにリストを使用するには
aList = [ [1,2,3,4,5] , aList[1] , aList[1] ] see aList # 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 を表示一階層以上のループから脱出 → 理由
for x = 1 to 10 for y = 1 to 10 see "x=" + x + " y=" + y + nl if x = 3 and y = 5 exit 2 # 二階層のループから脱出 ok next next
/* プログラム名 : Ring を使用したはじめてのプログラム 日付 : 2017 */ see "What is your name? " # 画面上にメッセージを表示します。 give cName # ユーザからの入力を取得 see "Hello " + cName # hello を表示! // See "Bye!"
ステートメントの後に ; を記述したり ENTER や TAB を押して 行の区別 する必要はありません。 つまり、このようなコードを書くことができます。
see "The First Message" see " Another message in the same line! " + nl see "Enter your name?" give Name see "Hello " + Name
このコードは三種類の属性 X, Y および Z を有する Point クラスを作成します。 パッケージ・クラス・関数の定義を終了するために end キーワードは使用していません。 また、クラスの名前の直下に属性の名前を書くことができます。
class Point X Y Z
定義前にクラスと関数を使用できます。 この用例では、オブジェクトの新規作成と属性の設定、および値を表示します。
o1 = new point o1.x=10 o1.y=20 o1.z=30 see O1 class Point X Y Z
ドット演算子 ‘.’ でオブジェクトの属性とメソッドへアクセスするのではなく、 括弧 { } でオブジェクトへアクセスできます。その後にオブジェクトの属性とメソッドを使用できます。
o1 = new point { x=10 y=20 z=30 } see O1 class Point X Y Z
メソッドの呼出し後に { } を使用してオブジェクトへアクセスします。
oPerson = new Person { Name = "Somebody" Address = "Somewhere" Phone = "0000000" Print() # ここでは Print() メソッドを呼び出します。 } class Person Name Address Phone func Print see "Name :" + name + nl + "Address :" + Address + nl + "Phone : " + phone + nl
{ } を使用してオブジェクトへアクセスしてから任意のオブジェクトの名前を記述するとき、 自動的に呼び出される全ての setter/getter メソッドに対してクラスを検査します。
new Number { see one # GetOne() の実行 see two # GetTwo() の実行 see three # GetThree() の実行 } class Number one two three func GetOne see "Number : One" + nl return 1 func GetTwo see "Number : Two" + nl return 2 func GetThree see "Number : Three" + nl return 3
{ } を使用してオブジェクトへアクセス後にクラスに BraceEnd() と呼ばれるメソッドがある場合は BraceEnd() メソッドを実行します! → 理由
TimeForFun = new journey # あっと驚く! TimeForFun { Hello it is me # なんと美しいプログラミングの世界でしょう! } # クラス本体 class journey hello=0 it=0 is=0 me=0 func GetHello See "Hello" + nl func braceEnd See "Goodbye!" + nl
Eval() 関数は文字列に記述されたコードを実行します。
cCode = "See 'Code that will be executed later!' " Eval(cCode) # コードを実行してメッセージを表示します。
リストの作成後にリストから実行用のコードを生成できます。
aWords = ["hello","it","is","me"] for word in aWords cCode=word+"=0" eval(cCode) next
Read(cFileName) 関数はテキストファイルを読み取ります。 また Write(cFileName,cString) 関数はファイルへ書き込みます。
see "Enter File Name:" give cFileName see read(cFileName) # ファイルの内容を表示
この用例は二つの命令を定義するクラスの作成方法です。
最初の命令は : I want window
次の命令は : Window title = <式>
‘the’ などのキーワードは無視されます。
new App { I want window The window title = "hello world" } class App # I want window 命令の属性 i want window nIwantwindow = 0 # Window title 命令の属性 # ここでは window 属性を再定義しません。 title nWindowTitle = 0 # 値を与えると、キーワードは無視されます。 the=0 func geti if nIwantwindow = 0 nIwantwindow++ ok func getwant if nIwantwindow = 1 nIwantwindow++ ok func getwindow if nIwantwindow = 2 nIwantwindow= 0 see "Instruction : I want window" + nl ok if nWindowTitle = 0 nWindowTitle++ ok func settitle cValue if nWindowTitle = 1 nWindowTitle=0 see "Instruction : Window Title = " + cValue + nl ok
前述の用例を完了するには read() を使用してファイルの内容を取得します。
I want window The window title = "hello world"そして eval() を使用してファイルの内容を実行します!
自然言語 (Natural) ステートメントを使用したコードの実行、 および入れ子構造を使用したコードの実行方法について既に学んでいます。
この用例は Web ライブラリからのものであり Bootstrap ライブラリで HTML ドキュメントを生成します。
この用例では HTML コードを直接記述せずに類似言語を作成しています (ただの用例です)。
その後、宣言型言語を使用するために入れ子構造を使用して、 HTML ドキュメントを生成しています。
この用例での考え方として GetDiv() および GetH1() メソッドは { } を使用してアクセスできるオブジェクトを返します。
各オブジェクトへのアクセス後に BraceEnd() メソッドが実行されると生成された HTML を
BraceEnd() の出力表示がルートに到達するまで親オブジェクトへ送信します。
load "weblib.ring" import System.Web func Main BootStrapWebPage() { div { classname = :container div { classname = :jumbotron H1 { text("Bootstrap Page") } } div { classname = :row for x = 1 to 3 div { classname = "col-sm-4" H3 { html("Welcome to the Ring programming language") } P { html("Using a scripting language is very fun!") } } next } } }
宣言型インタフェースを強化するクラスはこのようなものなります。
class Link from ObjsBase title link func braceend cOutput = nl+GetTabs() + " "+ Title + " " + nl class Div from ObjsBase func braceend cOutput += nl+' " + nl cOutput = TabMLString(cOutput)
ソースコードの記述に関して様々な記法があります!
また、言語のキーワードと演算子を変更することで、お好みの記法を作成できます!
see "Hello, World!"実行結果
================================================================== Tokens - Generated by the Scanner ================================================================== Keyword : SEE Literal : Hello, World! EndLine ================================================================== ================================================================== Grammar Rules Used by The Parser ================================================================== Rule : Program --> {Statement} Line 1 Rule : Factor --> Literal Rule : Range --> Factor Rule : Term --> Range Rule : Arithmetic --> Term Rule : BitShift --> Arithmetic Rule : BitAnd --> BitShift Rule : BitOrXOR --> BitAnd Rule : Compare --> BitOrXOR Rule : EqualOrNot --> Compare Rule : LogicNot -> EqualOrNot Rule : Expr --> LogicNot Rule : Statement --> 'See' Expr ================================================================== ================================================================== Byte Code - Before Execution by the VM ================================================================== PC OPCode Data 1 FuncExE 2 PushC Hello, World! 3 Print 4 ReturnNull ================================================================== Hello, World!
aList = [1,2,3,4,5] aList = "nice"二行目の直後、リスト [1,2,3,4,5] はメモリから削除され、文字列 “nice” が残ります。
アプリケーションでスレッドを使用するとき、インタプリタ (VM) 全体の停止 (global interpreter (VM) lock - GIL) は起こりません。
よって、スレッドは並列動作可能であり、Ring 命令は同時実行されます。
これはスレッドと平行性において最良のものです (さらなる高速化が実現できます!)
Ring は単純明快、小規模、柔軟な言語の頂点として設計されています。また、ほとんどのアプリケーションで十分に高速動作します。
これまで5年間、市販の電子計算機で Ring を使用してきました。下記の処理は約1秒で完了します。
(1) 100,000 行コードのコンパイル
(2) 1 ~ 10,000,000 まで数え上げる空ループの実行
(3) 100,000 項目から成るリストで最後の項目を見つけようとして、線形検索で1000 回の検索処理を実行 (最悪の場合)
(4) 1,000,000 項目から成るリストを作成後にリスト全項目の合計を計算
(5) GUI アプリケーションで ListWidget へ 20,000 アイテムを追加
(6) GUI アプリケーションで TreeWidget へ 5,000 ノードを追加
(7) ターミナルのコンソールアプリケーションで 10,000 メッセージを表示
もっと高速化が必要なときは C/C++ 拡張機能を使用します!