**/
/* }}} */
+#define __USE_EXTERN_INLINES
+
#include <dlfcn.h>
+#include <unistd.h>
#include <sys/stat.h>
+/* Cycript - Optimizing JavaScript Compiler/Runtime
+ * Copyright (C) 2009-2015 Jay Freeman (saurik)
+*/
+
+/* GNU Affero General Public License, Version 3 {{{ */
+/*
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+**/
+/* }}} */
+
#include <cstring>
#include <iostream>
#include <map>
#include <clang-c/Index.h>
+#include "Functor.hpp"
+#include "Replace.hpp"
+#include "Syntax.hpp"
+
+static CXChildVisitResult CYVisit(CXCursor cursor, CXCursor parent, CXClientData arg) {
+ (*reinterpret_cast<const Functor<void (CXCursor)> *>(arg))(cursor);
+ return CXChildVisit_Continue;
+}
+
+static unsigned CYForChild(CXCursor cursor, const Functor<void (CXCursor)> &visitor) {
+ return clang_visitChildren(cursor, &CYVisit, const_cast<void *>(static_cast<const void *>(&visitor)));
+}
+
+static bool CYOneChild(CXCursor cursor, const Functor<void (CXCursor)> &visitor) {
+ bool visited(false);
+ CYForChild(cursor, fun([&](CXCursor child) {
+ _assert(!visited);
+ visited = true;
+ visitor(child);
+ }));
+ return visited;
+}
+
struct CYCXString {
CXString value_;
{
}
+ CYCXString(CXCursor cursor) :
+ value_(clang_getCursorSpelling(cursor))
+ {
+ }
+
+ CYCXString(CXCursorKind kind) :
+ value_(clang_getCursorKindSpelling(kind))
+ {
+ }
+
+ CYCXString(CXTranslationUnit unit, CXToken token) :
+ value_(clang_getTokenSpelling(unit, token))
+ {
+ }
+
~CYCXString() {
clang_disposeString(value_);
}
operator const char *() const {
return clang_getCString(value_);
}
-};
-
-struct CYFieldBaton {
- std::ostringstream types;
- std::ostringstream names;
-};
-static CXChildVisitResult CYFieldVisit(CXCursor cursor, CXCursor parent, CXClientData arg) {
- CYFieldBaton &baton(*static_cast<CYFieldBaton *>(arg));
-
- if (clang_getCursorKind(cursor) == CXCursor_FieldDecl) {
- CXType type(clang_getCursorType(cursor));
- baton.types << "(typedef " << CYCXString(clang_getTypeSpelling(type)) << "),";
- baton.names << "'" << CYCXString(clang_getCursorSpelling(cursor)) << "',";
+ const char *Pool(CYPool &pool) const {
+ return pool.strdup(*this);
}
-
- return CXChildVisit_Continue;
-}
-
-struct CYAttributeBaton {
- std::string label;
};
-static CXChildVisitResult CYAttributeVisit(CXCursor cursor, CXCursor parent, CXClientData arg) {
- CYAttributeBaton &baton(*static_cast<CYAttributeBaton *>(arg));
-
- if (clang_getCursorKind(cursor) == CXCursor_AsmLabelAttr)
- baton.label = CYCXString(clang_getCursorSpelling(cursor));
-
- return CXChildVisit_Continue;
-}
-
typedef std::map<std::string, std::string> CYKeyMap;
struct CYChildBaton {
}
};
+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);
+}
+
static CXChildVisitResult CYChildVisit(CXCursor cursor, CXCursor parent, CXClientData arg) {
CYChildBaton &baton(*static_cast<CYChildBaton *>(arg));
CXTranslationUnit &unit(baton.unit);
- CYCXString spelling(clang_getCursorSpelling(cursor));
+ CYCXString spelling(cursor);
std::string name(spelling);
std::ostringstream value;
std::cout << spelling << " " << path << ":" << line << std::endl;
}*/
- switch (clang_getCursorKind(cursor)) {
+ switch (CXCursorKind kind = clang_getCursorKind(cursor)) {
case CXCursor_EnumConstantDecl: {
value << clang_getEnumConstantDeclValue(cursor);
} break;
clang_annotateTokens(unit, tokens, tokens.count, cursors);
for (unsigned i(1); i != tokens.count - 1; ++i) {
- CYCXString token(clang_getTokenSpelling(unit, tokens[i]));
+ CYCXString token(unit, tokens[i]);
if (i != 1)
value << " ";
else if (strcmp(token, "(") == 0)
if (spelling[0] == '\0')
goto skip;
- CYFieldBaton baton;
- clang_visitChildren(cursor, &CYFieldVisit, &baton);
+ std::ostringstream types;
+ std::ostringstream names;
+
+ CYForChild(cursor, fun([&](CXCursor child) {
+ if (clang_getCursorKind(child) == CXCursor_FieldDecl) {
+ CXType type(clang_getCursorType(child));
+ types << "(typedef " << CYCXString(clang_getTypeSpelling(type)) << "),";
+ names << "'" << CYCXString(child) << "',";
+ }
+ }));
name += "$cy";
- value << "new Type([" << baton.types.str() << "],[" << baton.names.str() << "])";
+ value << "new Type([" << types.str() << "],[" << names.str() << "])";
} break;
case CXCursor_TypedefDecl: {
} break;
case CXCursor_FunctionDecl:
- case CXCursor_VarDecl: {
- CYAttributeBaton baton;
- clang_visitChildren(cursor, &CYAttributeVisit, &baton);
-
- if (baton.label.empty()) {
- baton.label = spelling;
- baton.label = '_' + baton.label;
- } else if (baton.label[0] != '_')
+ case CXCursor_VarDecl: try {
+ std::string label;
+
+ CYList<CYFunctionParameter> parameters;
+ CYStatement *code(NULL);
+
+ CYLocalPool local;
+
+ CYForChild(cursor, fun([&](CXCursor child) {
+ switch (CXCursorKind kind = clang_getCursorKind(child)) {
+ case CXCursor_AsmLabelAttr:
+ label = CYCXString(child);
+ break;
+
+ case CXCursor_CompoundStmt:
+ code = CYTranslateBlock(unit, child);
+ break;
+
+ case CXCursor_ParmDecl:
+ parameters->*$P($B($I(CYCXString(child).Pool($pool))));
+ break;
+
+ case CXCursor_IntegerLiteral:
+ case CXCursor_ObjCClassRef:
+ case CXCursor_TypeRef:
+ case CXCursor_UnexposedAttr:
+ break;
+
+ default:
+ std::cerr << "A:" << CYCXString(child) << std::endl;
+ break;
+ }
+ }));
+
+ if (label.empty()) {
+ label = spelling;
+ label = '_' + label;
+ } else if (label[0] != '_')
goto skip;
- CXType type(clang_getCursorType(cursor));
- value << "*(typedef " << CYCXString(clang_getTypeSpelling(type)) << ").pointerTo()(dlsym(RTLD_DEFAULT,'" << baton.label.substr(1) << "'))";
+ if (code == NULL) {
+ CXType type(clang_getCursorType(cursor));
+ value << "*(typedef " << CYCXString(clang_getTypeSpelling(type)) << ").pointerTo()(dlsym(RTLD_DEFAULT,'" << label.substr(1) << "'))";
+ } else {
+ CYOptions options;
+ CYOutput out(*value.rdbuf(), options);
+ CYFunctionExpression *function($ CYFunctionExpression(NULL, parameters, code));
+ function->Output(out, CYNoBFC);
+ //std::cerr << value.str() << std::endl;
+ }
+ } catch (const CYException &error) {
+ CYPool pool;
+ //std::cerr << error.PoolCString(pool) << std::endl;
+ goto skip;
} break;
default: {
argv[--offset] = "-ObjC++";
#endif
- CXTranslationUnit unit(clang_parseTranslationUnit(index, file, argv + offset, argc - offset, NULL, 0, CXTranslationUnit_DetailedPreprocessingRecord | CXTranslationUnit_SkipFunctionBodies));
+ CXTranslationUnit unit(clang_parseTranslationUnit(index, file, argv + offset, argc - offset, NULL, 0, CXTranslationUnit_DetailedPreprocessingRecord));
for (unsigned i(0), e(clang_getNumDiagnostics(unit)); i != e; ++i) {
CXDiagnostic diagnostic(clang_getDiagnostic(unit, i));
--- /dev/null
+/* Cycript - Optimizing JavaScript Compiler/Runtime
+ * Copyright (C) 2009-2015 Jay Freeman (saurik)
+*/
+
+/* GNU Affero General Public License, Version 3 {{{ */
+/*
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+**/
+/* }}} */
+
+#include "Error.hpp"
+
+const char *CYPoolError::PoolCString(CYPool &pool) const {
+ return pool.strdup(message_);
+}
+
+CYPoolError::CYPoolError(const CYPoolError &rhs) :
+ message_(pool_.strdup(rhs.message_))
+{
+}
+
+CYPoolError::CYPoolError(const char *format, ...) {
+ va_list args;
+ va_start(args, format);
+ // XXX: there might be a beter way to think about this
+ message_ = pool_.vsprintf(64, format, args);
+ va_end(args);
+}
+
+CYPoolError::CYPoolError(const char *format, va_list args) {
+ // XXX: there might be a beter way to think about this
+ message_ = pool_.vsprintf(64, format, args);
+}
+
+_visible void CYThrow(const char *format, ...) {
+ va_list args;
+ va_start(args, format);
+ throw CYPoolError(format, args);
+ // XXX: does this matter? :(
+ va_end(args);
+}
_assert_("sqlcall", _value == 0 || _value >= 100 && _value < 200, #expr, " %u:%s", _value, sqlite3_errmsg(database_)); \
_value; })
+#ifdef CY_EXECUTE
struct CYJSException {
JSContextRef context_;
JSValueRef value_;
CYJSException _error(context); \
(code)(args, _error); \
})
+#endif
#endif/*CYCRIPT_ERROR_HPP*/
--- /dev/null
+/* Cycript - Optimizing JavaScript Compiler/Runtime
+ * Copyright (C) 2009-2015 Jay Freeman (saurik)
+*/
+
+/* GNU Affero General Public License, Version 3 {{{ */
+/*
+ * This program is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Affero General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Affero General Public License for more details.
+
+ * You should have received a copy of the GNU Affero General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+**/
+/* }}} */
+
+#ifndef FUNCTOR_HPP
+#define FUNCTOR_HPP
+
+template <typename Function_>
+class Functor;
+
+template <typename Type_, typename... Args_>
+class Functor<Type_ (Args_...)> {
+ public:
+ virtual Type_ operator ()(Args_... args) const = 0;
+};
+
+template <typename Function_>
+class FunctorImpl;
+
+template <typename Value_, typename Type_, typename... Args_>
+class FunctorImpl<Type_ (Value_::*)(Args_...) const> :
+ public Functor<Type_ (Args_...)>
+{
+ private:
+ const Value_ *value_;
+
+ public:
+ FunctorImpl(const Value_ &value) :
+ value_(&value)
+ {
+ }
+
+ virtual Type_ operator ()(Args_... args) const {
+ return (*value_)(args...);
+ }
+};
+
+template <typename Function_>
+FunctorImpl<decltype(&Function_::operator())> fun(const Function_ &value) {
+ return value;
+}
+
+#endif//FUNCTOR_HPP
#include <iostream>
#include <set>
#include <map>
-#include <iomanip>
#include <sstream>
-#include <cmath>
#include <dlfcn.h>
#include "String.hpp"
#include "Syntax.hpp"
-template <>
-::pthread_key_t CYLocal<CYPool>::key_ = Key_();
-
/* C Strings {{{ */
CYUTF8String CYPoolUTF8String(CYPool &pool, CYUTF16String utf16) {
// XXX: this is wrong
return false;
}
/* }}} */
-/* JavaScript *ify {{{ */
-void CYStringify(std::ostringstream &str, const char *data, size_t size, bool c) {
- bool single;
- if (c)
- single = false;
- else {
- unsigned quot(0), apos(0);
- for (const char *value(data), *end(data + size); value != end; ++value)
- if (*value == '"')
- ++quot;
- else if (*value == '\'')
- ++apos;
-
- single = quot > apos;
- }
-
- str << (single ? '\'' : '"');
-
- for (const char *value(data), *end(data + size); value != end; ++value)
- switch (uint8_t next = *value) {
- case '\\': str << "\\\\"; break;
- case '\b': str << "\\b"; break;
- case '\f': str << "\\f"; break;
- case '\n': str << "\\n"; break;
- case '\r': str << "\\r"; break;
- case '\t': str << "\\t"; break;
- case '\v': str << "\\v"; break;
-
- case '"':
- if (!single)
- str << "\\\"";
- else goto simple;
- break;
-
- case '\'':
- if (single)
- str << "\\'";
- else goto simple;
- break;
-
- case '\0':
- if (value[1] >= '0' && value[1] <= '9')
- str << "\\x00";
- else
- str << "\\0";
- break;
-
- default:
- if (next >= 0x20 && next < 0x7f) simple:
- str << *value;
- else {
- unsigned levels(1);
- if ((next & 0x80) != 0)
- while ((next & 0x80 >> ++levels) != 0);
-
- unsigned point(next & 0xff >> levels);
- while (--levels != 0)
- point = point << 6 | uint8_t(*++value) & 0x3f;
-
- if (point < 0x100)
- str << "\\x" << std::setbase(16) << std::setw(2) << std::setfill('0') << point;
- else if (point < 0x10000)
- str << "\\u" << std::setbase(16) << std::setw(4) << std::setfill('0') << point;
- else {
- point -= 0x10000;
- str << "\\u" << std::setbase(16) << std::setw(4) << std::setfill('0') << (0xd800 | point >> 0x0a);
- str << "\\u" << std::setbase(16) << std::setw(4) << std::setfill('0') << (0xdc00 | point & 0x3ff);
- }
- }
- }
-
- str << (single ? '\'' : '"');
-}
-
-void CYNumerify(std::ostringstream &str, double value) {
- if (std::isinf(value)) {
- if (value < 0)
- str << '-';
- str << "Infinity";
- return;
- }
-
- char string[32];
- // XXX: I want this to print 1e3 rather than 1000
- sprintf(string, "%.17g", value);
- str << string;
-}
bool CYIsKey(CYUTF8String value) {
const char *data(value.data);
return true;
}
-/* }}} */
-
-double CYCastDouble(const char *value, size_t size) {
- char *end;
- double number(strtod(value, &end));
- if (end != value + size)
- return NAN;
- return number;
-}
-
-double CYCastDouble(const char *value) {
- return CYCastDouble(value, strlen(value));
-}
_visible bool CYStartsWith(const CYUTF8String &haystack, const CYUTF8String &needle) {
return haystack.size >= needle.size && strncmp(haystack.data, needle.data, needle.size) == 0;
static CYPool pool;
return pool;
}
-
-_visible void CYThrow(const char *format, ...) {
- va_list args;
- va_start(args, format);
- throw CYPoolError(format, args);
- // XXX: does this matter? :(
- va_end(args);
-}
-
-const char *CYPoolError::PoolCString(CYPool &pool) const {
- return pool.strdup(message_);
-}
-
-CYPoolError::CYPoolError(const CYPoolError &rhs) :
- message_(pool_.strdup(rhs.message_))
-{
-}
-
-CYPoolError::CYPoolError(const char *format, ...) {
- va_list args;
- va_start(args, format);
- // XXX: there might be a beter way to think about this
- message_ = pool_.vsprintf(64, format, args);
- va_end(args);
-}
-
-CYPoolError::CYPoolError(const char *format, va_list args) {
- // XXX: there might be a beter way to think about this
- message_ = pool_.vsprintf(64, format, args);
-}
libcycript_la_LDFLAGS = $(CY_LDFLAGS)
libcycript_la_LIBADD = $(LTLIBUV) $(LTLIBFFI) $(LTLIBSQLITE3) $(LTLIBGCC) -ldl
-libcycript_la_SOURCES = ConvertUTF.c Decode.cpp Driver.cpp Highlight.cpp Library.cpp Network.cpp Output.cpp Replace.cpp Syntax.cpp
+libcycript_la_SOURCES = ConvertUTF.c Decode.cpp Driver.cpp Error.cpp Highlight.cpp Library.cpp Network.cpp Output.cpp Replace.cpp Syntax.cpp
libcycript_la_SOURCES += Parser.cpp Scanner.cpp
filters =
if CY_PRELINK
CLEANFILES += Analyze
-Analyze: Analyze.cpp
- $(CXX_FOR_BUILD) $(CXXFLAGS_FOR_BUILD) $(LDFLAGS_FOR_BUILD) -DCY_OBJECTIVEC=$(CY_OBJECTIVEC) -I$(srcdir)/extra -o $@ $< $(CY_LIBCLANG)
+Analyze: Analyze.cpp Error.cpp Output.cpp Replace.cpp Syntax.cpp
+ $(CXX_FOR_BUILD) $(CXXFLAGS_FOR_BUILD) -std=c++11 $(LDFLAGS_FOR_BUILD) -DCY_OBJECTIVEC=$(CY_OBJECTIVEC) -I$(srcdir)/extra -o $@ $^ $(CY_LIBCLANG) -Wno-bitwise-op-parentheses -Wno-dangling-else -Wno-logical-op-parentheses
CLEANFILES += Bridge.def
Bridge.def: Analysis.cpp Analyze
$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_2) \
$(am__DEPENDENCIES_3) $(am__DEPENDENCIES_4)
am__libcycript_la_SOURCES_DIST = ConvertUTF.c Decode.cpp Driver.cpp \
- Highlight.cpp Library.cpp Network.cpp Output.cpp Replace.cpp \
- Syntax.cpp Parser.cpp Scanner.cpp Complete.cpp \
+ Error.cpp Highlight.cpp Library.cpp Network.cpp Output.cpp \
+ Replace.cpp Syntax.cpp Parser.cpp Scanner.cpp Complete.cpp \
sig/ffi_type.cpp sig/parse.cpp sig/copy.cpp Execute.cpp \
JavaScriptCore.cpp Java/Execute.cpp ObjectiveC/Output.cpp \
ObjectiveC/Replace.cpp ObjectiveC/Library.mm Handler.cpp
@CY_OBJECTIVEC_TRUE@ ObjectiveC/Replace.lo \
@CY_OBJECTIVEC_TRUE@ ObjectiveC/Library.lo
@CY_ATTACH_TRUE@am__objects_5 = Handler.lo
-am_libcycript_la_OBJECTS = ConvertUTF.lo Decode.lo Driver.lo \
+am_libcycript_la_OBJECTS = ConvertUTF.lo Decode.lo Driver.lo Error.lo \
Highlight.lo Library.lo Network.lo Output.lo Replace.lo \
Syntax.lo Parser.lo Scanner.lo $(am__objects_1) \
$(am__objects_2) $(am__objects_3) $(am__objects_4) \
libcycript_la_LIBADD = $(LTLIBUV) $(LTLIBFFI) $(LTLIBSQLITE3) \
$(LTLIBGCC) -ldl $(am__append_3) $(am__append_12) \
$(am__append_15)
-libcycript_la_SOURCES = ConvertUTF.c Decode.cpp Driver.cpp \
+libcycript_la_SOURCES = ConvertUTF.c Decode.cpp Driver.cpp Error.cpp \
Highlight.cpp Library.cpp Network.cpp Output.cpp Replace.cpp \
Syntax.cpp Parser.cpp Scanner.cpp $(am__append_1) \
$(am__append_2) $(am__append_11) $(am__append_14) \
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ConvertUTF.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Decode.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Driver.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Error.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Execute.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Handler.Plo@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/Highlight.Plo@am__quote@
.DELETE_ON_ERROR:
@CY_EXECUTE_TRUE@libcycript.db: Bridge.def libcycript.sh
@CY_EXECUTE_TRUE@ $(srcdir)/libcycript.sh $(CY_SYSTEM) $@ $<
-@CY_EXECUTE_TRUE@@CY_PRELINK_TRUE@Analyze: Analyze.cpp
-@CY_EXECUTE_TRUE@@CY_PRELINK_TRUE@ $(CXX_FOR_BUILD) $(CXXFLAGS_FOR_BUILD) $(LDFLAGS_FOR_BUILD) -DCY_OBJECTIVEC=$(CY_OBJECTIVEC) -I$(srcdir)/extra -o $@ $< $(CY_LIBCLANG)
+@CY_EXECUTE_TRUE@@CY_PRELINK_TRUE@Analyze: Analyze.cpp Error.cpp Output.cpp Replace.cpp Syntax.cpp
+@CY_EXECUTE_TRUE@@CY_PRELINK_TRUE@ $(CXX_FOR_BUILD) $(CXXFLAGS_FOR_BUILD) -std=c++11 $(LDFLAGS_FOR_BUILD) -DCY_OBJECTIVEC=$(CY_OBJECTIVEC) -I$(srcdir)/extra -o $@ $^ $(CY_LIBCLANG) -Wno-bitwise-op-parentheses -Wno-dangling-else -Wno-logical-op-parentheses
@CY_EXECUTE_TRUE@@CY_PRELINK_TRUE@Bridge.def: Analysis.cpp Analyze
@CY_EXECUTE_TRUE@@CY_PRELINK_TRUE@ ./Analyze $< $(OBJCXX) $(AM_OBJCXXFLAGS) $(OBJCXXFLAGS) >$@
@CY_EXECUTE_TRUE@@CY_PRELINK_FALSE@Bridge.def: Bridge.def.in
**/
/* }}} */
-#include "cycript.hpp"
-
+#include <cmath>
+#include <iomanip>
#include <sstream>
#include "Syntax.hpp"
+void CYStringify(std::ostringstream &str, const char *data, size_t size, bool c) {
+ bool single;
+ if (c)
+ single = false;
+ else {
+ unsigned quot(0), apos(0);
+ for (const char *value(data), *end(data + size); value != end; ++value)
+ if (*value == '"')
+ ++quot;
+ else if (*value == '\'')
+ ++apos;
+
+ single = quot > apos;
+ }
+
+ str << (single ? '\'' : '"');
+
+ for (const char *value(data), *end(data + size); value != end; ++value)
+ switch (uint8_t next = *value) {
+ case '\\': str << "\\\\"; break;
+ case '\b': str << "\\b"; break;
+ case '\f': str << "\\f"; break;
+ case '\n': str << "\\n"; break;
+ case '\r': str << "\\r"; break;
+ case '\t': str << "\\t"; break;
+ case '\v': str << "\\v"; break;
+
+ case '"':
+ if (!single)
+ str << "\\\"";
+ else goto simple;
+ break;
+
+ case '\'':
+ if (single)
+ str << "\\'";
+ else goto simple;
+ break;
+
+ case '\0':
+ if (value[1] >= '0' && value[1] <= '9')
+ str << "\\x00";
+ else
+ str << "\\0";
+ break;
+
+ default:
+ if (next >= 0x20 && next < 0x7f) simple:
+ str << *value;
+ else {
+ unsigned levels(1);
+ if ((next & 0x80) != 0)
+ while ((next & 0x80 >> ++levels) != 0);
+
+ unsigned point(next & 0xff >> levels);
+ while (--levels != 0)
+ point = point << 6 | uint8_t(*++value) & 0x3f;
+
+ if (point < 0x100)
+ str << "\\x" << std::setbase(16) << std::setw(2) << std::setfill('0') << point;
+ else if (point < 0x10000)
+ str << "\\u" << std::setbase(16) << std::setw(4) << std::setfill('0') << point;
+ else {
+ point -= 0x10000;
+ str << "\\u" << std::setbase(16) << std::setw(4) << std::setfill('0') << (0xd800 | point >> 0x0a);
+ str << "\\u" << std::setbase(16) << std::setw(4) << std::setfill('0') << (0xdc00 | point & 0x3ff);
+ }
+ }
+ }
+
+ str << (single ? '\'' : '"');
+}
+
+void CYNumerify(std::ostringstream &str, double value) {
+ if (std::isinf(value)) {
+ if (value < 0)
+ str << '-';
+ str << "Infinity";
+ return;
+ }
+
+ char string[32];
+ // XXX: I want this to print 1e3 rather than 1000
+ sprintf(string, "%.17g", value);
+ str << string;
+}
+
void CYOutput::Terminate() {
operator ()(';');
mode_ = NoMode;
**/
/* }}} */
+#include <cmath>
+#include <sstream>
+
#include "Syntax.hpp"
+double CYCastDouble(const char *value, size_t size) {
+ char *end;
+ double number(strtod(value, &end));
+ if (end != value + size)
+ return NAN;
+ return number;
+}
+
+double CYCastDouble(const char *value) {
+ return CYCastDouble(value, strlen(value));
+}
+
+template <>
+::pthread_key_t CYLocal<CYPool>::key_ = Key_();
+
CYRange DigitRange_ (0x3ff000000000000LLU, 0x000000000000000LLU); // 0-9
CYRange WordStartRange_(0x000001000000000LLU, 0x7fffffe87fffffeLLU); // A-Za-z_$
CYRange WordEndRange_ (0x3ff001000000000LLU, 0x7fffffe87fffffeLLU); // A-Za-z_$0-9
#include "Location.hpp"
#include "Options.hpp"
#include "Pooling.hpp"
+#include "String.hpp"
+
+double CYCastDouble(const char *value, size_t size);
+double CYCastDouble(const char *value);
+
+void CYNumerify(std::ostringstream &str, double value);
+void CYStringify(std::ostringstream &str, const char *data, size_t size, bool c = false);
struct CYContext;
bool CYRecvAll_(int socket, uint8_t *data, size_t size);
bool CYSendAll_(int socket, const uint8_t *data, size_t size);
-void CYNumerify(std::ostringstream &str, double value);
-void CYStringify(std::ostringstream &str, const char *data, size_t size, bool c = false);
-
double CYCastDouble(const char *value, size_t size);
double CYCastDouble(const char *value);
char **CYComplete(const char *word, const std::string &line, CYUTF8String (*run)(CYPool &pool, const std::string &));
+void CYStringify(std::ostringstream &str, const char *data, size_t size, bool c);
+
#endif/*CYCRIPT_HPP*/
});
};
-const F_OK = 0;
const X_OK = (1<<0);
const W_OK = (1<<1);
const R_OK = (1<<2);
-typedef long size_t;
-
-extern "C" int access(const char *path, int amode);
-extern "C" char *getcwd(char *buf, size_t size);
-extern "C" int getpid();
-
$cy_set(Date.prototype, {
toCYON: function() {
return `new ${this.constructor.name}(${this.toUTCString().toCYON()})`;