Wiki

Porting C# code to Cobra

see Cobra differences fm C#

Heres a process for C# to Cobra generally.

  1. Take .cs file, rename to .cobra file.
  1. Change multiline comments from multiple // or /* */ bounded to be /# #/ bounded.

Change single line comments to use leading '#'

Remove extraneous separator line comments between method calls - if any

// ------------------------------

  1. Remove trailing ';' from each line they occur on
  1. Fixup blocking and indentation. Remove all '{' and '}' indicating start and end blocks from source.
    Ensure remaining blocks are all correctly (equally) indented and that indentation uses either all spaces or all Tabs and that the indents are in multiples of either 4 spaces or 1 tab.

  1. Fix 'using' statements:
    using -> use
    Remove any lines for
    using System
    using System.Collections.Generic
    using System.IO
    using System.Text
    
    as cobra includes these automagically

Change any other lines from

'using xxxx;' to 'use xxxx'

  1. Namespace decl Namespaces in cobra need to start with an upcased letter.
    Remove any lowercased prefix from namespace line
  1. Correct any Enum definitions.
    After applying the above its basically removing trailing ',' and ensuring indentation of enum items are all the same. e.g.
    enum ID_CONTROLS  {
        ID_RADIO_ORIENT = 5999,
        ID_CHK_SHOWIMAGES,
        ID_BTN_NEXT_PAGE,
        ID_NOTEBOOK
    }
    
    to
    enum ID_CONTROLS
        ID_RADIO_ORIENT = 5999
        ID_CHK_SHOWIMAGES
        ID_BTN_NEXT_PAGE
        ID_NOTEBOOK
    
  1. Fix class declaration syntax

Change lines like 'class X : Y' to 'class X inherits Y'

  1. Change any class instance attributes/fields to be prefixed with 'var'.

Change type and accessmodifier to cobra forms.

<Type> name = <init> ;

to

var name as <Type> = <init>

10. Fixup class constructor definitions

For initializer/constructor change lines like :

public ClassName(params,...) : base(baseParams,...) 

to

    cue init(params, ...) is public
        base.init(baseParams,...) 

Within the params list correct type declaration syntax from C# to cobra

[<accessModifier> ...] <Type> name, 

to

name as <Type> [is <accessModifier>, ...],

public is default accessModifier so can leave that off
e.g.

public GeoArea (string title, GeoPoint pos, Size size) : base(title, pos, size)

to

cue init(title as String, pos as GeoPoint, size as Size ) is public
    base.init (title, pos, size)

11. Remove any uses of 'new' to construct a class instance,

instead just make a call to the class type passing any initializer args, i.e just remove 'new'
e.g.

    var gFile = new GeoFile() -> gFile = GeoFile()
    new GeoPoint(10, 100)     -> GeoPoint(10, 100)
    new Size(650,340)	      -> Size(650, 340)

For classes that construct delegates (take method names) prefix the methodname with ref, methodNames must start with a lowercase letter and are prefixed by 'this.' or just '.' so change the methodName accordingly

e.g. new Listener( OnFileChange ) -> Listener(ref .onFileChange)

12. Methods:

Prefix methods with def.
Change methodnames to start with a lowercase letter,
Change param definitions to cobra form.

[<accessModifier> ...] <Type> name, -> name as <Type> [is <accessModifier>, ...],

Cobra methods by default return void and are public so if the C# code specifies public void you can just delete those words.

Also, if a method has no parameters then the empty trailing () can be left off.

Note builtin types:

C# string -> String (System.String)
C# object -> Object (System.Object)

public void OnFileChange( object sender, Event e )

to

def onFileChange(sender as Object, e as Event)  

No param method

    public override bool OnInit()

turns into

def onInit as bool is override 
    # or 
def onInit as bool is public, override # explicit

13. Calls to methods, properties and attributes/fields.

Instance method names, properties and fields are called with a prefix of 'this.' or just '.'
and they all must be named starting with a lowercase letter so the calls and settings
must be modified accordingly.

e.g.

    gFile.AppendPosn(...   -> 	gFile.appendPosn( ...
    CreateNewCity()       -> .createNewCity # or this.createNewCity

Similarly with properties and fields

    Street = new Street(this, ...   -> 	.street = Street(this, ...

If a method takes no args then any empty trailing () on a method call can/should be left off.

14. Property definition. Depending on the property use, prefix properties with :

  • get - readable property only
  • set - settable property only
  • pro - gettable and settable

Change property names to start with a lowercase letter

15. Local variables declared and assigned on first use can usually be changed to remove

the type definition (type inferred from the assignment) or can still be explicitly typed.

    DataItem info = new DataItem() 

changes to

    info = DataItem()     # or    info as DataItem = DataItem()

16. Fixup 'For' loops

for ( <Type> name = start ; name < stop; ++name ) 

becomes

for name as Type in start : stop : 1 # explicit or equally use shortcuts:
for name in start : stop : 1 
for name  in start : stop  # if step is one (1)
for name in stop           # if start is zero (0) and step is one (1)
    # same as for name in 0 : stop : 1

e.g

for ( int i = 0; i < 200; ++i ) -> for i in 0 : 200

17. Casting

Casts of form '(Type)name' become 'name to Type'
e.g. ... (object) cl.MyString ... --> ... cl.myString to Object ...

Casts of form 'a as Type' can also become 'name to Type' or 'name to? Type' e.g ListEvent le = event as ListEvent; ---> le = event to ListEvent

18. String concatenated with expressions (converted to string) can be modified to use string interpolation.

Put the expressions (suitably cobra converted) into the string inside []

e.g.

 "Value " + item.Value + " selected item: " + item.Selected 

becomes

"Value [item.value] selected item:[item.selected]" 

if you have [ and ] symbols, these should be doubled

e.g "some constant [ string ]" ---> "some constant [[ string ]]"

19. Boolean expressions must be reviewed to ensure that they will work correctly. Add parentheses to ensure that the C# boolean expressions (which give and precedence over or) will be evaluated correctly in Cobra (which gives and and or equal precedence.)

20. Adding eventHandlers

Cobra uses the listen statement to register event handlers where C# uses an override on the += operator.
Otherwise normal cobra mapping for method names and reference to methods (vs method calls) apply;
Methodnames in Cobra must start with a lower case letter and calls to this instance names are prefixed with 'this.' or (easier) '.'

When translating from a 'use'd library namespace, calls to capcased methodnames are referenced in cobra with the first char lowercased,
Upcased methodnames are referenced with the first word lowercased
so

    EVENT +=  new Listener(MethodName)  in C# becomes
    listen .EVENT,  Listener( ref .methodName ) 

becomes

    EVENT += new Listener( EH_METHOD_NAME ) in C# becomes
    listen .EVENT, Listener( ref .eh_METHOD_NAME ) 

e.g.

    FileChange += new Listener( OnFileChange )

turns into

    listen .fileChange,    Listener(ref .onFileChange) 

21. Main method

'public void' is default, static is an accessmodifier which becomes 'shared' in cobra, C# attributes (MetaInformation) are denoted with 'has' e.g.

[STAThread]
static public void main()

becomes

def main is shared has STAThread 

22. Multidimensional and/or fixed size jagged arrays

Multidimensional arrays are not supported by the language.

Jagged arrays of fixed size are possible but difficult to initialise. See  http://cobra-language.com/forums/viewtopic.php?f=4&t=654

for more information about these.