-/* 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 {{{ */
parse:
switch (next) {
case '?': type = new(pool) Unknown(); break;
+
+#ifdef CY_OBJECTIVEC
case '#': type = new(pool) Meta(); break;
+#endif
case '(':
type = new(pool) Aggregate(true);
goto aggregate;
case '*': type = new(pool) String(); break;
+
+#ifdef CY_OBJECTIVEC
case ':': type = new(pool) Selector(); break;
case '@': {
name = NULL;
else {
const char *quote = strchr(*encoding + 1, '"');
- if (quote == NULL) {
- printf("unterminated specific id type {%s}\n", *encoding - 10);
- _assert(false);
- } else if (!named || quote[1] == eos || quote[1] == '"') {
+ if (quote == NULL)
+ CYThrow("unterminated specific id type {%s}", *encoding - 10);
+ else if (!named || quote[1] == eos || quote[1] == '"') {
name = pool.strmemdup(*encoding + 1, quote - *encoding - 1);
*encoding = quote + 1;
} else {
}
} break;
+#endif
case 'B': type = new(pool) Primitive<bool>(); break;
case 'C': type = new(pool) Primitive<unsigned char>(); break;
case '[': {
size_t size(strtoul(*encoding, (char **) encoding, 10));
type = new(pool) Array(*Parse_(pool, encoding, eos, false, callback), size);
- if (**encoding != ']') {
- printf("']' != \"%s\"\n", *encoding);
- _assert(false);
- }
+ if (**encoding != ']')
+ CYThrow("']' != \"%s\"", *encoding);
++*encoding;
} break;
_assert(false); // XXX: why is this here?!?
else {
type = Parse_(pool, encoding, eos, named, callback);
+#ifdef CY_OBJECTIVEC
Aggregate *aggregate(dynamic_cast<Aggregate *>(type));
if (aggregate != NULL && strcmp(aggregate->name, "_objc_class") == 0)
type = new(pool) Meta();
else
+#endif
type = new(pool) Pointer(*type);
}
break;
case 's': type = new(pool) Primitive<short>(); break;
case 'v': type = new(pool) Void(); break;
+#ifdef __SIZEOF_INT128__
+ case 't': type = new(pool) Primitive<signed __int128>(); break;
+ case 'T': type = new(pool) Primitive<unsigned __int128>(); break;
+#endif
+
case '{':
type = new(pool) Aggregate(false);
next = '}';
char end = next;
const char *begin = *encoding;
- do next = *(*encoding)++;
- while (
- next != '=' &&
- next != '}'
- );
+ do switch (next = *(*encoding)++) {
+ case '\0':
+ _assert(false);
+ case '}':
+ // XXX: this is actually a type reference
+ aggregate->signature.count = _not(size_t);
+ next = '='; // this is a "break". I'm sorry
+ } while (next != '=');
+
size_t length = *encoding - begin - 1;
if (strncmp(begin, "?", length) != 0)
aggregate->name = (char *) pool.strmemdup(begin, length);
- if (next == '=')
+ if (aggregate->signature.count == _not(size_t))
+ aggregate->signature.elements = NULL;
+ else
Parse_(pool, &aggregate->signature, encoding, end, callback);
// XXX: this is a hack to support trivial unions
type = (*callback)(pool, aggregate);
} break;
- case 'N': flags |= JOC_TYPE_INOUT; goto next;
+ case 'r': flags |= JOC_TYPE_CONST; goto next;
+
case 'n': flags |= JOC_TYPE_IN; goto next;
- case 'O': flags |= JOC_TYPE_BYCOPY; goto next;
+ case 'N': flags |= JOC_TYPE_INOUT; goto next;
case 'o': flags |= JOC_TYPE_OUT; goto next;
+ case 'O': flags |= JOC_TYPE_BYCOPY; goto next;
case 'R': flags |= JOC_TYPE_BYREF; goto next;
- case 'r': flags |= JOC_TYPE_CONST; goto next;
case 'V': flags |= JOC_TYPE_ONEWAY; goto next;
next:
break;
default:
- printf("invalid type character: '%c' {%s}\n", next, *encoding - 10);
- _assert(false);
+ CYThrow("invalid type character: '%c' {%s}", next, *encoding - 10);
}
type->flags = flags;
return "i";
}
+#ifdef __SIZEOF_INT128__
+template <>
+const char *Primitive<signed __int128>::Encode(CYPool &pool) const {
+ return "t";
+}
+#endif
+
template <>
const char *Primitive<signed long int>::Encode(CYPool &pool) const {
return "l";
return "I";
}
+#ifdef __SIZEOF_INT128__
+template <>
+const char *Primitive<unsigned __int128>::Encode(CYPool &pool) const {
+ return "T";
+}
+#endif
+
template <>
const char *Primitive<unsigned long int>::Encode(CYPool &pool) const {
return "L";
return "*";
}
+#ifdef CY_OBJECTIVEC
const char *Meta::Encode(CYPool &pool) const {
return "#";
}
const char *Selector::Encode(CYPool &pool) const {
return ":";
}
+#endif
const char *Bits::Encode(CYPool &pool) const {
return pool.strcat("b", pool.itoa(size), NULL);
return pool.strcat("[", pool.itoa(size), type.Encode(pool), "]", NULL);
}
+#ifdef CY_OBJECTIVEC
const char *Object::Encode(CYPool &pool) const {
return name == NULL ? "@" : pool.strcat("@\"", name, "\"", NULL);
}
+#endif
+
+const char *Enum::Encode(CYPool &pool) const {
+ return type.Encode(pool);
+}
const char *Aggregate::Encode(CYPool &pool) const {
- return pool.strcat(overlap ? "(" : "{", name == NULL ? "?" : name, "=", Unparse(pool, &signature), overlap ? ")" : "}", NULL);
+ bool reference(signature.count == _not(size_t));
+ return pool.strcat(overlap ? "(" : "{",
+ name == NULL ? "?" : name,
+ reference ? "" : "=",
+ reference ? "" : Unparse(pool, &signature),
+ overlap ? ")" : "}", NULL);
}
const char *Function::Encode(CYPool &pool) const {
return "?";
}
+#ifdef CY_OBJECTIVEC
const char *Block::Encode(CYPool &pool) const {
return "@?";
}
+#endif
const char *Unparse(CYPool &pool, const struct Type *type) {
const char *base(type->Encode(pool));