🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

Epoch Success!

Published February 09, 2009
Advertisement
Bask in the utter awesome:

Epoch Win32 program demo

As the screenshot says, this app is written 100% in the Epoch programming language. The complete listing is fairly long, but most of it is declaring API function calls and structure types. Eventually I'll add support for multi-file compilation, and we can then move all the Win32 declarations into a shared location. For now, though, this works and works pretty well.

Here's the complete code of the app:
//// SCRIBBLE.EPOCH//// Basic Win32 application demo//library("Win32Util")function wndprocsignature : (integer, integer, integer, integer) -> (integer)structure point :(	integer(x),	integer(y))structure messagetype :(	integer(hwnd),	integer(message),	integer(wparam),	integer(lparam),	integer(time),	point(pt))structure wndclass :(	integer(size),	integer(style),	wndprocsignature(wndproc),	integer(classextra),	integer(wndextra),	integer(hinstance),	integer(hicon),	integer(hcursor),	integer(backgroundbrush),	string(menuname),	string(classname),	integer(hiconsmall))structure rect :(	integer(left),	integer(top),	integer(right),	integer(bottom))structure paintstruct :(	integer(hdc),	integer(erase),	rect(paintrect),	integer(restore),	integer(incupdate),	integer(reserved1),	integer(reserved2),	integer(reserved3),	integer(reserved4),	integer(reserved5),	integer(reserved6),	integer(reserved7),	integer(reserved8))external "user32.dll" GetMessageW : (messagetype ref(msg), integer(hwnd), integer(filtermin), integer(filtermax)) -> (boolean)external "user32.dll" TranslateMessage : (messagetype(msg)) -> (boolean)external "user32.dll" DispatchMessageW : (messagetype(msg)) -> (integer)external "user32.dll" PostQuitMessage : (integer(exitcode)) -> ()external "kernel32.dll" GetModuleHandleW : (integer(ignore)) -> (integer)external "user32.dll" RegisterClassExW : (wndclass(wc)) -> (integer)external "user32.dll" CreateWindowExW : (integer(exstyle),					string(classname),					string(caption),					integer(style),					integer(x),					integer(y),					integer(width),					integer(height),					integer(hwndparent),					integer(hmenu),					integer(hinstance),					integer(param)) -> (integer)external "user32.dll" DefWindowProcW : (integer(hwnd), integer(message), integer(wparam), integer(lparam)) -> (integer)external "user32.dll" ShowWindow : (integer(hwnd), integer(cmd)) -> (boolean)external "user32.dll" BeginPaint : (integer(hwnd), paintstruct ref(ps)) -> (integer)external "user32.dll" EndPaint : (integer(hwnd), paintstruct ref(ps)) -> (integer)external "user32.dll" LoadCursorW : (integer(hinstance), integer(name)) -> (integer)external "user32.dll" GetDC : (integer(hwnd)) -> (integer)external "gdi32.dll" LineTo : (integer(hdc), integer(x), integer(y)) -> (integer)external "gdi32.dll" MoveToEx : (integer(hdc), integer(x), integer(y), integer(ignored)) -> (integer)global{	integer(oldx, 0)	integer(oldy, 0)}entrypoint : () -> (){	integer(hInstance, GetModuleHandleW(0))	wndclass(wc, sizeof(wndclass), 0, mywndproc, 0, 0, hInstance, 0, LoadCursorW(0, 32512), 6, "", "ScribbleClass", 0)	RegisterClassExW(wc)		integer(hwnd, CreateWindowExW(0, "ScribbleClass", "Scribble", 13565952, -2147483648, 0, -2147483648, 0, 0, 0, hInstance, 0))	ShowWindow(hwnd, 5)	if(notequal(hwnd, 0))	{		point(pt, 0, 0)		messagetype(msg, 0, 0, 0, 0, 0, pt)		while(GetMessageW(msg, 0, 0, 0))		{			TranslateMessage(msg)			DispatchMessageW(msg)		}	}}mywndproc : (integer(hwnd), integer(message), integer(wparam), integer(lparam)) -> (integer(ret, 0)){	if(equal(message, 15))	{		rect(prect, 0, 0, 0, 0)		paintstruct(ps, 0, 0, prect, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)		BeginPaint(hwnd, ps)		EndPaint(hwnd, ps)		assign(ret, 0)	}	else	{		if(equal(message, 2))		{			PostQuitMessage(0)			assign(ret, 0)		}		else		{			if(equal(message, 512))			{				integer(x, loword(lparam))				integer(y, hiword(lparam))				integer(hdc, GetDC(hwnd))				if(equal(wparam, 1))				{					MoveToEx(hdc, oldx, oldy, 0)					LineTo(hdc, x, y)				}				assign(oldx, x)				assign(oldy, y)			}			else			{				assign(ret, DefWindowProcW(hwnd, message, wparam, lparam))			}		}	}}


Some drive-by commentary on the code:
  • I kind of lied about the code being 100% Epoch. I implemented a couple of helpers via the new Library system (see earlier post for details). This library is named, aptly enough, Win32Util. All it provides is wrappers for the HIWORD and LOWORD macros. I decided to put them in a library since they are platform-specific and don't really belong in the core language. Plus, it gives me a starting point for a shared Win32 support library.

  • Towards the beginning you can see a new bit of syntax - this allows us to declare a function signature and then refer to it by name later on. This greatly simplifies the use of first-class functions. The signature used here, wndprocsignature, is used by the wndclass structure, and represents your standard Windows message callback handler.

  • Another new feature is the ability to nest structures inside each other, as the messagetype and point structures demonstrate. Implementing this turned up a lot of bugs and oversights in the Fugue code, which have been taken care of.

  • Past all the API declarations, we see another new bit of syntax: the global block. These blocks can be placed anywhere at global (file) scope. They define variables which are globally available in all contexts. Naturally, use of this block is discouraged and unsafe... although the language doesn't do anything about it yet.

  • Another common problem is integer literals, aka "magic numbers". For instance, the call to CreateWindowExW specifies quite a few magic numbers. I will replace these with named constants eventually, as soon as I settle on a syntax for constants.

  • mywndproc is pretty ugly at the moment, because I haven't yet implemented the ability to chain if/elseif/elseif/else style blocks. That should be fairly low-hanging fruit so I may work on that soon.


So that's the state of Epoch at the moment... after a little more cleanup and polish, I think I'll be ready to unleash Release 5 on the world [grin]
Previous Entry An Epoch weekend
Next Entry Epoch, again.
0 likes 0 comments

Comments

Nobody has left a comment. You can be the first!
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Profile
Author
Advertisement
Advertisement