Wednesday, August 4, 2010

Zonnon - Basics by Example



The second of a series of basics statements and constructs of .NET/JVM Programming Language is here! This time the language chosen was Zonnon.
If you want to know more details about this interesting Programming Language you can find it here: http://carlosqt.blogspot.com/2010/06/oo-hello-world-zonnon.html

You can copy and paste the code below in your favorite IDE/Editor and start playing and learning with it. This little "working" program will teach you the basics of the Programming Language.

There are some "comments" on the code added just to tell you what are or how are some features called. In case you do not know the theory part, then you can read my previous post, where I give a definition of each of the concepts mentioned on the code. You can find it here: http://carlosqt.blogspot.com/2010/08/new-series-languages-basics-by-example.html

Greetings Program - Verbose
(* Zonnon Basics *)
module Main;  
import System;

(* Greeting Class and Contructor(No Args) *)
type {ref, public} Greet = object()
 (* Fields or Attributes *)
 var {private}
  message: string;
  name: string;
  loopMessage: integer;

 (* Getters and Setters - No "Working" Properties Support in version 1.2.7? *)
 procedure {public} GetMessage: string;
 begin  
  return self.message;
 end GetMessage;

 procedure {public} SetMessage(val: string);
 begin
  self.message := val;
 end SetMessage;

 procedure {public} GetName: string;
 begin  
  return self.name;
 end GetName;

 procedure {public} SetName(val: string);
 begin
  self.name := val;
 end SetName;

 procedure {public} GetLoopMessage: integer;
 begin  
  return self.loopMessage;
 end GetLoopMessage;

 procedure {public} SetLoopMessage(val: integer);
 begin
  self.loopMessage := val;
 end SetLoopMessage;

 (* Overloaded Constructor *)
 (* No Overloaded Constructors Support in version 1.2.7 *)

 (* Method 1 *)
 procedure {private} Capitalize(val: string): string;  
 begin
  if val.Length >= 1 then 
   return val.Substring(0, 1).ToUpper() + val.Substring(1, val.Length - 1);
  else
   return "";
  end;
 end Capitalize;  

 (* Method 2 *)
 procedure {public} Salute();  
 var i: integer;
 begin
  (* "for" statement *)
  for i := 0 to self.loopMessage do;
   writeln(self.Capitalize(self.message) + " " + self.Capitalize(self.name) + "!");
  end;   
 end Salute; 

 (* Overloaded Methods *)  
 (* No Overloaded Methods Support in version 1.2.7 *)

 (* Method 2.1 *)
 procedure {public} Salute21(message: string; name: string; loopMessage: integer);
 var i: integer;
 begin
  i := 0;
  (* "while" statement *)
  while i < loopMessage do;
   writeln(self.Capitalize(message) + " " + self.Capitalize(name) + "!");
   i := i + 1;
  end;
 end Salute21;

 (* Method 2.2 *)
 procedure {public} Salute22(name: string);
 var 
  dtNow: System.DateTime;
  time: integer;
 begin
  dtNow := System.DateTime.Now;
  time := dtNow.Hour;
  (* "switch/case" statement *)
  case time of  
      6..11 : 
    self.message := "good morning,"; 
   | 12..17 : 
    self.message := "good afternoon,"; 
   | 18..22 :
    self.message := "good evening,"; 
   (*| 23, 0..5 : this doesnt work in 1.2.8 use the following instead*)
   | 23,0,1,2,3,4,5 :
    self.message := "good night,"; 
   else   
          self.message := "huh?";
  end;   
  writeln(self.Capitalize(self.message) + " " + self.Capitalize(name) + "!");
 end Salute22;

(* Contructor | Initializer *)
begin  
 self.message := "";
 self.name := "";
 self.loopMessage := 0;
end Greet;  

(* Console Program *)
var   
 (* Define object of type Greet *)
 g: Greet;
begin   
 (* Instantiate Greet. Call Constructor *)
  g := new Greet();   
 (* Call Setters *)
 g.SetMessage("hello");
 g.SetName("world");
 g.SetLoopMessage(5);
 (* Call Method 2 *)
 g.Salute();
 (* Call Method 2.1 and Getters *)
 g.Salute21(g.GetMessage(), "zonnon", g.GetLoopMessage());
 (* Call Method 2.2 *)
 g.Salute22("carlos");
            
 (* Stop and exit *)
 writeln("Press any key to exit...");
 readln();
end Main.

Greetings Program - Minimal
(* Zonnon Basics *)
module Main;  
import System;

