When have you found something that gave you pause and made you realize that more cooks in the kitchen is sometimes a good thing? Specifically, simple things you've seen that made you wonder why you never thought of them before.
+6
A:
Working on a Half-Life 2 mod I recently found in the source a simple way of keeping track of how many items exist in an enumeration. This comes in handy when doing lookups in, for example, an array of entity relations to see if they are friendly or not.
"Oh, duh!"
#include <iostream>
using namespace std;
enum Robots
{
Bender = 0,
Boxy,
Calculon,
Flexo,
Hedonismbot,
ReverendPreacherbot,
Roberto,
RobotDevil,
RobotMafia,
RobotSanta,
TinnyTim,
// Always add new robots above this line
NumRobots
};
void main()
{
cout << "There are " << NumRobots << " robot types" << endl;
}
RobotCaleb
2008-08-18 06:17:50
+5
A:
When I saw the 1-page assembler and interpreter in "The Awk Programming Language". It was a revelation!
http://plan9.bell-labs.com/cm/cs/awkbook
First a sample assembler program
# print sum of input numbers (terminated by zero)
ld zero # initialize sum to zero
st sum
loop get # read a number
jz done # no more input if number is zero
add sum # add in accumulated sum
st sum # store new value back in sum
j loop # go back and read another number
done ld sum # print sum
put
halt
zero const 0
sum const
And the assembler and interpreter
# asm - assembler and interpreter for simple computer
# usage: awk -f asm program-file data-files...
BEGIN {
srcfile = ARGV[1]
ARGV[1] = "" # remaining files are data
tempfile = "asm.temp"
n = split("const get put ld st add sub jpos jz j halt", x)
for (i = 1; i <= n; i++) # create table of op codes
op[x[i]] = i-1
# ASSEMBLER PASS 1
FS = "[ \t]+"
while (getline <srcfile > 0) {
sub(/#.*/, "") # strip comments
symtab[$1] = nextmem # remember label location
if ($2 != "") { # save op, addr if present
print $2 "\t" $3 >tempfile
nextmem++
}
}
close(tempfile)
# ASSEMBLER PASS 2
nextmem = 0
while (getline <tempfile > 0) {
if ($2 !~ /^[0-9]*$/) # if symbolic addr,
$2 = symtab[$2] # replace by numeric value
mem[nextmem++] = 1000 * op[$1] + $2 # pack into word
}
# INTERPRETER
for (pc = 0; pc >= 0; ) {
addr = mem[pc] % 1000
code = int(mem[pc++] / 1000)
if (code == op["get"]) { getline acc }
else if (code == op["put"]) { print acc }
else if (code == op["st"]) { mem[addr] = acc }
else if (code == op["ld"]) { acc = mem[addr] }
else if (code == op["add"]) { acc += mem[addr] }
else if (code == op["sub"]) { acc -= mem[addr] }
else if (code == op["jpos"]) { if (acc > 0) pc = addr }
else if (code == op["jz"]) { if (acc == 0) pc = addr }
else if (code == op["j"]) { pc = addr }
else if (code == op["halt"]) { pc = -1 }
else { pc = -1 }
}
}
Mark Harrison
2008-08-18 06:59:56