2005/5/10

     
 

AAL definition

artefaktur

| Intentional Programming | ACI Concept | AAL definition | AAL syntax | AAL parser | Object Representation | OpCode | Reference Links |

Spec of the language.

Content of this chapter:

   Code Unit
     Comments
   Types
     Other Types
       Arrays
     Coercion
     Storage types of values
     Allocator
   Module / Namespace
     Syntax
     Implementation
     Imports
     Globals
   Functions
     Syntax
     Implementation
   Classes
     Syntax
     Implementation
     Extend class methods/overwrite methods
     External Classes
   Functions and Methods
     Parameters
       Rest parameter types
     Operators
       Assocation of operators
       Operator precendence
       Name mapping for operators
   Closures
   Defun
     Intro
     Implementation
   Statement
     Left Hand Expression Assignments

 Code Unit

 Comments

Enable C and C++ comments.

 Types

The standard type system of ACDK should be supported:
  • Basic Types (int, char, etc.)
  • Class/Object Types
  • Function (implemented as anon Classes with operator()

 Other Types

  • Arrays of basic types and Objects (may implemented as object)
  • Enumerations (mapped to type?)
  • Const/static values (may implement a 'freeze' features of Objects)
  • Unions (probably not)

 Arrays

// aal
String[][] ds = String[][](2);
// acdk
StringArrayArray ds = StringArrayArray(2);
ds[0] = new StringArray(0);
ds[1] = new StringArray(0);

 Coercion

Which Types should be automatically converted:
  • int -> long (widen to long)
  • long -> int (error?, but castable)
  • int -> float (error?, but castable)
  • flot -> int (error, but castable)
  • int -> Object (Integer)
  • Object -> int (error, but castable)

 Storage types of values

  • Basic types as value by default.
  • Object types as reference by default.
  • in, out, inout, byval, byref modifier.

 Allocator

Support for Allocator, similar to C++/ACDK. Maybe use attributes for the 'new' operator?
Class A { /* ... */ }
A a = [OnStack] new A();
// or
A a =  new [OnStack] A();
The allocator concept is quite difficult to implement, may not implementable for all back ends (Java-ByteCode).

 Module / Namespace

 Syntax

Form 1:
namespace unit {
// all declaration in this block are part of unit
}
Form 2:
package unit;
// all further declaration are part of unit

 Implementation

Problem: - Should be implemented as Class with public static members? - Or should be implemented as namespace (using Unit)?

 Imports

imports just make the types of the given unit available in current scope. It is equivalent to 'using namespace unit;' of C++.
namespace unit {
  import anotherunit;
}

 Globals

int myGlobalInt = 42;
any myGlobalAny = initFunc();

 Functions

 Syntax

int foo(int i, String s)
{
}
Sample to implement a single method interface:
interface IFace
{
  public int foo(int i, String s);
}
int foo(int i, String s) implements IFace;
int foo(int i, String s) implements IFace.foo;

 Implementation

Alternatives:
  • Each free standing function has an assiated Class.
        int foo(int i, String s);
        //is mapped to 
        class foo 
        { 
          public static int operator()(int i, String s);
          
          /* alt
          public static int __call_static(int i , String s); 
          public int __call_dynamic(int i , String s); 
          */
        }
        
    Pro: Can be used as Object in Callback situation. Pro: Can be used to implement Interfaces. Con: Overhead of ClazzInfos
  • Functions are public static methods of the surounding unit. Pro/Con: opposite to free standing classes.

 Classes

 Syntax

class AClass
extends AnotherClass
implements AInterface
{
  int _myVar;
  AClass(int ival)
  : _myVar(ival)
  {
    _myVar = ival;
    this._myVar = ival;
  }
}
Allowing different flavor (Java, C++).

 Implementation

For each class a DClazzInfo instance will be generated, which is compatible with DMI ClazzInfo. This enables full DMI Server and Client functionality of Script Classes.

 Extend class methods/overwrite methods

class AClass
{
  public int foo(int i) { return i; }
}
AClass a = new AClass();

// extend the class with bar
extend int AClass.bar(int i) { return i; }

// extend instance with method
extend int a.bar(int i) { return i; }

// overwrite instance method
overwrite int a.foo(int i) { return i + 1; }

// overwrite class method
overwrite int AClass.foo(int i) { return i + 1; }

// failure, because incompatible signature
overwrite int AClass.foo(long i) { return i + 1; 

 External Classes

By default all ACDK and aal classes defined in current source file are available. To include the definition of other classes, a type of import functionality has to be provided:
[ // these will be evaluated while compile time
  use AcdkLib("acdk/net");
  use AcdkClass("acdk/net/SocketServer");
  use JavaClass("java/util/HashMap");
  use ComClass("Ms.Word");
}

 Functions and Methods

 Parameters

  • attributes in, out, inout:
     void foo(in int ival, out int oval);
  • named attributes
    foo(str := "asdf", ival := 42);
  • default attributes
    void foo(int ival = 42);
  • Rest-Collector as Array:
    void foo(int ival, rest ObjectArray args);
  • Rest-Collector as Hash:
    void foo(int ival, rest Params args);

 Rest parameter types

// ACDK
typedef ScriptVarArray RestArgs;
typedef core_vector<NamedArg> NamedRestArgs;

class AClass
{
  void foo(int i, IN(acdk::lang::dmi::RDmiObjectArray) rest);
  void bar(int i, IN(acdk::lang::dmi::RDNamedArgArray) rest);
};

AClass::standardDispatch( const char* classname, const char* fname
                          , ScriptVar& ret
                          , ScriptVarArray& args
                          , DmiClient& dc
                          , IN(::acdk::lang::RStringArray) namedArgs
                          , int flags
                          , const ClazzInfo* clazzinfo
                          , const ClazzMethodInfo* methinf/* = 0*/)
{
  // incase of foo
    foo(args[0].getIntVar(), getRest(1, args, namedArgs));
  // in case of bar
    foo(args[0].getIntVar(), getNamedRest(1, args, namedArgs));
};

ClazzMethodInfo* findFunction(...)
{
  if (arg->isRest())
    return meth;
  if (args->isNamedRest())
    checkEnoughNamedParameter()
    
    
}
// aal
class AClass
{
  void foo(int i, DmiObject[] rest);
  void foo(int i, DmiNamedArgs rest);
}

 Operators

Enable to create operators for classes:
class A
{
  A(String str);
  String toString();
  A operator+(A a) { return new A(toString() + a.toString()); }
  // internal name of this operator: 'operator_plus'
  void operator()(int i);
  // internal name of this operator: 'operator_call'
}
Rules for operators: An operator is a stream of chars except:
  • char '(' except it is the first character in operator
  • any legal identifier char (A-Za-z0-9_)
  • white spaces
class A
{
  // not very reasonable operator '(/^$\|@#%.,?'
  operator (/^$\|@#%.,?(int a);
}
Operators can have none or one parameter and follows the rules of C++. The corresponding DMI methods for an operator are named by following rule:

 Assocation of operators

By default all operators are associated with the left hand operant.
class AClass
{
  // left hand operator
  AClass operator+(AClass cls);
  // aclass1 + aclass2 -> aclass1.operator+(aclass2)
  AClass operator++();
  // aclass1++ aclass2 -> aclass1.operator++()
  
  // implicit right hand operator in C++
  AClass operator++(int); // C++
  // aclass1++ aclass2 -> aclass2.operator++() // C++ only
  
  // right hand operator
  AClass rhoperator+();
  // ++aclass1-> aclass1.operator++() // C++ only
}

If calling an operator, first an matching operatant on the left side of the operator will be found. If non found, an matching rhoperator will be searched for the operant on the right side. This will be done on runtime in case of dynamic binding or at compile time in case of static binding.

 Operator precendence

obj.member+a; // obj.operator.(member).operator+(a)
a+obj.member; // a.operator+(obj).operator.(member) // not the right way
List predefined operators in order of strength:
(...)
[...]
.&nbsp;
++ --
* /
+ -

 Name mapping for operators

operator >=(...);
// is
operator_gt_eq(...);
List of known operator with its corresponding names:
dt . dot
eq = equal
lt < lessthen
gt > greaterthen
nt ! not
cm , comma
pl + plus
hs # hash
ps % per[s]cent
as * asterix
mi - minus
sl / slash
bo [ bracketopen
bc ] bracketclose
dp : double point
bs \ backslash
vb | verticalbar
rf ^ roof
qs ? question
la & logical and
po ( parantesisopen
pc ) parantesisclose
tl ~ tilde
at @ at
pg  paragraph
dl $ dollar
co { closure open
cc } closure close
If no name mapping was found for a operator sign, the ascii code of the sign will be used.

 Closures

 Defun

 Intro

Working with closures it may not very handy always to define an interface for each method/operator. For the operator definitions of an interface, class or closure should automatically the typed interface available:
class AClass
{
  public int operator()(String s, int i) { ... }
  public static int operator()(String s, int i) { ... }
  public int doSomeThing(String s, int i) { ... }
  public static int staticMethod(int i) { ... }
}

defun AnCall int (String s, int i);
// or alias
defun AnCall int operator()(String s, int i);
defun AnPlusCall int operator+(String s, int i);
defun AnStaticCall static int (int i);

void foo(AnCall callable)
{
  callable("asdf", 42);
}

void bar(AnStaticCall callable)
{
  callable(42);
}

AnCall callable = new AClass(); // using operator()(String s, int i)
AnCall callable = new AClass().doSomeThing; // use doSomeThing(String s, int i)
AnCall callable = new () { int operator()(String s, int i) { ... } };
AnCall callable = AClass; // using static int AClass.operator()(String s, int i);
foo(callable);
AnStaticCall staticcall = AClass.staticMethod;
bar(staticcall);

 Implementation

May be support from DMI, which allows to generate ClazzInfos for Functions.
ACDK_DECL_FUNC(StringAdder);
class StringAdder
{
  ACDK_WITH_FUNC_METAINFO
public:
  RString operator+(IN(RString) s);
};
Which generates ClazzInfo for the operator+.

 Statement

 Left Hand Expression Assignments

// has to push outOf the variable of 
// foo.bar 
foo.bar = x;

// or more complex
(x, b) = x;