.. index:: single: Language Design; Introduction =============== Language Design =============== In this chapter we will learn about the basic concepts behind the language design. .. index:: pair: Language Design; Why Ring? Why Ring? ========= The language is simple, trying to be natural, encourage organization and comes with transparent and visual implementation. It comes with compact syntax and a group of features that enable the programmer to create natural interfaces and declarative domain-specific languages in a fraction of time. It is very small, fast and comes with smart garbage collector that puts the memory under the programmer control. It supports many programming paradigms, comes with useful and practical libraries. The language is designed for productivity and developing high quality solutions that can scale. .. index:: pair: Language Design; Designed for a clear goal Designed for a Clear Goal ========================= * Applications programming language. * Productivity and developing high quality solutions that can scale. * Small and fast language that can be embedded in C/C++ projects. * Simple language that can be used in education and introducing Compiler/VM concepts. * General-Purpose language that can be used for creating domain-specific libraries, frameworks and tools. * Practical language designed for creating the next version of the Programming Without Coding Technology software. .. index:: pair: Language Design; Simple Simple ====== Ring is a very simple language, and has a very straightforward syntax. It encourages programmers to program without boilerplate code .. code-block:: ring See "Hello, World!" The Main function is optional and will be executed after the statements, and is useful for using the local scope. .. code-block:: ring Func Main See "Hello, World!" Uses Dynamic Typing and Lexical scoping. No $ is required before the variable name! You can use the '+' operator for string concatenation and the language is weakly typed and will convert automatically between numbers and strings based on the context. .. code-block:: ring nCount = 10 # Global variable Func Main nID = 1 # Local variable See "Count = " + nCount + nl + " ID = " + nID .. index:: pair: Language Design; Trying to be natural Trying to be natural ==================== Ring is not case-sensitive .. code-block:: ring See "Enter your name ? " Give name See "Hello " + Name # Name is the same as name The list index starts from 1 .. code-block:: ring aList = ["one","two","three"] See aList[1] # print one Call functions before definition .. code-block:: ring one() two() three() Func one See "One" + nl Func two See "two" + nl Func three See "three" + nl The assignment operator uses Deep copy (no references in this operation) .. code-block:: ring aList = ["one","two","three"] aList2 = aList aList[1] = 1 see alist[1] # print 1 see aList2[1] # print one Pass numbers and strings by value, but pass lists and objects by reference. The for in loop can update the list items. .. code-block:: ring Func Main aList = [1,2,3] update(aList) see aList # print 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 Using Lists during definition .. code-block:: ring aList = [ [1,2,3,4,5] , aList[1] , aList[1] ] see aList # print 1 2 3 4 5 1 2 3 4 5 1 2 3 4 5 Exit from more than one loop .. code-block:: ring for x = 1 to 10 for y = 1 to 10 see "x=" + x + " y=" + y + nl if x = 3 and y = 5 exit 2 # exit from 2 loops ok next next .. index:: pair: Language Design; Encourage Organization Encourage Organization ====================== The language encourage organization, Forget bad days using languages where the programmer start with function then class then function and a strange mix between things! Each source file follow the next structure * Load Files * Statements and Global Variables * Functions * Packages and Classes This enable us to use Packages, Classes and Functions without the need to use a keyword to end these components. We can write one line comments and multi-line comments The comment starts with # or // Multi-line comments are written between /* and */ .. code-block:: ring /* Program Name : My first program using Ring Date : 2015.05.08 */ See "What is your name? " # print message on screen give cName # get input from the user see "Hello " + cName # say hello! // See "Bye!" .. index:: pair: Language Design; Compact Syntax Compact Syntax ============== The language is not line sensitive, you don't need to write ; after statements, also you don't need to press ENTER or TAB, so we can write the next code .. code-block:: ring See "The First Message" See " Another message in the same line! " + nl See "Enter your name?" Give Name See "Hello " + Name The next code create a class called Point contains three attributes X,Y and Z. No keywords is used to end the package/class/function definition. Also, we can write the attributes names directly below the class name. .. code-block:: ring Class Point X Y Z We can use classes and functions before their definition, In this example we will create new object, set the object attributes then print the object values. .. code-block:: ring o1 = New point o1.x=10 o1.y=20 o1.z=30 See O1 Class Point X Y Z Instead of using the dot '.' operator to access the object attributes and methods we can use braces { } to access the object, then we can use the object attributes and methods. .. code-block:: ring o1 = New point { x=10 y=20 z=30 } See O1 Class Point X Y Z Now we will call a method after accessing the object using { } .. code-block:: ring oPerson = new Person { Name = "Somebody" Address = "Somewhere" Phone = "0000000" Print() # here we call the Print() method } Class Person Name Address Phone Func Print See "Name :" + name + nl + "Address :" + Address + nl + "Phone : " + phone + nl When we use { } to access the object then write any attribute name, the language will check the class for any setter/getter methods that will be called automatically. .. code-block:: ring New Number { See one # Execute GetOne() See two # Execute GetTwo() See three # Execute 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 .. index:: pair: Language Design; Define Natural Statements Define Natural Statements ========================= After the object access using { } if the class contains a method called BraceEnd() it will be executed! .. code-block:: ring TimeForFun = new journey # The first surprise! TimeForFun { Hello it is me # What a beatiful programming world! } # Our Class Class journey hello=0 it=0 is=0 me=0 func GetHello See "Hello" + nl func braceEnd See "Goodbye!" + nl We can execute code written in strings using the Eval() function .. code-block:: ring cCode = "See 'Code that will be executed later!' " Eval(cCode) # execute the code to print the message We can create a list then execute code generated from that list .. code-block:: ring aWords = ["hello","it","is","me"] for word in aWords cCode=word+"=0" eval(cCode) next We can read text files using the Read(cFileName) function and we can write files using the Write(cFileName,cString) function. .. code-block:: ring See "Enter File Name:" Give cFileName See Read(cFileName) # Print the file content The next example presents how to create a class that defines two instructions The first instruction is : I want window The second instruction is : Window title = Expression Also keywords that can be ignored like the ‘the’ keyword .. code-block:: ring New App { I want window The window title = "hello world" } Class App # Attributes for the instruction I want window i want window nIwantwindow = 0 # Attributes for the instruction Window title # Here we don't define the window attribute again title nWindowTitle = 0 # Keywords to ignore, just give them any value 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 To complete the previous example, use read() to get the content of a file that contains .. code-block:: ring I want window The window title = "hello world" Then use eval() to execute the content of that file!. Also, you can update the methods GetWindow() and SetTitle() to create Real windows using the GUI Library .. index:: pair: Language Design; Define Declarative Languages Define Declarative Languages ============================ We learned how to use Natural statements to execute our code and using the same features we can use nested structures to execute our code. The next example from the Web library, generate HTML document using the Bootstrap library. No HTML code is written directly in this example, we created a similar language (just as example) Then using this declarative language that uses nested structures, we generated the HTML Document.. The idea in this example is that the GetDiv() and GetH1() methods return an object that we can access using {} and after each object access the method BraceEnd() will be executed to send the generated HTML to the parent object until we reach to the root where BraceEnd() will print the output. .. code-block:: ring 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 } } } The classes that power the declarative interface looks like this .. code-block:: ring 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) .. index:: pair: Language Design; Syntax Flexibility Syntax Flexibility ================== Ring comes with many styles for writing your source code! Also you can change the language keywords and operators and create your custom style! .. index:: pair: Language Design; Transparent Implementation Transparent Implementation ========================== Ring comes with transparent implementation. We can know what is happening in each compiler stage and what is going on during the run-time by the Virtual Machine Example : ring helloworld.ring -tokens -rules -ic .. code-block:: ring See "Hello, World!" Output .. code-block:: ring ================================================================== 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! .. index:: pair: Language Design; Visual Implementation Visual Implementation ===================== The Ring programming language is designed using the PWCT visual programming tool and you will find the visual source of the language in the folder "visualsrc" - *.ssf files and the generated source code (In the C Language) in the src folder and the include folder. The next screen shot from the ring_vm.ssf file (Generate ring_vm.c and ring_vm.h) .. image:: visualsrc1.jpg The next screen shot from the ring_list.ssf file (Generate ring_list.c and ring_list.h) .. image:: visualsrc2.JPG .. index:: pair: Language Design; Smart Garbage Collector Smart Garbage Collector ======================= Avoid memory problems :- * Invalid Memory Access * Memory leaks * Uninitialized Memory Access * Dangling pointer Rules :- * Global variables always stay in the memory, until you delete these variables using the assignment statement. * Local variables always deleted after the end of the function. * The programmer have full control on when to delete the variable from the memory using the Assignment statement. Example: .. code-block:: ring aList = [1,2,3,4,5] aList = "nice" After the second line directly, The list [1,2,3,4,5] will be deleted from the memory and we will have a string "nice" * The programmer can call the function callgc() to force running the garbage collector. * If we have a reference to a variable (when we pass objects and lists to functions), then deleting variables will be based on reference counting, if no references everything will be deleted, but if we have a reference, the data will stay in memory. .. index:: pair: Language Design; No Global Interpreter (VM) Lock - No GIL No Global Interpreter (VM) Lock - No GIL ======================================== When we use threads in Ring applications, We don't have global interpreter (VM) lock (No GIL) So threads can work in parallel and execute Ring instructions at the same time This is better for threads and concurrency (More Faster!) .. index:: pair: Language Design; Fast Enough For Many Applications Fast Enough For Many Applications ================================= Ring is designed to be a simple, small and flexible language in the first place, but also it is fast enough for many applications. Ring can do each of the next tasks in around 1 second using normal computers in the market during the last 5 years (1) Compiling 100,000 lines of code (2) Executing empty loop that count from 1 to 10,000,000 (3) Executing 1000 search operation using linear search in a list contains 100,000 items, trying to find the last item (The worst case) (4) Creating list contains 1,000,000 items then summing all of the list items (5) Adding 20,000 items to the ListWidget in GUI applications (6) Adding 5,000 nodes to the TreeWidget in GUI applications (7) Printing 10,000 messages to the terminal in Console applications Also when we need more speed we can use C/C++ extensions!