Cobra Code Examples
Some highlights of Cobra code and syntax ( on .Net).
These are selected cobra code samples for the same items as in VB and C# comparison.
Program Structure
#use System # already defaulted in namespace Hello class HelloWorld def main is shared name = "Cobra" args = CobraCore.commandLineArgs # See if an argument was passed from the command line # (first arg is progname) if args.count == 2 name = args[1] Console.writeLine("Hello, " + name + "!") #print "Hello, [name]!"
Comments
# Single line comment /# Multiple lines #/ # <summary>XML comments on single line</summary> /# <summary>XML comments on multiple lines</summary> #/
Data Types
These are as per .Net (using .Net naming rather than C#)
# Value Types bool uint8 # byte char int16, uint16, int, uint, int64, uint64 # short, ushort, int, uint, long, ulong float, float32, float64 #float, double Decimal DateTime #(not a built-in C# type) Struct Enum (enumerations) #Reference Types Object String arrays Sigs/Delegates #Initializing ( the explicit typing (clause 'as ????' ) is optional, types are inferred from initialisation) correct as bool = true b as uint8 = 0x2A # hex person as Object? = nil name as String = "Dwight" grade as char = c'B' today as DateTime= DateTime.parse("12/31/2010 12:15:00 PM") amount as decimal = 35.99 gpa as float = 2.9f pi as float64 = 3.14159265_f64 lTotal as int64 = 123456_i64 sTotal as int16 = 123 usTotal as uint16 = 123 uiTotal as uint = 123 # or 123u ulTotal as uint64 = 123 # or 123u64 #Nilable Types x as int? = nil #Anonymous Types # Havent worked out how Cobra handle these examples yet... #var stu = new {Name = "Sue", Gpa = 3.5} #var stu2 = new {Name = "Bob", Gpa = 2.9} # no Key equivalent #Implicitly Typed Local Variables s = "Hello!" nums = @[ 1, 2, 3 ] #init from array literal hero = SuperHero("Batman") #Type Information x as int? = 0 # Nilable int Console.writeLine(x.getType) # Prints System.Int32 Console.writeLine(sharp'typeof(int)') # Prints System.Int32 Console.writeLine(x.getType.name) # prints Int32 #Type Conversion / Casting d = 3.5f i = Convert.toInt32(d) # Set to 4 (rounds) i1 as int = d to int # set to 3 (truncates decimal)
Constants
const MAX_STUDENTS as int = 25 # Can set to a const or var; may be initialized in a constructor var MIN_DIAMETER as float is readonly= 4.93f
Enumerations
enum Action Start, Stop, Rewind, Forward enum Status Flunk = 50 Pass = 70 Excel = 90 a = Action.Stop if a <> Action.Start Console.writeLine(a + " is " + (int) a); # Prints "Stop is 1" Console.writeLine(Status.Pass to int) # Prints 70 Console.writeLine(Status.Pass) # Prints Pass
Operators
#Comparison == < > <= >= <> # Arithmetic + - * / % (mod) / (integer division if both operands are ints) Math.Pow(x, y) #Assignment = += -= *= /= %= &= |= ^= <<= >>= # +=1 -=1 # ++, -- No post increment/decrement #Bitwise & | ^ ~ << >> #Logical and or not #Note: and and or perform short-circuit logical evaluations #String Concatenation +
Choices
# Nil-coalescing operator x = y ? 5 # if y != null then x = y, else x = 5 # non nil coalescing x = y ! y.parseIt # if y nil x = nil else x = y.parseIt() # Ternary/Conditional operator greeting = if(age < 20, "What's up?", "Hello") if age < 20 greeting = "What's up?" else greeting = "Hello" # Multiple statements must be indented following if x <> 100 and y < 5 x *= 5 y *= 2 # braces not needed around condition expressions unless complicated if x > 5 x *= y else if x == 5 or y % 2 == 0 x += y else if x < 10 x -= y else x /= y # alternatively (1 liners) if x > 5, x *= y else if x == 5 or y % 2 == 0, x += y else if x < 10, x -= y else, x /= y # indented action blocks, breaks not needed case color # Must be integer, character, enumeration or string on "pink" or "red" #constants r++ on "blue" b++ on "green" g++ else other++ # 1 liners case color on 'pink' or 'red', r++ on 'blue', b++ on 'green', g++ else, other++
Loops
# re-test Loops: # no "until" keyword while c < 10 c += 1 for c in 2 : 11 : 2 # start: stop : step Console.writeLine(c) #print c #Post-test Loop: post while c < 10 c += 1 # Array or collection looping names = {"Fred", "Sue", "Barney"} for s in names Console.writeLine(s) # print s # Breaking out of loops i = 0 while true if i == 5 break i += 1 # Continue to next iteration for i in 0 : 5 if i < 4 continue print i #same as Console.writeLine(i) # Only prints 4
Arrays
#Preference is for (typed) collections rather than arrays
nums as int[] = @[1, 2, 3] for i in 0 : nums.length Console.writeLine(nums[i]) # 5 is the size of the array names as String[]= String[](5) names[0] = 'David'; names[5] = "Bobby"; # Throws System.IndexOutOfRangeException # Add two elements, keeping the existing values Array.resize(ref names, 7) # multi dim and jagged arrays not well supported (use Collections) twoD = sharp'new float[rows, cols]' twoD[2,0] = 4.5f jagged as int[][] = sharp'new int[3][] { new int[5], new int[2], new int[3] }' jagged[0][4] = 5
As a collection
nums = [1, 2, 3] for i in 0 : nums.count print nums[i] # 5 is the size of the array names = List(5) names[0] = "David"; names[5] = "Bobby"; # Throws System.IndexOutOfRangeException
Functions
# Pass by value (in, default), in/out reference (inout), and reference (out) def testFunc(x as int, y as inout int, z as out int) x += 1 y += 1 z = 5 # Accept variable number of arguments def sum(nums as vari int) as int sum as int = 0 for i in nums sum += i return sum def sayHello(name as String, prefix = "") Console.writeLine("Greetings, " + prefix + " " + name) def main a = 1 b = 1 c as int # c doesn't need initializing .testFunc(a, inout b, out c) Console.writeLine("{0} {1} {2}", a, b, c) # 1 2 5 assert c == 5 and b == 2 total = .sum(4, 3, 2, 1) # returns 10 assert total == 10 .sayHello("Strangelove", "Dr.") .sayHello("Mom")
Strings
# Escape sequences # \r # carriage-return # \n # line-feed # \t # tab # \\ # backslash # Can use either " or ' to delimit String literals # preference is for ' unless string contains ', then use " # String concatenation school = "Harding\t" school = school + "University" # school is "Harding (tab) University" school += "University" # Same thing school += 'University' # Same thing # Chars letter = school[0] # letter is H letter = 'Z' # letter is Z letter = Convert.toChar(65) # letter is A letter = 65 to Char # same thing word = school.toCharArray # word holds Harding # String literal string filename = r'c:\temp\x.dat' # Same as "c:\\temp\\x.dat" # String comparison mascot = 'Bisons' # or mascot = "Bisons" if mascot == "Bisons" # true if mascot.equals('Bisons') # true if mascot.toUpper.equals('BISONS') # true if mascot.compareTo('Bisons') == 0 # true # String matching - No Like equivalent, use Regex # Substring s = mascot.substring(2, 3) # s is "son" # Replacement s = mascot.replace('sons', 'nomial') # s is "Binomial" # Split names = 'Michael,Dwight,Jim,Pam' parts = names.split(','.toCharArray()) # One name in each slot #or parts = names.split([ c',']) # Date to string DateTime dt = DateTime(1973, 10, 12) s = dt.toString('MMM dd, yyyy') # Oct 12, 1973 # int to string x = 2 y = x.toString() # y is "2" # string to int x = Convert.toInt32('-5') # x is -5 # Mutable string buffer = System.Text.StringBuilder('two ') buffer.append('three ') buffer.insert(0, 'one ') buffer.replace('two', 'TWO') Console.writeLine(buffer) # Prints "one TWO three"
Regular Expressions
use System.Text.RegularExpressions # Match a string pattern r = Regex(r'j[aeiou]h?. \d:*', RegexOptions.IgnoreCase | RegexOptions.Compiled) if r.match('John 3:16').success # true Console.writeLine("Match") # Find and remember all matching patterns s = 'My number is 305-1881, not 305-1818.' r = Regex(r'(\\d+-\\d+)') # Matches 305-1881 and 305-1818 m as Match = r.match(s) while m.success #Console.writeLine("Found number: " + m.groups[1].toString + " at position " + m.groups[1].index.toString) print 'Found number: [m.groups[1]] at position [m.groups[1].index]' m = m.nextMatch to ! # Remember multiple parts of matched pattern r = Regex(r'(\d\d):(\d\d) (am|pm)') m = r.match("We left at 03:15 pm.") if m.success Console.writeLine("Hour: " + m.groups[1].toString) # 03 Console.writeLine("Min: " + m.groups[2].toString) # 15 Console.writeLine("Ending: " + m.groups[3].toString) # pm # Replace all occurrances of a pattern r = Regex(r'h\\w+?d', RegexOptions.IgnoreCase) s = r.replace("I heard this was HARD!", "easy") # I easy this was easy! # Replace matched patterns s = Regex.replace('123 < 456', r'(\d+) . (\d+)', '$2 > $1') # 456 > 123 # Split a string based on a pattern names = 'Michael, Dwight, Jim, Pam' r = Regex(r',\s*') parts = r.split(names) # One name in each slot
Exceptions
# Throw an exception up = Exception('Something is really wrong.') throw up # ha ha # Catch an exception try y = 0 x = 10 / y catch ex as Exception # Argument is optional, no "When" keyword Console.writeLine(ex.message) finally Microsoft.VisualBasic.Interaction.beep
Namespaces
namespace Harding.Compsci.Graphics ... # or namespace Harding namespace Compsci namespace Graphics ... use Harding.Compsci.Graphics
Classes and Interfaces
## Access Modifiers public # default private internal protected protected internal #Class Modifiers abstract shared #Method Modifiers abstract shared virtual #default #No Module equivalent - just use static class # Partial classes class Competition is partial ... # Inheritance class FootballGame inherits Competition ... # Interface definition interface IAlarmClock def ring # public returns void by default pro currentDateTime as DateTime from var } # Extending an interface interface IAlarmClock inherits IClock ... } # Interface implementation class WristWatch implements IAlarmClock, ITimer def ring Console.writeLine('Wake up!') pro triggerDateTime as DateTime from var ...
Constructors and Destructors
class SuperHero inherits Person var powerLevel as int is private var name as String is private # Default constructor cue init .powerLevel = 0 .name = 'Super Bison' cue init(powerLevel as int) base.init('Super Bison') # Call other constructor .powerLevel = powerLevel cue init(name as String) base.init(name) # Call base classes' constructor .name = name cue init is shared # Static constructor invoked before 1st instance is created cue finalize # Destructor implicitly creates a Finalize method
Using Objects
hero as SuperHero? = SuperHero() # No "With" but can use property initializers hero = SuperHero(name = "SpamMan", powerLevel = 3) hero.defend("Laura Jones") SuperHero.rest # Calling static method hero2 = hero # Both reference the same object hero2.name = 'WormWoman' Console.writeLine(hero.name) # Prints WormWoman hero = nil # Free the object if hero == nil # or if not hero hero = SuperHero() obj as Object = SuperHero() if obj inherits SuperHero Console.writeLine("Is a SuperHero object.") # Mark object for quick disposal using reader as StreamReader = File.openText("test.txt") line as String? while (line = reader.readLine) <> nil Console.writeLine(line)
Structs
struct Student var name as String var gpa as float cue init(name as String, gpa as float) .name = name .gpa = gpa stu = Student("Bob", 3.5f) stu2 = stu stu2.name = "Sue" Console.writeLine(stu.name) # Prints Bob Console.writeLine(stu2.name) # Prints Sue
Properties
# Auto-implemented properties pro name as String from var get size as int from var # Set default value in constructor # Traditional property implementation var name as String is private # private backing variable #or #var __name as String #private #var _name as String #protected pro Name as String get return .name # return __name set .name = value #__name = value # Read-only property var powerLevel as int is private # private backing variable get powerlevel from var #alternatively var __powerLevel = 0 # inferred as type int, private get powerlevel from var # Write-only property var height as double is private # private backing variable set height as double .height = if(value < 0, 0, value)
Generics
# Enforce accepted data type at compile-time numbers = List<of int>() numbers.add(2) numbers.add(4) .displayList<of int>(numbers) # Function can display any type of List def displayList<of T>(List<of T> list) for item as T in list Console.writeLine(item) # Class works on any data type class SillyList<of T> list as T[] = T[](10) rand as Random = Random() public void add(item as T) list[rand.next(10)] = item public getItem as T return list[rand.next(10)] } # Limit T to only types that implement IComparable def maximum<of T>(items as vari T) where T must be IComparable<of T> max as T = items[0] for item in items if item.compareTo(max) > 0 max = item return max
Delegates and Lambda Expresssions
sig HelloDelegate(s as String) # returns void def sayHello(s as String) Console.writeLine('Hello, ' + s) # C# 1.0 delegate syntax with named method hello as HelloDelegate = ref .sayHello hello('World') # Or hello.Invoke('World') # C# 2.0 delegate syntax with anonymous method # method body indented on lines following do(args) hello2 as HelloDelegate = do(s as String) Console.WriteLine('Hello, ' + s) hello2("World") # C# 3.0 delegate syntax with lambda expression HelloDelegate hello3 as HelloDelegate = do(s as string)=Console.writeLine('Hello, ' + s) hello3("World") # Use Func<in T, out TResult> delegate to call Uppercase convert as Func<of String, of String> = ref .uppercase Console.writeLine(convert("test")) def uppercase(s as String) return s.toUpper # Declare and invoke Func using a lambda expression Console.WriteLine( Func<of int, of int>do(num as int) = num + 1)(2)) # Pass lamba expression as an argument TestValues(do(x, y) = x % y == 0) void TestValues(Func<of int, of int, of bool> f) if f(8, 4) Console.writeLine("true") else Console.writeLine("false")
Events
sig MsgArrivedEventHandler(message as String) event MsgArrivedEvent as MsgArrivedEventHandler # listen EVENT_NAME, METHOD_NAME listen MsgArrivedEvent, ref .my_MsgArrivedEventCallback raise MsgArrivedEvent, "Test message" # fire event : Throws exception if obj is null #ignore EVENT_NAME, METHOD_NAME ignore MsgArrivedEvent, ref .my_MsgArrivedEventCallback using System.Windows.Forms myButton = Button() listen myButton.click, ref .myButton_Click #listen myButton.click, ref .myButton_Click to System.EventHandler def myButton_Click(sender as Object, e as System.EventArgs ) # same sig as System.EventHandler MessageBox.show(this, "Button was clicked", "Info", MessageBoxButtons.OK, MessageBoxIcon.Information)
LINQ
TBI
Attributes
# Attribute can be applied to anything class IsTestedAttribute inherits Attribute pass # Attribute can only be applied to classes or structs class AuthorAttribute inherits Attribute has AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct) pro name as String from var pro version as int from var cue init(name as String ) .name = name; .version = 0; class Shape has Author("Sue", version = 3) def move has IsTested # Do something...
Console I/O
Console.write("What's your name? ") name as String = Console.readLine Console.write('How old are you? ') age as int = Convert.toInt32(Console.readLine) Console.writeLine("{0} is {1} years old.", name, age) # or Console.writeLine(name + " is " + age + " years old.") c as int = Console.read # Read single char Console.writeLine(c) # Prints 65 if user enters "A" # alternatively print "What's your name? " stop name = Console.readLine print 'How old are you? ' stop age = Convert.toInt32(Console.readLine) print '[name] is [age] years old.' # or print String.format('{0} is {1} years old.', name, age) c as int = Console.read # Read single char print c # Prints 65 if user enters "A"
File I/O
#use System.IO # already autoloaded # Write out to text file writer as StreamWriter = File.createText(r'c:\myfile.txt') writer.writeLine('Out to file.') writer.close # Read all lines from text file reader as StreamReader = File.openText(r'c:\myfile.txt') line = reader.readLine while line Console.writeLine(line) line = reader.readLine reader.close # Write out to binary file str as String = "Text data" num = 123 binWriter = BinaryWriter(File.openWrite(r'c:\myfile.dat')) binWriter.write(str) binWriter.write(num) binWriter.close # Read from binary file binReader = BinaryReader(File.openRead(r'c:\myfile.dat')) str = binReader.readString num = binReader.readInt32 binReader.close
Return to wiki:WikiStart