Skip navigation

Category Archives: C#

So over spring break I worked tirelessly, even through my severe rhinovirus infection at the end on a compiler for a new programming language that I’m developing which I call Fera.

I’m doing it purely for educational purposes right now, but if it turns out good maybe I’ll release it. It’s very similar to C#, but it just outright drops most of the historical baggage that it brought along from C.

The best example of this is the ‘switch’ construct in the language, which is something that pisses me off about C#. In C# switch statements you are required to place a ‘break’ instruction at the end of each case, with the exception of cases with no instructions, which fallthrough into the next case.

Example:

switch (x) {
 case 0:
 case 1:
   int y = 4;
   Console.WriteLine ("x is either 0 or 1");
   break; // this MUST be here
 case 2:
   int y = 6;   // compile-time error, 'y' already exists in the current scope
   Console.WriteLine ("x is 2");
   break; // this TOO must be here
}

Yes, even that last break has to be there, supposedly to make sure a developer never adds a case without adding the ‘break’ between the old last case and the new case. If you think about the logic of that it’s pretty retarded, and really is only there to make it look like Microsoft has improved it. As you see with the multiple definitions of ‘y’, the whole inside of a switch statement is within the scope it is placed in, meaning in order to define similarly-named variables within multiple case statements, you must place {}s around the cases like so:

switch (x) {
 case 0:
 case 1: {
   int y = 4;
   Console.WriteLine ("x is either 0 or 1");
   break; // this MUST be here
 } case 2: {
   int y = 6;   // compile-time error, 'y' already exists in the current scope
   Console.WriteLine ("x is 2");
   break; // this TOO must be here
 }
}

And boy, doesn’t that look retarded. All the current IDEs get confused too when you do this, changing the indent on lots of stuff while you hammer out the curly braces.

So with that said, here’s Fera’s interpretation of the switch statement.

switch (x) {
 case 0:
 case 1:
   int y = 4;
   Console.WriteLine ("x is either 0 or 1");
 case 2:
   int y = 6;
   Console.WriteLine ("x is 2");
}

As you see, each case statement is given it’s own variable scope, and a break at the end of each case is implicit. To fallthrough to the next statement, you use the ‘continue’ construct like so:

switch (x) {
 case 0:
 case 1:
   int y = 4;
   Console.WriteLine ("x is either 0 or 1");
   continue;
 case 2:
   int y = 6;
   Console.WriteLine ("x is 0, 1, or 2");
}

The ‘break’ construct works like it does in C# and other languages, using it causes the instruction pointer to exit the whole switch statement, allowing the next instruction to execute.

Another interesting thing about Fera’s switch statement is that it’s totally dynamic. The compiler is (well, isn’t yet but will be) capable of determining the static nature of the case statements for a given switch statement, so using static cases will allow the compiler to turn it into a constant time branch (CTB). But if it can’t do that it will just compile it as a simple cascading set of if/else branches.

int x = 3;
int y = 2;
switch (x) {
 case y + 1:
 case y + 2:
   int y = 4;
   Console.WriteLine ("x is 1 or 2 more than y");
 case 2:
   Console.WriteLine ("x is 2");
   break; // this TOO must be here
}

Naturally there are times when you want to ensure that the compiler can use static analysis to improve compilation of your switch. For this purpose, Fera provides the ‘branch’ construct:

branch (x) {
 case 0:
 case 1:
   Console.WriteLine ("x is either 0 or 1");
 case y+1:  // this causes a compile-time error
   Console.WriteLine ("x is 1 more than y");
}

This doesn’t guarantee that the construct will compile to a constant time branch any more than C#’s does, but at least it gives the compiler a chance while making sure the programmer doesn’t get any fancy ideas and use dynamic expressions for it’s cases.

So there’s tons more stuff I’m working to implement, but this is a particularly interesting bit which is already mostly implemented. I think I’ll post a few more blogs with info about some of the other features, like contract-based design, aspect-oriented programming, advanced language-level features and more.

Advertisements

Very much aligned with the fact that the control bitmap technique was wholly unsatisfactory, last night I changed the page allocator I’m working on to use the free page stack technique. I even wrote the code to allocate a range of contiguous physical pages. I still must finish paging and the basic memory mapping API.

I’ve started work on the memory manager implementation for SharpOS. Mostly this is because it hasn’t been done yet and I will need the functionality to test any of the other code (SharpOS.EIC and SharpOS.Runtime) using the SharpOS AOT compiler.

Using various internet resources I have hacked together what is a mega-basic page allocator. It uses the provided Multiboot information to determine the amount of RAM, and the offset/size of the kernel must be passed to MemoryManager.Init(). Using this information, it sets up a bitmap for control information on the first page past the end of the kernel, and reserves the pages below 0x100000 as well as the pages occupied by the kernel. The only thing left to implement for a basic page allocator is the Alloc/Dealloc, which is a matter of binary search.

The allocator also handles setting up 2-level paging and enabling it, but right now it does not relocate anything–so physical == virtual. I’d like to put the kernel in the higher half, but that requires modifying the segment base pointer so that we don’t have to relocate pointers (would be tedious). I think I need the AOT’s help to manipulate the segment base pointer at the right time (compile-time?).

Of course, the bitmap is not an ideal method of memory management. The bitmap search will be slow once lots of memory is allocated, and I’m looking into various ways of improving the performance. One method I’ve seen is to use another control bitmap for ‘superpages’ which represent large blocks of pages. Another method is to use a stack of free pages and just pop and push pages to it for allocation. This is a much faster way of allocating, but apparently gets difficult when allocating contiguous pages. I believe it is the method used by Linux and Windows NT though, which lends credence to the concept.

More later!

I’m currently working on a garbage collector written in C# for the SharpOS project. It’s an interesting project as the code must avoid making use of new managed objects to keep track of the old ones. Without managed objects I’m left with two possibilities–deal directly with unmanaged memory space and pointers or I can have the runtime have all objects explicitly implement an interface which includes the size of the GC tracking data in the size to be allocated. So the GC indirectly allocates the resources necessary to track it implicitly. This work is dependent on having a VMM to handle paging, swapping, etc. Chriss said he looked into it and will handle writing it. The GC code I have currently implements all the appropriate System.GC methods/members which are useful.

I’m following a site that lists the basic compacting/generational GC design. I’ll write more as I make the code more capable.

I was rather inspired by the return of Cosmoe today, so I decided to start a window system in C#.. which adds nicely to all the other things being rewritten for C#. It’s more of a back burner project, but maybe one day it’ll show stuff on the screen :). I’ll have more details later as I make them up.

First post by the way!