The Artima Developer Community
Sponsored Link

Heron-Centric: Ruminations of a Language Designer
Looking at Heron Primitives
by Christopher Diggins
September 1, 2005
Summary
I have made a pre-release of HeronFront which semi-successfully translates to C++ the primitives module from the standard library.

Advertisement

I said HeronFront semi-successfully translates to C++ because, besides virtually everything else interesting, there is no function invocation by string yet. That little feature is top priority and should be ready in a couple of days. Function invocation by string makes the HeronScript interpreter easy to implement.

For the time being it may interest some to see some of the changes in the language since the last time I posted Heron code. One thing which I mentioned briefly yesterday is that standalone operators are assumed to be prefix unary operators mapping to the object instance. This allows me to eliminate the need for the this keyword. You can refer to the object instance by value through * and by address through @.

Hopefully the operator overloading scheme is obvious enough. A cool feature of Heron is that it supports a sequence of any length of valid operator characters as an overloadable operator. For instance I could overload %^&! as a prefix/unary operator by simply writing a function named: _pre_percent_hat_ampersand_bang() ( the infix/binary version drops the leading _pre).

I know some people are going to be offended by what appears to be a preponderance of leading underscores. They are reserved for certain keywords, operator overload names, and system level primitives. As a result in the standard library you see a heck of a lot of them, but user-code should be much prettier. Part of their purpose is to make abuse unattractive.

Anyway, enought blabbering here is the current version of the primitives module:

module primitives_module
{
  public
  {
    class int
    {
      public {
        // constructor
        _init(_int x) { m = x; }
        // operators
        _eq(self x) { m = x.m;  }
        _plus_eq(self x) { m += x.m; }
        _minus_eq(self x) { m -= x.m; }
        _star_eq(self x) { m *= x.m; }
        _slash_eq(self x) { m /= x.m; }
        _percent_eq(self x) { m %= x.m; }
        _pre_minus() : self { result = -m; }
        _post_plus_plus() : self { result = *; ++m; }
        _post_minus_minus() : self { result = *; --m; }
        _pre_plus_plus() : self* { ++m; result = @; }
        _pre_minus_minus() : self* { --m; result = @; }
        _plus(self x) : self { result = *; result += x; }
        _minus(self x) : self { result = *; result -= x; }
        _star(self x) : self { result = *; result *= x; }
        _slash(self x) : self { result = *; result /= x; }
        _percent(self x) : self { result = *; result %= x; }
        _gt(self x) : bool { result = (compare(x) > 0); }
        _gt_eq(self x) : bool { result = (compare(x) >= 0); }
        _lt(self x) : bool { result = (compare(x) < 0); }
        _lt_eq(self x) : bool { result = (compare(x) <= 0); }
        _eq_eq(self x) : bool { result = (compare(x) == 0); }
        _bang_eq(self x) : bool { result = (compare(x) != 0); }
        // public methods
        compare(self x) : int { result = m.compare(x.m); }
        to_primitive() : _int { result = m; }
      }
      fields {
        _int m;
      }
    }

    class char {
      public {
        // constructors
        _init(_char x) { m = x; }
        // operators
        _eq(char x) { m = x.m; }
        _gt(self x) : bool { result = (compare(x) > 0); }
        _gt_eq(self x) : bool { result = (compare(x) >= 0); }
        _lt(self x) : bool { result = (compare(x) < 0); }
        _lt_eq(self x) : bool { result = (compare(x) <= 0); }
        _eq_eq(self x) : bool { result = (compare(x) == 0); }
        _bang_eq(self x) : bool { result = (compare(x) != 0); }
        // public member functions
        compare(self x) : int { result = m.compare(x.m); }
        to_primitive() : _char { result = m; }
      }
      fields {
        _char m;
      }
    }

    class bool {
      public {
        // constructor
        _init(_bool x) { m = x; }
        // operators
        _eq(bool x) { m = x.m; }
        _amp_amp(self x) : self { result = m && x.m; }
        _pipe_pipe(self x) : self { result = m || x.m; }
        _pre_bang() : self { result = !m; }
        _eq_eq(self x) : bool { result = (m == x.m); }
        _bang_eq(self x) : bool { result = (m != x.m); }
        // public member functions
        to_primitive() : _bool { result = m; }
      }
      fields {
        _bool m;
      }
    }
  }
}
To see what kind of C++ this translates to you can check out the file primitives.heron.hpp from the HeronFront pre-release at http://www.heron-language.com/heronfront-5-9-1.zip. Any questions?

Talk Back!

Have an opinion? Readers have already posted 11 comments about this weblog entry. Why not add yours?

RSS Feed

If you'd like to be notified whenever Christopher Diggins adds a new entry to his weblog, subscribe to his RSS feed.

About the Blogger

Christopher Diggins is a software developer and freelance writer. Christopher loves programming, but is eternally frustrated by the shortcomings of modern programming languages. As would any reasonable person in his shoes, he decided to quit his day job to write his own ( www.heron-language.com ). Christopher is the co-author of the C++ Cookbook from O'Reilly. Christopher can be reached through his home page at www.cdiggins.com.

This weblog entry is Copyright © 2005 Christopher Diggins. All rights reserved.

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2014 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use - Advertise with Us