(* Greeting Class and Contructor(No Args) *)
type {ref} Greet = object
 (* Fields or Attributes *)
 var 
  message, name: string;
  loopMessage: integer;

 (* Getters and Setters - No "Working" Properties Support in version 1.2.7? *)
 procedure {public} GetMessage: string;
 begin  
  return message;
 end GetMessage;

 procedure {public} SetMessage(val: string);
 begin
  message := val;
 end SetMessage;

 procedure {public} GetName: string;
 begin  
  return name;
 end GetName;

 procedure {public} SetName(val: string);
 begin
  name := val;
 end SetName;

 procedure {public} GetLoopMessage: integer;
 begin  
  return loopMessage;
 end GetLoopMessage;

 procedure {public} SetLoopMessage(val: integer);
 begin
  loopMessage := val;
 end SetLoopMessage;

 (* Overloaded Constructor *)
 (* No Overloaded Constructors Support in version 1.2.7 *)

 (* Method 1 *)
 procedure Capitalize(val: string): string;  
 begin
  if val.Length >= 1 then 
   return val.Substring(0, 1).ToUpper() + val.Substring(1, val.Length - 1);
  else
   return "";
  end;
 end Capitalize;  

 (* Method 2 *)
 procedure {public} Salute;  
 var i: integer;
 begin
  (* "for" statement *)
  for i := 0 to loopMessage do;
   writeln(Capitalize(message) + " " + Capitalize(name) + "!");
  end;   
 end Salute; 

 (* Overloaded Methods *)  
 (* No Overloaded Methods Support in version 1.2.7 *)

 (* Method 2.1 *)
 procedure {public} Salute21(message: string; name: string; loopMessage: integer);
 var i: integer;
 begin
  i := 0;
  (* "while" statement *)
  while i < loopMessage do;
   writeln(Capitalize(message) + " " + Capitalize(name) + "!");
   i := i + 1;
  end;
 end Salute21;

 (* Method 2.2 *)
 procedure {public} Salute22(name: string);
 var 
  dtNow: System.DateTime;
  time: integer;
 begin
  dtNow := System.DateTime.Now;
  time := dtNow.Hour;
  (* "switch/case" statement *)
  case time of  
       6..11 : 
    message := "good morning,"; 
   | 12..17 : 
    message := "good afternoon,"; 
   | 18..22 :
    message := "good evening,"; 
    (*| 23, 0..5 : this doesnt work in 1.2.8 use the following instead*)
   | 23,0,1,2,3,4,5 :
    message := "good night,"; 
   else   
          message := "huh?";
  end;   
  writeln(Capitalize(message) + " " + Capitalize(name) + "!");
 end Salute22;

(* Contructor | Initializer *)
begin  
 message := "";
 name := "";
 loopMessage := 0;
end Greet;  

(* Console Program *)
var   
 (* Define object of type Greet *)
 g: Greet;
begin   
 (* Instantiate Greet. Call Constructor *)
  g := new Greet();   
 (* Call Setters *)
 g.SetMessage("hello");
 g.SetName("world");
 g.SetLoopMessage(5);
 (* Call Method 2 *)
 g.Salute();
 (* Call Method 2.1 and Getters *)
 g.Salute21(g.GetMessage(), "zonnon", g.GetLoopMessage());
 (* Call Method 2.2 *)
 g.Salute22("carlos");
            
 (* Stop and exit *)
 writeln("Press any key to exit...");
 readln();
end Main.

And the Output is:


I decided to take out some extra comments I added to the code to explain to myself the missing features of Zonnon (overloaded constructors, overloaded methods and properties), but added them with the code examples in the following code section:

(* Properties: *)
 (* It looks like there is some Properties support, but then you need to define your attributes outside 
  the type, into a definition object and then inherit from it in the type = object definition.
  Then you can start creating get and set procedures that also implement each of the attributes defined
  in the definition object... which in fact looks like a normal procedure with more typing. Now, the 
  thing is that I was not able to make it work... I'm still doing some research on that, but for the 
  time being I decided to use Getters and Setters, BUT, definitively, I will show you here below the syntax 
  for those = Get and Set Properties:*)

  (* Step 1: Create a Definition *)
  definition GreetAttributes;
  var {private}
   message, name: string;    
   loopMessage: integer;
  end GreetAttributes;
  
  (* Step 2: Define your Type and Implement from GreetDataMembers Definition *)
  type {ref, public} Greet = object() implements GreetDataMembers

  (* Step 3: Do not define Attributes on the Type (we will use Definition's Attributes) *)  
  
  (* Step 4: Create a Get Property for message attribute which implements attribute in definition *)
  procedure {get, public} message(): string implements GreetDataMembers.message;
  begin
   return self.message;
  end message;

  (* Step 5: Create a Set Property for message attribute which implements attribute in definition *)
  procedure {set, public} message(val: string) implements GreetDataMembers.message;
  begin
   self.message := val;
  end message;

(* Overloaded Constructors: *)
(* Overloaded Constructors are not supported in version 1.2.7 *)
 (* If you need parameters in the constructor
    You need to define the Greet Type as follows: *)
  
  type {ref, public} Greet = object(message: string; name: string; loopMessage: integer) 

  (*  And then update the Constructor | Initialize section of the Type to initialize the values: *)

  begin  
   self.message := message;
   self.name := name;
   self.loopMessage := 0;
  end Greet;  

(* Overloaded Methods: *)
(* Overloaded Methods are not supported in version 1.2.7 *)
 (* If you try to declare the same method name even if the signature differs it gives the following error message 

  "[2015] Duplicate declaration with the name 'Salute' in the current scope" BEEP!

  So, I'm calling the next methods Salute21 and Salute22 (cuz they suppose to be overloading Method 2
 *)

No comments:

Post a Comment