Special BETA Constructs for JVM/CLR Support

To facilitate interoperability with JVM and CLR, a number of special constructs have been introduced into BETA. These constructs are mostly temporary workarounds, to get things up and running, and will be attempted handled in a more elegant way in a future release.

Special Prefix Patterns

A number of special superpatterns are available, which when used as prefix for a pattern will modify the way the pattern is mapped to JVM/CLR code. These are:
  1. ExternalClass
    The pattern ExternalClass is used to declare classes originating from outside BETA, e.g. Java or C# in BETA syntax. This is currently needed to allow the BETA compiler to support type-safe use of non-BETA classes. As this can be quite tedious to do by hand, a tool has been made, that will read the binary external classes and emit BETA declarations corresponding to them. In a future version of the BETA compiler, this may be automated.
    See ExternalClass below for specific usage of ExternalClass.
  2. class
    The pattern class is used to restrict a pattern to class usage only. As a BETA pattern can be used as both a class/type and as a method, normally code will be generated for both usages. Using class as prefix for a pattern will make the compiler not generate code for the usage of the pattern as a method.
    class is only used for patterns implementing functionality in BETA, i.e. not for classes in Java/.NET.
  3. proc
    The pattern proc is used to restrict a pattern to method usage only. As a BETA pattern can be used as both a class/type and as a method, normally code will be generated for both usages. Using proc as prefix for a pattern will make the compiler not generate code for the usage of the pattern as a class.
    proc is used both for patterns implementing methods in BETA and for methods in external classes.
  4. cons
    Using cons as a prefix of a pattern tells the compiler to generate special code for the pattern to be used as a constructor. These methods have special internal names and calling conventions in the generated byte codes. Specifying cons implies proc, i.e. the pattern cannot be used as a class.
    There may be specified more than one constructor, as long as they differ in enter lists (corresponding to signatures in the byte code).
    cons can be used both in a BETA pattern implementing functionality to be used from BETA and/or external languages, and in ExternalClass declarations.
    However, there is a problem in the current implementation: If the constructor is to be called from BETA code, it should include a local variable of the same type as the class it is creating, and the constructor should return this value, e.g.:
    Foo: 
      (# ...
         create: cons
           (# result: ^Foo;
           exit result[]
           #);
      #)
    
    On the other hand, if the constructor is to be called from outside BETA, you should not declare the variable and the exit part, since this will lead to illegal byte code.
    See Constructors below for further information on how to specify and use constructors in BETA patterns.
  5. static_proc
    Using static_proc as a prefix for a method in an ExternalClass specification (as opposed to just proc) tells the BETA compiler that this is a static method, which has a special calling convention in the byte code, and which is invoked on the external class itself and not on an object.
    Notice that specifying static_proc as a prefix of a pattern implementing functionality in BETA is not supported; the compiler will currently not complain, but generate non-functional (illegal) byte code.
  6. static_cons
    Using static_cons as a prefix for a method in an ExternalClass specification (as opposed to just cons) tells the BETA compiler that this is a static constructor which has a special calling convention in the byte code, and which is invoked on the external class itself and not on an object.
    Notice that specifying static_cons as a prefix of a pattern implementing functionality in BETA is not supported; the compiler will currently not complain, but generate non-functional (illegal) byte code.
Notice, that since these are to be used as superpatterns, you cannot specify a "real" superpattern. We hope to introduce a notation a la the .NET attributes into BETA, to allow for specifying these special behaviours without using superpattern notation.

Specifying JVM Packages

BETA code compiled with jbeta by default is emitted to the JVM package named beta. If another package is to be used (e.g. to because some java code is to use the BETA generated code), a new BETA property has been defined:
PACKAGE 'org.foo.bar';
This property can be added in the beginning of the file, typically just after ORIGIN.

External Class Declarations

To access an external class, you just make a BETA pattern with the prefix ExternalClass, and declares the various methods in this external class, you want to access, as local patterns with prefixes proc/static_proc/cons/static_cons. You furthermore specify the fully qualified class name of the class in the form of an assignment to an attribute called className inside the do-part of the ExternalClass. Finally you can declare (non-static) fields of the external objects, just by declaring dynamic BETA references with the correct qualification.
As an example, here is an excerpt of the ExternalClass declaration corresponding to the Java String class:
String: ExternalClass
  (#
     _init: cons (* constructor *)
       (# result: ^String;
       exit result[]
       #);
     ...
     _init_ArrayOfC: cons (* constructor *)
       (# result: ^String;
          arg1: [0]@char;
       enter (arg1[])
       exit result[]
       #);
     ...
     compareTo_String: proc (* overloaded compareTo *)
       (# result: @int32;
          arg1: ^String;
       enter (arg1[])
       do 'compareTo' -> procname;
       exit result
       #);
     compareTo_Object: proc (* overloaded compareTo *)
       (# result: @int32;
          arg1: ^Object;
       enter (arg1[])
       do 'compareTo' -> procname;
       exit result
       #);
     ...
  do 'java/lang/String' -> className;
#)
And here is the corresponding .NET declarations:
String: ExternalClass
  (# ...
     _init_ArrayOfChar: cons (* constructor *)
       (# result: ^String;
          arg1: [0]@char;
       enter (arg1[])
       exit result[]
       #);
     _init_char_int32: cons (* constructor *)
       (# result: ^String;
          arg1: @char;
          arg2: @int32;
       enter (arg1, arg2)
       exit result[]
       #);
     ...
     CompareTo_Object: proc (* overloaded CompareTo *)
       (# result: @int32;
          arg1: ^Object;
       enter (arg1[])
       do 'CompareTo' -> procname;
       exit result
       #);
     CompareTo_String: proc (* overloaded CompareTo *)
       (# result: @int32;
          arg1: ^String;
       enter (arg1[])
       do 'CompareTo' -> procname;
       exit result
       #);
     ...
  do '[mscorlib]System.String' -> className
#)
You can then instantiate String objects in BETA using these patterns, and subsequently access methods and fields in these objects.
It may seem confusing that the className specification resembles a statement, and a future version of the BETA compiler may support an improved way of specifying this.
Notice, that two tools have been provided, that can be used to convert an external class to corresponding BETA declarations instead of writing these by hand. In a future version of the compiler, this may be handled automatically.

Specializations of ExternalClasses

In BETA you can declare a subpattern of a pattern with prefix ExternalClass. This may mean two different things: Either you are just declaring an interface to another external class, which happens to be a subclass of the first external class you declared, or you want to implement a specialization of the external class in BETA.
To distinguish between these two situations, a subtle solution is currently supported by the compiler:

JVM Interfaces

The Java virtual machine use different calling conventions when calling interface-methods and class-methods. To inform jbeta about this, the pipe character '|' should be used as the first character when specifying the className for :
do '|.....' -> className;

CLR value types

The .NET CLR use different calling conventions when calling methods on reference types and valuetypes. To inform nbeta about this, the ad character '@' should be used as the first character when specifying the className for a value type:
do '@...' -> className

Constructors

There are currently four ways to declare a constructor in BETA code:

Instantiation

There are a number of ways to instantiate objects when using constructors:

Overloaded Methods

In external classes, method overloading is commonly used. This means that a number of methods in a class may have the same name, but different parameter lists and possibly return values (neither Java nor .NET allows for overloaded methods to be distinguished by different return values only).
BETA does not have overloaded pattern names. To declare interface to an ExternalClass with two or more methods with identical names, in BETA just make corresponding proc (or static_proc) declarations, where you specify the actual (identical) external name as a string argument to an attribute called procname in proc/static_proc. E.g.
foo: ExternalClass
  (# bar_I: proc
       (# i: @integer
       enter i	
       do 'bar' -> procname;
       #);
     bar_C: proc
       (# c: @char
       enter c
       do 'bar' -> procname;
       #);
  #);
It may seem confusing that the procname specification resembles a statement, and a future version of the BETA compiler may support an improved way of specifying this.

Not Yet Specifiable

The following do not yet have textual BETA representations, and thus cannot be expressed directly in BETA. To access such entities, you will currently have to make wrapper classes in Java/C#.