Trevor wrote:
> OK, I'll bite - please tell us more about REBOL -> C#.

First I wrote some programs in C# to get to know the language. Then I
realised that I was repeating a lot of information in each source file and
that I wasn't able to keep all the source files up to date accurately and
reliably. So I designed a Rebol dialect and it's associated interpreter in
Rebol to generate the C# code for me. As I repeated this process, I
discovered I could embed C# inside the Rebol dialect. This then allowed me
to automatically generate classes and their associated support classes just
from a basic description expressed as Rebol values, along with some specific
C# code stored inside a string value. For example, here's my Rebol dialect
for expressing a Person class:

Person: "Person's details." [
    Honourific: Honourific Global/Mesh/Honourifics
    Forename: string
    Surname: string
    Nickname: string
    Gender: Gender
    Relations: many Relation
    Birthday: DateTime
    Residence: Residence Global/Mesh/Residences
    Cellphone: Cellphone Global/Mesh/Cellphones
    Address: Address Global/Mesh/Addresses
    Email: many Email
    this: {
        public string Age {
            get {
                if (0 != birthday.Ticks) {
                    int Days, Months, Years;
                    DateTime Now = DateTime.Now;
                    DateTime Birth = Birthday;
                    Days = Now.Day - Birth.Day;
                    if (Days < 0) {
                        Months = Birth.Month + 1;
                        Years = Birth.Year;
                        if (12 < Months) {
                            Months = 1;
                            Years++;
                            }
                        DateTime n = new DateTime (Years, Months, 1);
                        Days = (n - Birth).Days + Now.Day - 1;
                        Birth = n;
                        }
                    Months = Now.Month - Birth.Month;
                    Years = Now.Year - Birth.Year;
                    if (Months < 0) {
                        Months = Months + 12;
                        Years = Years - 1;
                        }
                    return Years + " years, " + Months + " months, " + Days
+ " days.";
                    }
                return "";
                }
            }
        public override string ToString () {
            return Forename + " " + Surname;
            }
        }
    ]

Note that the above class refers to several other classes. After processing
by my Rebol dialect interpreter, the above description gets expanded into
several C# classes. Like this:

