+static CYExpression *CYTranslateExpression(CXTranslationUnit unit, CXCursor cursor) {
+ switch (CXCursorKind kind = clang_getCursorKind(cursor)) {
+ case CXCursor_CallExpr: {
+ CYExpression *function(NULL);
+ CYList<CYArgument> arguments;
+ CYForChild(cursor, fun([&](CXCursor child) {
+ CYExpression *expression(CYTranslateExpression(unit, child));
+ if (function == NULL)
+ function = expression;
+ else
+ arguments->*$C_(expression);
+ }));
+ return $C(function, arguments);
+ } break;
+
+ case CXCursor_DeclRefExpr: {
+ return $V(CYCXString(cursor).Pool($pool));
+ } break;
+
+ case CXCursor_IntegerLiteral: {
+ CYTokens tokens(unit, cursor);
+ _assert(tokens.count != 0);
+ // XXX: I don't understand why this is often enormous :/
+ return $ CYNumber(CYCastDouble(CYCXString(unit, tokens[0])));
+ } break;
+
+ case CXCursor_CStyleCastExpr:
+ // XXX: most of the time, this is a "NoOp" integer cast; but we should check it
+
+ case CXCursor_UnexposedExpr:
+ // there is a very high probability that this is actually an "ImplicitCastExpr"
+ // "Douglas Gregor" <dgregor@apple.com> err'd on the incorrect side of this one
+ // http://lists.llvm.org/pipermail/cfe-commits/Week-of-Mon-20110926/046998.html
+
+ case CXCursor_ParenExpr: {
+ CYExpression *pass(NULL);
+ CYOneChild(cursor, fun([&](CXCursor child) {
+ pass = CYTranslateExpression(unit, child);
+ }));
+ return pass;
+ } break;
+
+ default:
+ //std::cerr << "E:" << CYCXString(kind) << std::endl;
+ _assert(false);
+ }
+}
+
+static CYStatement *CYTranslateStatement(CXTranslationUnit unit, CXCursor cursor) {
+ switch (CXCursorKind kind = clang_getCursorKind(cursor)) {
+ case CXCursor_ReturnStmt: {
+ CYExpression *value(NULL);
+ CYOneChild(cursor, fun([&](CXCursor child) {
+ value = CYTranslateExpression(unit, child);
+ }));
+ return $ CYReturn(value);
+ } break;
+
+ default:
+ //std::cerr << "S:" << CYCXString(kind) << std::endl;
+ _assert(false);
+ }
+}
+
+static CYStatement *CYTranslateBlock(CXTranslationUnit unit, CXCursor cursor) {
+ CYList<CYStatement> statements;
+ CYForChild(cursor, fun([&](CXCursor child) {
+ statements->*CYTranslateStatement(unit, child);
+ }));
+ return $ CYBlock(statements);
+}
+