Major tasks: ------------ Apply the method verification process to indexers and properties as well. Properties and 17.6.3: Finish it. Finish pre-processor (and, or and nested expressions not yet supported). Implement base indexer access. base property access on a virtual method. Final should not be set for abstract method implementations. final should be set for implementations of interface methods. BUGS ---- * Major bug: Since I added the support for the dual interpreatation of names, I dont catch this error: class X { int i; static void a () { i = 1; } } * Currently the code path for 108/109 reporting is not being ran for methods as we need to compare method signatures. But since we retrieve the expensive method arguments in the method, we probably should do 108/109 processing there. * Emit warning on hiding members without NEW not only in members. * Implement visibility. * Adding variables. We do add variables in a number of places, and this is erroneous: void a (int b) { int b; } Also: void a (int b) { foreach (int b ...) ; } * Visibility I am not reporting errors on visibility yet. * Interfaces For indexers, the output of ix2.cs is different from our compiler and theirs. They use a DefaultMemberAttribute, which I have yet to figure out: .class interface private abstract auto ansi INTERFACE { .custom instance void [mscorlib]System.Reflection.DefaultMemberAttribute::.ctor(string) = ( 01 00 04 49 74 65 6D 00 00 ) // ...Item.. ... } * Interface indexers I have not figured out why the Microsoft version puts an `instance' attribute, and I am not generating this `instance' attribute. Explanation: The reason for the `instance' attribute on indexers is that indexers only apply to instances * Handle destructors specially Turn ~X () { a () } into: void Finalize () { try { a (); } finally { base.Finalize (); } } The code is mostly done, but `base' is missing. The reason it is missing is because we have to implement visibility first. * Arrays We need to make sure at *compile time* that the arguments in the expression list of an array creation are always positive. * Implement dead code elimination in statement.cs It is pretty simple to implement dead code elimination in if/do/while * Indexer bugs: the following wont work: x [0] = x [1] = N if x has indexers, the value of x [N] set is set to void. This needs to be fixed. * Array declarations Multi-dim arrays are declared as [,] instead of [0..,0..] * Break/Continue statements A finally block should reset the InLoop/LoopBegin/LoopEnd, as they are logically outside the scope of the loop. * Break/continue part 2. They should transfer control to the finally block if inside a try/catch block. * Conversions and overflow I am not using the checked state while doing type casts, they should result in conv.ovf.XXX * Method Registration and error CS111 The way we use the method registration to signal 111 is wrong. Method registration should only be used to register methodbuilders, we need an alternate method of checking for duplicates. * We need to catch: extern string Property { get { } } The get there should only have a semicolon * > // CSC sets beforefieldinit > class X { > // .cctor will be generated by compiler > public static readonly object O = new System.Object (); > public static void Main () {} > } > PENDING TASKS ------------- * Implement Goto. * Unsafe code. Making the parser accept unsafe code. * Implement `base' (BaseAccess class) * Implement constant folding. We might need to implement a new `Constant' class and derive Literal from it. * OUT Variables passed as OUT variables. Currently we pass the pointer to the pointer (see expression.cs:Argument.Emit) * Make the rules for inheritance/overriding apply to properties, operators and indexers (currently we only do this on methods). * Handle volatile * Static flow analysis Required to warn about reachability of code and definite assignemt as well as missing returns on functions. * Code cleanup The information when registering a method in InternalParameters is duplicated, you can always get the types from the InternalParameters OPTIMIZATIONS ------------- * Emitcontext Do we really need to instanciate this variable all the time? It could be static for all we care, and just use it for making sure that there are no recursive invocations on it. * Static-ization Since AppDomain exists, maybe we can get rid of all the stuff that is part of the `compiler instance' and just use globals everywhere. * Constructors Currently it calls the parent constructor before initializing fields. It should do it the other way around. * Use of EmitBranchable Currently I use brfalse/brtrue in the code for statements, instead of using the EmitBranchable function that lives in Binary * ConvertImplicit Currently ConvertImplicit will not catch things like: - IntLiteral in a float context to generate a -FloatLiteral. Instead it will perform an integer load followed by a conversion. * Tests Write tests for the various reference conversions. We have test for all the numeric conversions. * Remove the tree dumper, cleanup `public readonly' And make all the stuff which is `public readonly' be private unless required. * Optimizations In Indexers and Properties, probably support an EmitWithDup That emits the code to call Get and then leaves a this pointer in the stack, so that later a Store can be emitted using that this pointer (consider Property++ or Indexer++) * Optimizations: variable allocation. When local variables of a type are required, we should request the variable and later release it when we are done, so that the same local variable slot can be reused later on. * Add a cache for the various GetArrayMethod operations. * Optimization: Do not use StatementCollections, use ArrayLists of Statements, and then "copy" it out to arrays. Then reuse the existing Statement structures. * TypeManager.FindMembers: Instead of having hundreds of builder_to_blah hash table, have a single one that maps a TypeBuilder `t' to a set of classes that implement an interface that supports FindMembers. RECOMMENDATIONS --------------- * Use of lexer.Location in the parser Currently we do: TOKEN nt TERMINAL nt TERMINAL nt3 { $$ = new Blah ($2, $4, $6, lexer.Location); } This is bad, because the lexer.Location is for the last item in `nt3' We need to change that to use this pattern: TOKEN { oob_stack.Push (lexer.Location) } nt TERMINAL nt TERMINAL nt3 { $$ = new Blah ($3, $5, $7, (Location) oob_stack.Pop ()); } Notice how numbering of the arguments changes as the { oob_stack.Push (lexer.Location) } takes a "slot" in the productions. * local_variable_declaration Not sure that this grammar is correct, we might have to resolve this during semantic analysis. * Try/Catch Investigate what is the right value to return from `Emit' in there (ie, for the `all code paths return') * Optimizations Only create one `This' instance per class, and reuse it. Maybe keep a pool of constants/literals (zero, 1)? ************ Potential bug: We would need to decode the shortname before we lookup members? Maybe not. interface I { void A (); } class X : I { void I.A (); } class Y : X, I { void I.A () {} }