[Serializable]
[TypeConverter (typeof (PersonConverter))]
public class Person {
 public string DisplayName () {
  return "Person";
  }
 public string Description () {
  return "Person's details.";
  }
 [Editor (typeof (HonourificEditor), typeof(UITypeEditor))]
 [RefreshProperties (RefreshProperties.All)]
 [NotifyParentProperty (true)]
 public Honourific Honourific {
  get {return honourific;}
  set {honourific = value;}
  }
 Honourific honourific;
 [RefreshProperties (RefreshProperties.All)]
 [NotifyParentProperty (true)]
 public string Forename {
  get {return forename;}
  set {forename = value;}
  }
 string forename;
 [RefreshProperties (RefreshProperties.All)]
 [NotifyParentProperty (true)]
 public string Surname {
  get {return surname;}
  set {surname = value;}
  }
 string surname;
 [RefreshProperties (RefreshProperties.All)]
 [NotifyParentProperty (true)]
 public string Nickname {
  get {return nickname;}
  set {nickname = value;}
  }
 string nickname;
 [RefreshProperties (RefreshProperties.All)]
 [NotifyParentProperty (true)]
 public Gender Gender {
  get {return gender;}
  set {gender = value;}
  }
 Gender gender;
 [RefreshProperties (RefreshProperties.All)]
 [NotifyParentProperty (true)]
 public RelationCollection Relations {
  get {return relations;}
  set {relations = value;}
  }
 RelationCollection relations = new RelationCollection ();
 [RefreshProperties (RefreshProperties.All)]
 [NotifyParentProperty (true)]
 public DateTime Birthday {
  get {return birthday;}
  set {birthday = value;}
  }
 DateTime birthday;
 [Editor (typeof (ResidenceEditor), typeof(UITypeEditor))]
 [RefreshProperties (RefreshProperties.All)]
 [NotifyParentProperty (true)]
 public Residence Residence {
  get {return residence;}
  set {residence = value;}
  }
 Residence residence;
 [Editor (typeof (CellphoneEditor), typeof(UITypeEditor))]
 [RefreshProperties (RefreshProperties.All)]
 [NotifyParentProperty (true)]
 public Cellphone Cellphone {
  get {return cellphone;}
  set {cellphone = value;}
  }
 Cellphone cellphone;
 [Editor (typeof (AddressEditor), typeof(UITypeEditor))]
 [RefreshProperties (RefreshProperties.All)]
 [NotifyParentProperty (true)]
 public Address Address {
  get {return address;}
  set {address = value;}
  }
 Address address;
 [RefreshProperties (RefreshProperties.All)]
 [NotifyParentProperty (true)]
 public EmailCollection Email {
  get {return email;}
  set {email = value;}
  }
 EmailCollection email = new EmailCollection ();
 public string Age {
  get {
   if (0 != birthday.Ticks) {
    int Days, Months, Years;
    DateTime Now = DateTime.Now;
    DateTime Birth = Birthday;
    Days = Now.Day - Birth.Day;
    if (Days < 0) {
     Months = Birth.Month + 1;
     Years = Birth.Year;
     if (12 < Months) {
      Months = 1;
      Years++;
      }
     DateTime n = new DateTime (Years, Months, 1);
     Days = (n - Birth).Days + Now.Day - 1;
     Birth = n;
     }
    Months = Now.Month - Birth.Month;
    Years = Now.Year - Birth.Year;
    if (Months < 0) {
     Months = Months + 12;
     Years = Years - 1;
     }
    return Years + " years, " + Months + " months, " + Days + " days.";
    }
   return "";
   }
  }
 public override string ToString () {
  return Forename + " " + Surname;
  }
 public Person () {
  }
 }


[Serializable, TypeConverterAttribute (typeof (PersonCollectionConverter))]
public class PersonCollection : CollectionBase, ICustomTypeDescriptor {
 public int Add (Person s) {
  return (List.Add (s));
  }
 public int IndexOf (Person s) {
  return (List.IndexOf (s));
  }
 public void Insert (int Index, Person s) {
  List.Insert (Index, s);
  }
 public void Remove (Person s) {
  List.Remove (s);
  }
 public bool Contains (Person s) {
  return (List.Contains (s));
  }
 public Person this [int index] {
  get {return (Person)List[index];}
  set {List[index] = value;}
  }
 public static PersonCollection operator + (PersonCollection p, Person s) {
  p.Add (s);
  return p;
  }
 public String GetClassName() {
  return TypeDescriptor.GetClassName(this,true);
  }
 public AttributeCollection GetAttributes() {
  return TypeDescriptor.GetAttributes(this,true);
  }
 public String GetComponentName() {
  return TypeDescriptor.GetComponentName(this, true);
  }
 public TypeConverter GetConverter() {
  return TypeDescriptor.GetConverter(this, true);
  }
 public EventDescriptor GetDefaultEvent() {
  return TypeDescriptor.GetDefaultEvent(this, true);
  }
 public PropertyDescriptor GetDefaultProperty() {
  return TypeDescriptor.GetDefaultProperty(this, true);
  }
 public object GetEditor(Type editorBaseType) {
  return TypeDescriptor.GetEditor(this, editorBaseType, true);
  }
 public EventDescriptorCollection GetEvents(Attribute[] attributes) {
  return TypeDescriptor.GetEvents(this, attributes, true);
  }
 public EventDescriptorCollection GetEvents() {
  return TypeDescriptor.GetEvents(this, true);
  }
 public object GetPropertyOwner(PropertyDescriptor pd) {
  return this;
  }
 public PropertyDescriptorCollection GetProperties(Attribute[] attributes) {
  return GetProperties();
  }
 public PropertyDescriptorCollection GetProperties () {
  PropertyDescriptorCollection pdc = new PropertyDescriptorCollection
(null);
  for (int i = 0; i < List.Count; i++) {
   PersonCollectionPropertyDescriptor pd = new
PersonCollectionPropertyDescriptor (this, i);
   pdc.Add (pd);
   }
  return pdc;
  }
 }


