|
|
|
|
|
|
| Intentional Programming | ACI Concept | AAL definition | AAL syntax | AAL parser | Object Representation | OpCode | Reference Links |
Spec of the language.
Enable C and C++ comments.
The standard type system of ACDK should be supported:
- Basic Types (int, char, etc.)
- Class/Object Types
- Function (implemented as anon Classes with operator()
- 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)
// aal
String[][] ds = String[][](2);
// acdk
StringArrayArray ds = StringArrayArray(2);
ds[0] = new StringArray(0);
ds[1] = new StringArray(0);
|
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)
- Basic types as value by default.
- Object types as reference by default.
- in, out, inout, byval, byref modifier.
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).
Form 1:
namespace unit {
// all declaration in this block are part of unit
}
|
Form 2:
package unit;
// all further declaration are part of unit
|
Problem:
- Should be implemented as Class with public static members?
- Or should be implemented as namespace (using Unit)?
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;
}
|
int myGlobalInt = 42;
any myGlobalAny = initFunc();
|
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;
|
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.
class AClass
extends AnotherClass
implements AInterface
{
int _myVar;
AClass(int ival)
: _myVar(ival)
{
_myVar = ival;
this._myVar = ival;
}
}
|
Allowing different flavor (Java, C++).
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.
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;
|
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");
}
|
- attributes in, out, inout:
void foo(in int ival, out int oval);
|
- named attributes
foo(str := "asdf", ival := 42);
|
- default attributes
- Rest-Collector as Array:
void foo(int ival, rest ObjectArray args);
|
- Rest-Collector as Hash:
void foo(int ival, rest Params args);
|
// 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);
}
|
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:
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.
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:
(...)
[...]
.
++ --
* /
+ -
|
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.
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);
|
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+.
// has to push outOf the variable of
// foo.bar
foo.bar = x;
// or more complex
(x, b) = x;
|
|
|