Tuesday, September 25, 2007

Mynx Semantics and Code Generation One Leads into the Other

In implementing Mynx semantic checks, and clarifying Mynx semantics in the Mynx programming language manual (MPLM), reading and writing information from the symbol table in the context object is not the only thing involved in the process.

Since Mynx has operator overloading, a valid syntax (but questionable semantics) Mynx source text, can not simply be translated into the high-level language source code. Note: Mynx will not generate direct machine code to assemble, it will compile into high-level Java/C# (and C/C++) source code. By using code synthesis (a term to distinguish from code generation phase in a compiler) will make the back-end of the compiler simpler than the front-end, which uses a new parsing algorithm + new programming language = square of complexity.

The question is that semantics gathers information (such as type) and annotates the information in the sentence for code synthesis.

For example, the simple expression statement with assignment:

x = y;

The Mynx variable identifier (presumption of declared in method used within) requires type annotation, such as Int.

x:type=Int = y:type=Int

The check for type that is type compatibility is based on the operator '=' that is translated into the method that is overloaded in the Int class for the operator '='. The external semantic information in a MOXI XML file is read, so that the '=' is the method 'set' that takes an Int parameter. The type of the operator is determined by the type of the variable identifier which is the l-val. Operator type checking is using external semantic MOXI file information, and instead of being hard and fast wired into the programming language, is determined by operator overloading with a method.

x:type=Int .set(Int == y:type=Int)

The type compatibility is valid, and the method is 'set' to be called for the operator '=' assignment. Thus the expression statement is type valid (presuming the types are declared before use in the method) and the expression statement is translated from the expression operators to the expression methods.

x.set(y); //-> x = y;

Hence semantic checks for sentence, context, and type are not just to verify that a Mynx source text is valid, but to annotate information in each sentence for the code synthesis stage. A syntactically valid Mynx source text cannot be used to synthesize the high-level language source code in Java/C# without semantic checks to annotate the needed information in the classes used in the Mynx source.

Labels: , , , , , ,

Monday, September 10, 2007

Mynx Constructor and Destructor Semantics

In implementing context semantics, and looking ahead toward sentence-method semantics (far ahead, after uniqueness are the existence semantics) one important semantic clarification (as you implement a new language, the meanings of things go from general to very specific to avoid ambiguity in the compiler implementation...although some languages are more specific than others) is in the use of constructors and destructor of a class.

Both constructor and destructor are distinct from other class methods in that they are not explicitly invoked, and neither are inherited by a sub-class from the super-class.

A destructor is invoked automatically in Java and C#, and in C++ the super-class destructors are also invoked when the class destructor is invoked (again, not explicitly but indirectly with a delete[] for instance). In Java a constructor is invoked (similar to C++ and C#) with a new, but a super-class constructor must be called explicitly. The semantics of explicitness and implicitness must be clarified and the semantic rules written in the Mynx Programming Language Manual (MPLM) the “Mynx Book” which is the language guide.

My general rule of thumb or heuristic is to avoid implicitness except where it is also possible to be explicit. An implicit default which has a converse with an explicit syntax is only half expressing a feature, the implicit feature is unexpressable.

By this heuristic the C++ feature of implicitly calling a destructor (when possible, many a memory leak from lack of the keyword ‘virtual’ or the destructor being protected or private) is a bad approach. The intention can get lost in non-existent code.

Mynx, unlike C++ and Java, does not automatically create a default constructor. The compiler will flag an error of not having a constructor in the class if one is not defined for a class that can have an instance.

In the same approach, Mynx does not implicitly call the super-class constructors or a super-class destructor. The use of a constructor or destructor in Mynx must be explicit. This raises the following points of semantics:

  1. What if a super-class constructor or destructor is never used?

  2. What if a super-class constructor or destructor is used?


As the Mynx constructor and destructor are never explicitly invoked by a user using the class, similarly there is a semantic constraint on using them in defining the class.

The used hints on the major point, where in a class can a super-class constructor or destructor be used? If not used, what is the potential consequence?

The latter question of non-use is a semantic error if the super-class is a concrete and non-static class. Not invoking a super-class constructor or destructor if defined can lead to class initialization anomalies, any super-class methods inherited could function inconsistently, and when the class is destroyed complete finalization anomalies. In short, if a super-class is sub-classed and the super-class is concrete and non-static, then the constructors and destructors must be used. If a super-class defines them, the sub-class must use.

The answer the the not using constructors and destructors of a super-class leads back to the former question of where can the constructor and destructor be used in a sub-class.

The answer is simple--only a sub-class constructor or destructor invokes the same in the super-class. The semantic context rule is like invokes like. This semantic constraint ensures that a constructor and destructor can never be called explicitly or used to define a method.

The semantic context rules of a constructor and destructor are like calls like, and if you have them in the super use them in the sub. One might be inclined to go for if a super-class has a destructor, the sub-class destructor first invokes all of them. But then there is the point in what order, and before the sub-class destructor code is invoked, or after, or at any point in between? Such ambiguity would have to be resolved by a Mynx implementation by the compiler writer, and create different versions of Mynx with an implicit approach to those questions.

Another heuristic of Mynx is to give the software developer choice, requiring explicitness even if it can be tedious (although with today’s software environments and tools, much of the tediousness is relieved by the tools).

A destructor defines or invokes the super-class destructor explictly. For a class with multiple super-classes it can be helpful to indicate invocation of all.

For example, invoking multiple destructors with a single invocation:

class X as A,B,C is

//other class source code...

public destruct is

super.destruct;

//class X destructor code, close files, sockets, release memory

end destructor;

end class;

The equivalent invocation of the destructor in the same sub-class is:

class X as A,B,C is

//other class source code...

public destruct is

super.destruct.A;
super.destruct.B;
super.destruct.C;

//class X destructor code, close files, sockets, release memory

end destructor;

end class;

The software developer has the choice of invoke super-class destructors implicitly using order of inheritance, or each destructor must occur in a specific order with sub-class destructor code inter-mixed, the software developer can be explicit.

Labels: , ,

Website Spy Software