-/* Cycript - Optimizing JavaScript Compiler/Runtime
- * Copyright (C) 2009-2015 Jay Freeman (saurik)
+/* Cycript - The Truly Universal Scripting Language
+ * Copyright (C) 2009-2016 Jay Freeman (saurik)
*/
/* GNU Affero General Public License, Version 3 {{{ */
return out;
}
-typedef std::map<std::string, std::string> CYKeyMap;
+struct CYKey {
+ unsigned priority_ = 0;
+
+ std::string code_;
+ unsigned flags_;
+};
+
+typedef std::map<std::string, CYKey> CYKeyMap;
struct CYChildBaton {
CXTranslationUnit unit;
CYCXString spelling(cursor);
std::string name(spelling);
std::ostringstream value;
+ unsigned priority(2);
+ unsigned flags(0);
/*CXSourceLocation location(clang_getCursorLocation(cursor));
CYCXPosition<> position(location);
CXCursor cursors[tokens.size()];
clang_annotateTokens(unit, tokens, tokens.size(), cursors);
- CYCXPosition<> start(clang_getRangeStart(range));
- CYCXString first(unit, tokens[1]);
- if (first == "(") {
- CYCXPosition<> paren(unit, tokens[1]);
- if (start.offset_ + strlen(spelling) == paren.offset_)
- _assert(false); // XXX: support parameterized macros
+ CYLocalPool local;
+ CYList<CYFunctionParameter> parameters;
+ unsigned offset(1);
+
+ if (tokens.size() != 1) {
+ CYCXPosition<> start(clang_getRangeStart(range));
+ CYCXString first(unit, tokens[offset]);
+ if (first == "(") {
+ CYCXPosition<> paren(unit, tokens[offset]);
+ if (start.offset_ + strlen(spelling) == paren.offset_) {
+ for (;;) {
+ _assert(++offset != tokens.size());
+ CYCXString token(unit, tokens[offset]);
+ parameters->*$P($B($I(token.Pool($pool))));
+ _assert(++offset != tokens.size());
+ CYCXString comma(unit, tokens[offset]);
+ if (comma == ")")
+ break;
+ _assert(comma == ",");
+ }
+ ++offset;
+ }
+ }
}
- for (unsigned i(1); i != tokens.size(); ++i) {
+ std::ostringstream body;
+ for (unsigned i(offset); i != tokens.size(); ++i) {
CYCXString token(unit, tokens[i]);
- if (i != 1)
- value << " ";
- value << token;
+ if (i != offset)
+ body << " ";
+ body << token;
+ }
+
+ if (!parameters)
+ value << body.str();
+ else {
+ CYOptions options;
+ CYOutput out(*value.rdbuf(), options);
+ out << '(' << "function" << '(';
+ out << parameters;
+ out << ')' << '{';
+ out << "return" << ' ';
+ value << body.str();
+ out << ';' << '}' << ')';
}
} catch (const CYException &error) {
CYPool pool;
} break;
case CXCursor_StructDecl: {
- if (!clang_isCursorDefinition(cursor))
- goto skip;
if (spelling[0] == '\0')
goto skip;
+ if (!clang_isCursorDefinition(cursor))
+ priority = 1;
std::ostringstream types;
std::ostringstream names;
}
}));
+ value << "new Type([" << types.str() << "],[" << names.str() << "]).withName(\"" << name << "\")";
name += "$cy";
- value << "new Type([" << types.str() << "],[" << names.str() << "])";
} break;
case CXCursor_TypedefDecl: {
} break;
}
- baton.keys[name] = value.str();
+ {
+ CYKey &key(baton.keys[name]);
+ if (key.priority_ < priority) {
+ key.priority_ = priority;
+ key.code_ = value.str();
+ key.flags_ = flags;
+ }
+ }
skip:
return CXChildVisit_Continue;
clang_visitChildren(clang_getTranslationUnitCursor(unit), &CYChildVisit, &baton);
for (CYKeyMap::const_iterator key(keys.begin()); key != keys.end(); ++key) {
- std::string value(key->second);
- for (size_t i(0), e(value.size()); i != e; ++i)
- if (value[i] <= 0 || value[i] >= 0x7f || value[i] == '\n')
+ std::string code(key->second.code_);
+ for (size_t i(0), e(code.size()); i != e; ++i)
+ if (code[i] <= 0 || code[i] >= 0x7f || code[i] == '\n')
goto skip;
- std::cout << key->first << "|\"" << value << "\"" << std::endl;
+ std::cout << key->first << "|" << key->second.flags_ << "\"" << code << "\"" << std::endl;
skip:; }
clang_disposeTranslationUnit(unit);