Well, my OS is exokernel, so the point is that programs need to be able to do as much as they want. That means for the language that it has to support programming from a level as low as C to as high as Java, and multiparadigm where possible. I have some prototype ideas on how I want to have stuff done, mainly it comes down to having very sophisticated Aspect-oriented features and template support.
import Kernel;
import GraphicsIPC;
import GC;
import String;
namespace default
{
use GC; // Garbagecollection by default
use String::autotostring; //allow automatic conversion to string
function getframebuffer () returns (boolean *, -GC void ptr framebufferaddress)
{
Log("initializing framebuffer");
Kernel::AllocatePageDirectory(0xE0000000, -1);
(boolean b, String s) = GraphicsIPC::RequestFramebufferAccess()
if (!b) { Log(s); return (b, null); }
Log("Framebuffer access granted");
(framebufferaddress, int bytes,*) = GraphicsIPC::GetFramebufferProperties();
Log("Framebuffer base address at 0x" + framebufferaddress + String::NEWLINE);
processif (Compiler::Arch == ARCH_I386)
subsection
{
use Kernel::Registers;
directive exclusive([edi,eax,ecx]);
edi = framebufferaddress;
ecx = bytes >> 2; // will compute bytes
eax = 0;
asm "cld";
asm "rep stosd";
}
else
memclear(framebufferaddress, bytes);
// return success, the lfb address was already set.
return (true, *);
}
// etc
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
I am actually intending to do this at some point, but I am still at the design stage of only having a vague impression of how I want it to work -- I haven't gotten nearly as far as deciding how I want it to look.
I think MessiahAndrew's language looks nice.
Mine would intentionally be an unstructured language -- much more K&R C-like than his C++ style. My language will have lots of pointers and gotos and will encourage their use (IMO structured programming is idiotic). The standard types will have defined sizes -- programmers will be encouraged to use those types, and #typedef'ing will be discouraged (IMO typedefs are vastly overused, and obfuscate memory usage).
I like the multiple return values.
One other thing that I am concerned about is separating error returns from value returns. In almost all coding, when a function returns you want to first test if the function got an error, and then use/save the return value. And in ASM, you can use some EFLAGS bits for indicating error returns. I'd like to extend that feature into the HLL. But this means that I'd need some way of handling error returns as exceptions or something, rather than having all the error handling built directly into the code, perhaps. And truly, I find it very irritating to write code where I have to test every single function return for an error, and then handle that error somehow -- when in truth, almost all functions return good values under almost all circumstances. Error handling should not be such a large part of the code, as it usually is.
Im nowhere near needing a language for my OS but if I had to make one I would probably keep it close to ASM since IMO its the easiest to learn but kick it up a level so as to make writing it a tad less tedious. Im still toying with the pointer idea but the rest of it is prettty solid.
Probably an ASM and C++ hybrid with a touch of pascal:
int start:
.variables
32 hello := "Hello World!",0; \\variables are declared by bit size not by type
32 output; \\Since hello isnt a pointer all you can access is the 'H' in this form
.code
push output; \\reliqueshes both its value and its name. If this isnt done then the address of output is written over to point to the function's output.
precall printf; \\precall inits all variables marked with pre for passing purposes
output = hello;
call printf;
pop output; \\gets both back now that output isnt in use
start := END_SUCCESSFULL;
end;
int printf:
.variables
16 x := 0; \\These two variables dont exist until call printf
32 char current;
32* char output (pre); \\This pointer is preinitialized. Pointer is the only variable type in this whole language.
.code
current := output[x]; \\Array stuff can be done on pointers with the address in question incing the variable size every element
while (current != 0);
\\Code to print the letter to screen
x++;
current := output[x];
end while;
ret SUCCESS; \\sets the value of printf and returns
This is the language of objects and links. It is basically not something that goes to a compiler. Hence you cannot write statements that do more work in one line. Hence instead of i=i-1 you write dec(i). The () at the start of each statement indicates the condition for that statement....
#struct test
int number
string id
#endstruct
#object printfun
test m
int i=5
string s="Salil is good"
(i>0) {
()printstring(s)
()dec(i)
()printnumber(m.number)
}
#endobject
Definately a cross between assembly and C. I'm good at both, and our OS project is in 16-bit assembly.
BTW, chezz, that seems awefully complicated. Way more so than regular assembly.
Solar wrote:It keeps stunning me how friendly we - as a community - are towards people who start programming "their first OS" who don't even have a solid understanding of pointers, their compiler, or how a OS is structured.
I maybe could see how its harder than assembly but I've always said "power and stupidity cannot exist in the same [programming] language." Powers such as functional variables that are only initialized when they are needed is going to come at the price of simplicity.
heh... I just quoted myself, that probably makes me seem a tad pretentious.
I know my limits and wouldn't attempt a new language for my OS - I would love to get to the stage where C# could be used as the main apps language, though (and anything else that can be compiled to the IL that I go for).
If I really found a loophole in this space-time continuum, I would work out things like this. But the absence of time wasn't really part of the question, more like that cliched "what if?"
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
/* reserved keywords
define, signed, struct, class, function, while, for, do, extern, return, this, new, delete, operator, static, asm
The C preprocessor will run through the sources files first
*/
define signed 4 MyGlobalVariable
struct hello
signed 4 Foo
unsigned 4 Bar
extern class someClassInAnotherFile
extern struct someStructInAnotherFile
class someBaseClass
function someMemberFunc() signed 4
printf("this is someClass, my address is %d\n", (unsigned 4)(deref this))
operator new() // called when class is created
Foo = 5
operator +(ref someClass)
Foo += someClass.Foo
virtual someMemberFunc2()
invisible
signed 4 Foo
class anotherBaseClass
// empty class
class someChildClass extend someBaseClass anotherBaseClass
function someMemberFunc2()
// overwrites above member - does nothing
function multiply2Numbers(signed 4 numA, signed 4 numB)
return numA * numB
function main()
define someChildClass HiThere
define ref someChildClass HiThere2 = ref HiThere // ref HiThere accesses the address of the variable
(deref HiThere2).someMemberFunc()
(deref (ref someBaseClass)HiThere2).someMemberFunc() // you can also type cast references
define signed 4 ACounter = 0
while ACounter < 10
printf("%d ",ACounter)
for ACounter = 0; ACounter < 5; ACounter++
printf("%d ",Acounter)
someChildClass = new someChildClass // dynamically allocate it
delete someChildClass // dynamically destroy it
define unsigned 8 AnotherVar // local scope only because it's indented
asm
eax = AnotherVar // all you can do in asm blocks is move variables in/out of registers
"int 100" // and call assembly instructions
AnotherVar = eax