public class PersonConverter : ExpandableObjectConverter {
 public override bool CanConvertTo (ITypeDescriptorContext context, Type
destinationType) {
  if (destinationType == typeof (Person)) {
   return true;
   }
  return base.CanConvertTo (context, destinationType);
  }

 public override object ConvertTo (ITypeDescriptorContext context,
CultureInfo culture, object value, Type destinationType) {
  if (destinationType == typeof (System.String) && value is Person) {
   }
  return base.ConvertTo (context, culture, value, destinationType);
  }
 }

public class PersonCollectionConverter : ExpandableObjectConverter {
 public override bool CanConvertTo (ITypeDescriptorContext context, Type
destinationType) {
  if (destinationType == typeof (PersonCollection)) {
   return true;
   }
  return base.CanConvertTo (context, destinationType);
  }

 public override object ConvertTo (ITypeDescriptorContext context,
CultureInfo culture, object value, Type destinationType) {
  if (destinationType == typeof (System.String) && value is
PersonCollection) {
   }
  return base.ConvertTo (context, culture, value, destinationType);
  }
 }

// [Editor (typeof (PersonEditor), typeof(UITypeEditor))]
public class PersonEditor : UITypeEditor {
 public override UITypeEditorEditStyle GetEditStyle (ITypeDescriptorContext
context) {
  if (null != context && null != context.Instance) {
   return UITypeEditorEditStyle.Modal;
   }
  return UITypeEditorEditStyle.None;
  }
 public override object EditValue (ITypeDescriptorContext context,
IServiceProvider provider, object value) {
  if (null != context && null != context.Instance && null != provider) {
   if (0 < Global.Mesh.Persons.Count) {
    CollectionPicker p = new CollectionPicker (value, Global.Mesh.Persons,
"Person");
    if (DialogResult.OK == p.ShowDialog ()) {
     return p.Picked;
     }
    } else {
     CollectionEditor ce = new CollectionEditor (Global.Mesh.Persons.GetType
());
     return ce.EditValue (context, provider, Global.Mesh.Persons);
    }
   }
  return value;
  }
 }

public class PersonCollectionPropertyDescriptor : PropertyDescriptor {
 PersonCollection personcollection = null;
 int index = -1;
 public PersonCollectionPropertyDescriptor (PersonCollection
PersonCollection, int Index) : base ("#" + Index, null) {
  personcollection = PersonCollection;
  index = Index;
  }
 public override AttributeCollection Attributes {
  get {return new AttributeCollection (null);}
  }
 public override bool CanResetValue (object component) {
  return true;
  }
 public override Type ComponentType {
  get {return personcollection.GetType ();}
  }
 public override string DisplayName {
  get {return personcollection[index].DisplayName ();}
  }
 public override string Description {
  get {return personcollection[index].Description ();}
  }
 public override object GetValue (object component) {
  return personcollection[index];
  }
 public override bool IsReadOnly {
  get {return false;}
  }
 public override string Name {
  get {return "#" + index;}
  }
 public override Type PropertyType {
  get {return personcollection[index].GetType ();}
  }
 public override bool ShouldSerializeValue (object component) {
  return true;
  }
 public override void ResetValue (object component) {
  // Do nothing.
  }
 public override void SetValue (object component, object value) {
  // Do nothing.
  // personcollection[index] = value;
  }
 }

Naturally the Rebol description is far easier to expand, maintain, verify
and correct than the C# equivalent.

Andrew J Martin
Speaking in tongues and performing miracles.
ICQ: 26227169
http://www.rebol.it/Valley/
http://valley.orcon.net.nz/
http://Valley.150m.com/
-><-

-- 
To unsubscribe from this list, just send an email to
[EMAIL PROTECTED] with unsubscribe as the subject.

Reply via email to