It turns out I was over-engineering for just a menu system. If I planned to do dynamic heirarchical menus I would use the nested set trees, which I learned about the first time someone posted the articles Christian linked.

But I'm just going to do a static menu that is expanded to the appropriate level for the page I'm on. So one query to get the top-level menu, then one query to get the submenu for the section I'm in. I don't think I want to put more than two levels in the main menu, so set trees would be overkill.

But, just because I can't leave it alone until I've solved the problem, here's how to do what I originally asked:
CREATE OR REPLACE FUNCTION "get_menu_level"(text) RETURNS integer AS '\nDECLARE\n    menu_in ALIAS FOR $1;\n    parent_id TEXT;\n    level INTEGER;\n    parent_level INTEGER;\nBEGIN\n    level := 1;\n    SELECT INTO parent_id menu_parent FROM menu_tbl WHERE menu_id = menu_in;\n    IF parent_id IS NOT NULL THEN\n        parent_level := get_menu_level(parent_id);\n        level := level + parent_level;\n    END IF;\n    RETURN level;\nEND;\n' LANGUAGE 'plpgsql';\n\nselect *, get_menu_level(menu_id) from menu_tbl;