= Cobra Code Examples =
Some highlights of Cobra code and syntax ( on .Net).
These are selected cobra code samples for the same items as in
[http://www.harding.edu/fmccown/vbnet_csharp_comparison.html VB and C# comparison].
== Program Structure ==
{{{
#!cobra
#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 ==
{{{
#!cobra
# Single line comment
/# Multiple
lines #/
# XML comments on single line
/# XML comments on multiple lines #/
}}}
== Data Types ==
These are as per .Net (using .Net naming rather than C#)
{{{
#!cobra
# 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 ==
{{{
#!cobra
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 ==
{{{
#!cobra
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 ==
{{{
#!cobra
#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 ==
{{{
#!cobra
# 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 ==
{{{
#!cobra
# 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
{{{
#!cobra
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
{{{
#!cobra
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 ==
{{{
#!cobra
# 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 ==
{{{
#!cobra
# 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 ==
{{{
#!cobra
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 ==
{{{
#!cobra
# 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 ==
{{{
#!cobra
namespace Harding.Compsci.Graphics
...
# or
namespace Harding
namespace Compsci
namespace Graphics
...
use Harding.Compsci.Graphics
}}}
== Classes and Interfaces ==
{{{
#!cobra
## 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 ==
{{{
#!cobra
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 ==
{{{
#!cobra
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 ==
{{{
#!cobra
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 ==
{{{
#!cobra
# 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 ==
{{{
#!cobra
# Enforce accepted data type at compile-time
numbers = List()
numbers.add(2)
numbers.add(4)
.displayList(numbers)
# Function can display any type of List
def displayList(List list)
for item as T in list
Console.writeLine(item)
# Class works on any data type
class SillyList
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(items as vari T) where T must be IComparable
max as T = items[0]
for item in items
if item.compareTo(max) > 0
max = item
return max
}}}
== Delegates and Lambda Expresssions ==
{{{
#!cobra
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 delegate to call Uppercase
convert as Func = ref .uppercase
Console.writeLine(convert("test"))
def uppercase(s as String)
return s.toUpper
# Declare and invoke Func using a lambda expression
Console.WriteLine( Funcdo(num as int) = num + 1)(2))
# Pass lamba expression as an argument
TestValues(do(x, y) = x % y == 0)
void TestValues(Func f)
if f(8, 4)
Console.writeLine("true")
else
Console.writeLine("false")
}}}
== Events ==
{{{
#!cobra
sig MsgArrivedEventHandler(message as String)
event MsgArrivedEvent as MsgArrivedEventHandler
# listen EVENT_NAME, METHOD_NAME
listen MsgArrivedEvent, MsgArrivedEventHandler(.my_MsgArrivedEventCallback)
raise MsgArrivedEvent, "Test message" # Throws exception if obj is null
#ignore EVENT_NAME, METHOD_NAME
ignore MsgArrivedEvent, MsgArrivedEventHandler(.my_MsgArrivedEventCallback)
using System.Windows.Forms
myButton = Button()
listen myButton.click, System.EventHandler(ref .myButton_Click)
def myButton_Click(sender as Object, e as System.EventArgs )
MessageBox.show(this, "Button was clicked", "Info",
MessageBoxButtons.OK, MessageBoxIcon.Information)
}}}
== LINQ ==
TBI
{{{
#!cobra
}}}
== Attributes ==
{{{
#!cobra
# 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 ==
{{{
#!cobra
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 ==
{{{
#!cobra
#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