🎉 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!

While loops and more goodies

Published August 29, 2008
Advertisement
Took a few minutes this evening and hacked in while loops to the Epoch language. This is the second loop type, following up do/while loops which have been in for quite some time.

Part of implementing a while loop correctly involves elegantly skipping the loop body's instructions when the condition evaluates to false on the first iteration. In order to get this, I built in a new result value that is returned from every operation; this value acts as a flow control sentinel.

Any operation is free to modify this sentinel, although only one currently does, and that is a helper operation that while loops use to check their conditions. When the sentinel value is set appropriately, the currently executing loop will exit. This can also be extended trivially to allow early function returns.

The upshot is that break and return keywords will be laughably easy to implement, which I will probably do sometime tomorrow. This will significantly improve the power and flexibility of the language.

In addition, this mechanism should make it pretty simple to implement stack unwinding when it comes time to implement exceptions.


For the technically curious, here's a simple demo program and the VM bytecode it generates:

//// FLOWCONTROL.EPOCH//// Demonstration of basic flow control elements in Epoch//entrypoint : () -> (){	integer(foo, 10)	while(greater(foo, 0))	{		debugwritestring(cast(string, foo))		assign(foo, subtract(foo, 1))	}}


00887A5C SCOPEPARENT 00000000STACK 0ISCLONE 0VARS 0GHOSTS 0FUNCTIONS 1entrypoint 0088F3280088EF90 SCOPEPARENT 00000000STACK 0ISCLONE 0VARS 0GHOSTS 0FUNCTIONS 0TUPLETYPES 0TUPLEHINTS 00088F020 TYPEDATA 00088EBC0 SCOPEPARENT 00000000STACK 0ISCLONE 0VARS 0GHOSTS 0FUNCTIONS 0TUPLETYPES 0TUPLEHINTS 00088EC50 TYPEDATA 0BLOCK00C803F8 SCOPEPARENT 00887A5CSTACK 0ISCLONE 0VARS 1foo 1GHOSTS 0FUNCTIONS 0TUPLETYPES 0TUPLEHINTS 000C80488 TYPEDATA 000C81088 PUSH_INT 1000C81110 WRITE foo00C808C0 WHILEBLOCK00C811A0 SCOPEPARENT 00C803F8STACK 0ISCLONE 0VARS 0GHOSTS 0FUNCTIONS 0TUPLETYPES 0TUPLEHINTS 000C81230 TYPEDATA 000C809E8 PUSH 00C817C0 READ foo00C81BA8 PUSH_INT 000C81628 PUSH 00C815E0 GT00C810D0 CONDITIONAL_BREAK00C81BF0 PUSH 00C816D0 READ foo00C81990 PUSH 00C81718 INT_TO_STRING00C81520 DEBUG_WRITE00C81B58 PUSH 00C81EE8 READ foo00C82268 PUSH_INT 100C819D8 PUSH 00C81DC0 SUB_INT00C80878 WRITE fooENDBLOCKENDBLOCKTUPLETYPES 0TUPLEHINTS 000887AEC TYPEDATA 0STATIC_STR_POOL 210 entrypoint3 fooVAR_STR_POOL 0TUPLEINFOIDCOUNTER 00


The interesting bits are as follows:

BLOCK...00C809E8 PUSH 00C817C0 READ foo00C81BA8 PUSH_INT 000C81628 PUSH 00C815E0 GT00C810D0 CONDITIONAL_BREAK00C81BF0 PUSH 00C816D0 READ foo00C81990 PUSH 00C81718 INT_TO_STRING00C81520 DEBUG_WRITE00C81B58 PUSH 00C81EE8 READ foo00C82268 PUSH_INT 100C819D8 PUSH 00C81DC0 SUB_INT00C80878 WRITE fooENDBLOCK


This snippet of bytecode is the while loop body. Note the READ and PUSH_INT instructions at the top; these are the parameters to the greater function, which is a builtin invoked by the GT instruction.

The greater function will leave a boolean value on the stack: true if foo is greater than 0, false if not. This boolean value is then read off the stack by the CONDITIONAL_BREAK instruction. If the boolean is true, the loop body executes. Otherwise, the flow control sentinel flag is set to the "break" value, the loop body is skipped, and the loop itself is exited.


I consider this a fairly clean implementation since the VM is not technically a von Neumann architecture - code and data do not share memory space in the VM environment. In fact, code instructions do not have memory addresses like they would on a typical von Neumann system. This means that simple goto or jmp style instructions are impossible, since we can't specify a destination address.


So there's your daily peek into the progress and inner workings of Epoch [smile]

Release 4 is more or less on track; I've been distracted by the while loop stuff today, so structures aren't quite done yet. But it should still be easy to get them done over the long weekend. Definitely look for R4 sometime next week at the latest.
0 likes 1 comments

Comments

evolutional
Just read the past few days worth of entries... looking good there :)
August 30, 2008 06:16 AM
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Profile
Author
Advertisement
Advertisement