@begin C
"typedef" L C I(identifier, Identifier("typedef"), tk::Typedef, hi::Meta);
+"unsigned" L C I(identifier, Identifier("unsigned"), tk::Unsigned, hi::Meta);
+"signed" L C I(identifier, Identifier("signed"), tk::Signed, hi::Meta);
@end
@begin ObjectiveC
CYProperty *property_;
CYPropertyName *propertyName_;
CYRubyProc *rubyProc_;
+ CYTypeSpecifier *specifier_;
CYStatement *statement_;
CYString *string_;
CYThis *this_;
@begin C
%token <identifier_> Typedef "typedef"
+%token <identifier_> Unsigned "unsigned"
+%token <identifier_> Signed "signed"
@end
@begin ObjectiveC
%type <expression_> FunctionExpression
%type <identifier_> Identifier
%type <identifier_> IdentifierOpt
+%type <identifier_> IdentifierType
%type <word_> IdentifierName
%type <statement_> IfStatement
%type <expression_> Initialiser
%type <protocol_> ClassProtocolsOpt
%type <expression_> EncodedType
%type <modifier_> FunctionedType
+%type <specifier_> IntegerType
+%type <specifier_> IntegerTypeOpt
%type <expression_> MessageExpression
%type <messageParameter_> MessageParameter
%type <messageParameter_> MessageParameters
%type <typedIdentifier_> ModifiedType
%type <module_> Module
%type <typedIdentifier_> PrefixedType
-%type <expression_> PrimitiveType
+%type <specifier_> PrimitiveType
%type <argument_> SelectorCall_
%type <argument_> SelectorCall
%type <selector_> SelectorExpression_
| { $$ = NULL; }
;
-Identifier
+IdentifierType
: Identifier_ { $$ = $1; }
-@begin C
- | "typedef" { $$ = $1; }
- | "YES" { $$ = $1; }
- | "NO" { $$ = $1; }
-@end
-
| "implements" { $$ = $1; }
| "interface" { $$ = $1; }
| "package" { $$ = $1; }
| "abstract" { $$ = $1; }
| "boolean" { $$ = $1; }
| "byte" { $$ = $1; }
- | "char" { $$ = $1; }
| "double" { $$ = $1; }
| "final" { $$ = $1; }
| "float" { $$ = $1; }
| "goto" { $$ = $1; }
- | "int" { $$ = $1; }
- | "long" { $$ = $1; }
| "native" { $$ = $1; }
- | "short" { $$ = $1; }
| "synchronized" { $$ = $1; }
| "throws" { $$ = $1; }
| "transient" { $$ = $1; }
- | "volatile" { $$ = $1; }
// XXX: currently I only have this as Word
// | "let" { $$ = $1; }
| "of" { $$ = $1; }
;
+Identifier
+ : IdentifierType
+ | "char" { $$ = $1; }
+ | "int" { $$ = $1; }
+ | "long" { $$ = $1; }
+ | "short" { $$ = $1; }
+ | "volatile" { $$ = $1; }
+@begin C
+ | "typedef" { $$ = $1; }
+ | "unsigned" { $$ = $1; }
+ | "signed" { $$ = $1; }
+ | "YES" { $$ = $1; }
+ | "NO" { $$ = $1; }
+@end
+ ;
+
IdentifierOpt
: Identifier { $$ = $1; }
| { $$ = NULL; }
;
TypeSignifier
- : Identifier { $$ = CYNew CYTypedIdentifier($1); }
+ : IdentifierType { $$ = CYNew CYTypedIdentifier($1); }
| TypeParenthetical { $$ = $1; }
;
;
TypeQualifierLeft
- : "const" TypeQualifierLeft { $$ = $2; CYSetLast($$) = CYNew CYTypeConstant(); }
- /* XXX: | "volatile" TypeQualifierLeft { $$ = $2; CYSetLast($$) = CYNew CYTypeVolatile(); } */
- | { $$ = NULL; }
+ : { $$ = NULL; }
+ | "const" TypeQualifierLeft { $$ = $2; CYSetLast($$) = CYNew CYTypeConstant(); }
+ | "volatile" TypeQualifierLeft { $$ = $2; CYSetLast($$) = CYNew CYTypeVolatile(); }
;
TypeQualifierRight
- : "const" TypeQualifierRight { $$ = $2; $$->modifier_ = CYNew CYTypeConstant($$->modifier_); }
- | PrefixedType { $$ = $1; }
+ : PrefixedType { $$ = $1; }
| SuffixedType { $$ = $1; }
+ | "const" TypeQualifierRight { $$ = $2; $$->modifier_ = CYNew CYTypeConstant($$->modifier_); }
+ | "volatile" TypeQualifierRight { $$ = $2; $$->modifier_ = CYNew CYTypeVolatile($$->modifier_); }
+ ;
+
+IntegerType
+ : "int" { $$ = CYNew CYTypeVariable("int"); }
+ | "unsigned" IntegerTypeOpt { $$ = CYNew CYTypeUnsigned($2); }
+ | "signed" IntegerTypeOpt { $$ = CYNew CYTypeSigned($2); }
+ | "long" IntegerTypeOpt { $$ = CYNew CYTypeLong($2); }
+ | "short" IntegerTypeOpt { $$ = CYNew CYTypeShort($2); }
+ ;
+
+IntegerTypeOpt
+ : IntegerType { $$ = $1; }
+ |
;
PrimitiveType
- : Variable { $$ = $1; }
- | "void" { $$ = CYNew cy::Syntax::New(CYNew CYVariable(CYNew CYIdentifier("Type")), CYNew CYArgument(CYNew CYString("v"))); }
+ : IdentifierType { $$ = CYNew CYTypeVariable($1); }
+ | IntegerType { $$ = $1; }
+ | "void" { $$ = CYNew CYTypeVoid(); }
+ | "char" { $$ = CYNew CYTypeVariable("char"); }
+ | "signed" "char" { $$ = CYNew CYTypeSigned(CYNew CYTypeVariable("char")); }
+ | "unsigned" "char" { $$ = CYNew CYTypeUnsigned(CYNew CYTypeVariable("char")); }
;
TypedIdentifier
- : TypeQualifierLeft PrimitiveType TypeQualifierRight { $$ = $3; $$->type_ = $2; CYSetLast($1) = $$->modifier_; $$->modifier_ = $1; }
+ : TypeQualifierLeft PrimitiveType TypeQualifierRight { $$ = $3; $$->specifier_ = $2; CYSetLast($1) = $$->modifier_; $$->modifier_ = $1; }
;
EncodedType
/* }}} */
/* Cycript (Objective-C): Block Expressions {{{ */
ModifiedType
- : TypeQualifierLeft PrimitiveType { $$ = CYNew CYTypedIdentifier(); $$->type_ = $2; $$->modifier_ = $1; }
+ : TypeQualifierLeft PrimitiveType { $$ = CYNew CYTypedIdentifier(); $$->specifier_ = $2; $$->modifier_ = $1; }
| ModifiedType "*" { $$ = $1; $$->modifier_ = CYNew CYTypePointerTo($$->modifier_); }
;
return Decode(pool, type->data.signature.elements[0].type)->Modify($ CYTypeFunctionWith(parameter));
} break;
- case sig::typename_P: return $ CYTypedIdentifier($V("Class"));
+ case sig::typename_P: return $ CYTypedIdentifier($ CYTypeVariable("Class"));
case sig::union_P: _assert(false); break;
- case sig::string_P: return $ CYTypedIdentifier($V("char"), $ CYTypePointerTo());
- case sig::selector_P: return $ CYTypedIdentifier($V("SEL"));
+ case sig::string_P: return $ CYTypedIdentifier($ CYTypeVariable("char"), $ CYTypePointerTo());
+ case sig::selector_P: return $ CYTypedIdentifier($ CYTypeVariable("SEL"));
case sig::block_P: {
_assert(type->data.signature.count != 0);
case sig::object_P: {
if (type->name == NULL)
- return $ CYTypedIdentifier($V("id"));
+ return $ CYTypedIdentifier($ CYTypeVariable("id"));
else
- return $ CYTypedIdentifier($V(type->name), $ CYTypePointerTo());
+ return $ CYTypedIdentifier($ CYTypeVariable(type->name), $ CYTypePointerTo());
} break;
- case sig::boolean_P: return $ CYTypedIdentifier($V("bool"));
- case sig::uchar_P: return $ CYTypedIdentifier($V("uchar"));
- case sig::uint_P: return $ CYTypedIdentifier($V("uint"));
- case sig::ulong_P: return $ CYTypedIdentifier($V("ulong"));
- case sig::ulonglong_P: return $ CYTypedIdentifier($V("ulonglong"));
- case sig::ushort_P: return $ CYTypedIdentifier($V("ushort"));
+ case sig::boolean_P: return $ CYTypedIdentifier($ CYTypeVariable("bool"));
+ case sig::uchar_P: return $ CYTypedIdentifier($ CYTypeUnsigned($ CYTypeVariable("char")));
+ case sig::uint_P: return $ CYTypedIdentifier($ CYTypeUnsigned($ CYTypeVariable("int")));
+ case sig::ulong_P: return $ CYTypedIdentifier($ CYTypeUnsigned($ CYTypeLong($ CYTypeVariable("int"))));
+ case sig::ulonglong_P: return $ CYTypedIdentifier($ CYTypeUnsigned($ CYTypeLong($ CYTypeLong($ CYTypeVariable("int")))));
+ case sig::ushort_P: return $ CYTypedIdentifier($ CYTypeUnsigned($ CYTypeShort($ CYTypeVariable("int"))));
case sig::array_P: return Decode(pool, type->data.data.type)->Modify($ CYTypeArrayOf($D(type->data.data.size)));
- // XXX: once again, the issue of void here is incorrect
case sig::pointer_P: {
CYTypedIdentifier *typed;
if (type->data.data.type == NULL)
- typed = $ CYTypedIdentifier($V("void"));
+ typed = $ CYTypedIdentifier($ CYTypeVoid());
else
typed = Decode(pool, type->data.data.type);
return typed->Modify($ CYTypePointerTo());
} break;
case sig::bit_P: _assert(false); break;
- case sig::char_P: return $ CYTypedIdentifier($V("char"));
- case sig::double_P: return $ CYTypedIdentifier($V("double"));
- case sig::float_P: return $ CYTypedIdentifier($V("float"));
- case sig::int_P: return $ CYTypedIdentifier($V("int"));
- case sig::long_P: return $ CYTypedIdentifier($V("long"));
- case sig::longlong_P: return $ CYTypedIdentifier($V("longlong"));
- case sig::short_P: return $ CYTypedIdentifier($V("short"));
+ case sig::char_P: return $ CYTypedIdentifier($ CYTypeVariable("char"));
+ case sig::double_P: return $ CYTypedIdentifier($ CYTypeVariable("double"));
+ case sig::float_P: return $ CYTypedIdentifier($ CYTypeVariable("float"));
+ case sig::int_P: return $ CYTypedIdentifier($ CYTypeVariable("int"));
+ case sig::long_P: return $ CYTypedIdentifier($ CYTypeLong($ CYTypeVariable("int")));
+ case sig::longlong_P: return $ CYTypedIdentifier($ CYTypeLong($ CYTypeLong($ CYTypeVariable("int"))));
+ case sig::short_P: return $ CYTypedIdentifier($ CYTypeShort($ CYTypeVariable("int")));
- // XXX: this happens to work, but is totally wrong
- case sig::void_P: return $ CYTypedIdentifier($V("void"));
+ case sig::void_P: return $ CYTypedIdentifier($ CYTypeVoid());
case sig::struct_P: {
_assert(type->name != NULL);
- return $ CYTypedIdentifier($V(type->name));
+ return $ CYTypedIdentifier($ CYTypeVariable(type->name));
} break;
}
return CYMakeType(context, &type);
} CYCatch(NULL) }
+static JSValueRef Type_callAsFunction_long(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
+ if (count != 0)
+ throw CYJSError(context, "incorrect number of arguments to Type.long");
+ Type_privateData *internal(reinterpret_cast<Type_privateData *>(JSObjectGetPrivate(_this)));
+
+ sig::Type type(*internal->type_);
+
+ switch (type.primitive) {
+ case sig::short_P: type.primitive = sig::int_P; break;
+ case sig::int_P: type.primitive = sig::long_P; break;
+ case sig::long_P: type.primitive = sig::longlong_P; break;
+ default: throw CYJSError(context, "invalid type argument to Type.long");
+ }
+
+ return CYMakeType(context, &type);
+} CYCatch(NULL) }
+
+static JSValueRef Type_callAsFunction_short(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
+ if (count != 0)
+ throw CYJSError(context, "incorrect number of arguments to Type.short");
+ Type_privateData *internal(reinterpret_cast<Type_privateData *>(JSObjectGetPrivate(_this)));
+
+ sig::Type type(*internal->type_);
+
+ switch (type.primitive) {
+ case sig::int_P: type.primitive = sig::short_P; break;
+ case sig::long_P: type.primitive = sig::int_P; break;
+ case sig::longlong_P: type.primitive = sig::long_P; break;
+ default: throw CYJSError(context, "invalid type argument to Type.short");
+ }
+
+ return CYMakeType(context, &type);
+} CYCatch(NULL) }
+
+static JSValueRef Type_callAsFunction_signed(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
+ if (count != 0)
+ throw CYJSError(context, "incorrect number of arguments to Type.signed");
+ Type_privateData *internal(reinterpret_cast<Type_privateData *>(JSObjectGetPrivate(_this)));
+
+ sig::Type type(*internal->type_);
+
+ switch (type.primitive) {
+ case sig::char_P: case sig::uchar_P: type.primitive = sig::char_P; break;
+ case sig::short_P: case sig::ushort_P: type.primitive = sig::short_P; break;
+ case sig::int_P: case sig::uint_P: type.primitive = sig::int_P; break;
+ case sig::long_P: case sig::ulong_P: type.primitive = sig::long_P; break;
+ case sig::longlong_P: case sig::ulonglong_P: type.primitive = sig::longlong_P; break;
+ default: throw CYJSError(context, "invalid type argument to Type.signed");
+ }
+
+ return CYMakeType(context, &type);
+} CYCatch(NULL) }
+
+static JSValueRef Type_callAsFunction_unsigned(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) { CYTry {
+ if (count != 0)
+ throw CYJSError(context, "incorrect number of arguments to Type.unsigned");
+ Type_privateData *internal(reinterpret_cast<Type_privateData *>(JSObjectGetPrivate(_this)));
+
+ sig::Type type(*internal->type_);
+
+ switch (type.primitive) {
+ case sig::char_P: case sig::uchar_P: type.primitive = sig::uchar_P; break;
+ case sig::short_P: case sig::ushort_P: type.primitive = sig::ushort_P; break;
+ case sig::int_P: case sig::uint_P: type.primitive = sig::uint_P; break;
+ case sig::long_P: case sig::ulong_P: type.primitive = sig::ulong_P; break;
+ case sig::longlong_P: case sig::ulonglong_P: type.primitive = sig::ulonglong_P; break;
+ default: throw CYJSError(context, "invalid type argument to Type.unsigned");
+ }
+
+ return CYMakeType(context, &type);
+} CYCatch(NULL) }
+
static JSValueRef Type_callAsFunction_functionWith(JSContextRef context, JSObjectRef object, JSObjectRef _this, size_t count, const JSValueRef arguments[], JSValueRef *exception) {
return Type_callAsFunction_$With(context, object, _this, count, arguments, sig::function_P, exception);
}
{NULL, NULL, NULL, 0}
};
-static JSStaticFunction Type_staticFunctions[10] = {
+static JSStaticFunction Type_staticFunctions[14] = {
{"arrayOf", &Type_callAsFunction_arrayOf, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{"blockWith", &Type_callAsFunction_blockWith, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{"constant", &Type_callAsFunction_constant, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{"functionWith", &Type_callAsFunction_functionWith, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
+ {"long", &Type_callAsFunction_long, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{"pointerTo", &Type_callAsFunction_pointerTo, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
+ {"short", &Type_callAsFunction_short, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
+ {"signed", &Type_callAsFunction_signed, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{"withName", &Type_callAsFunction_withName, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{"toCYON", &Type_callAsFunction_toCYON, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{"toJSON", &Type_callAsFunction_toJSON, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{"toString", &Type_callAsFunction_toString, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
+ {"unsigned", &Type_callAsFunction_unsigned, kJSPropertyAttributeDontEnum | kJSPropertyAttributeDontDelete},
{NULL, NULL, 0}
};
}
void CYTypedIdentifier::Output(CYOutput &out) const {
- type_->Output(out, 0, CYNoFlags);
+ specifier_->Output(out);
modifier_->Output(out, 0, identifier_);
}
} }
+void CYTypeLong::Output(CYOutput &out) const {
+ out << "long" << specifier_;
+}
+
+void CYTypeShort::Output(CYOutput &out) const {
+ out << "short" << specifier_;
+}
+
+void CYTypeSigned::Output(CYOutput &out) const {
+ out << "signed" << specifier_;
+}
+
+void CYTypeUnsigned::Output(CYOutput &out) const {
+ out << "unsigned" << specifier_;
+}
+
+void CYTypeVariable::Output(CYOutput &out) const {
+ out << *name_;
+}
+
+void CYTypeVoid::Output(CYOutput &out) const {
+ out << "void";
+}
+
void CYVar::Output(CYOutput &out, CYFlags flags) const {
out << "var";
declarations_->Output(out, flags);
virtual void Output(CYOutput &out) const;
};
+struct CYTypeSpecifier :
+ CYThing
+{
+ virtual CYExpression *Replace(CYContext &context) = 0;
+};
+
+struct CYTypeVoid :
+ CYTypeSpecifier
+{
+ CYTypeVoid() {
+ }
+
+ virtual CYExpression *Replace(CYContext &context);
+ virtual void Output(CYOutput &out) const;
+};
+
+struct CYTypeVariable :
+ CYTypeSpecifier
+{
+ CYIdentifier *name_;
+
+ CYTypeVariable(CYIdentifier *name) :
+ name_(name)
+ {
+ }
+
+ CYTypeVariable(const char *name) :
+ name_(new($pool) CYIdentifier(name))
+ {
+ }
+
+ virtual CYExpression *Replace(CYContext &context);
+ virtual void Output(CYOutput &out) const;
+};
+
+struct CYTypeUnsigned :
+ CYTypeSpecifier
+{
+ CYTypeSpecifier *specifier_;
+
+ CYTypeUnsigned(CYTypeSpecifier *specifier) :
+ specifier_(specifier)
+ {
+ }
+
+ virtual CYExpression *Replace(CYContext &context);
+ virtual void Output(CYOutput &out) const;
+};
+
+struct CYTypeSigned :
+ CYTypeSpecifier
+{
+ CYTypeSpecifier *specifier_;
+
+ CYTypeSigned(CYTypeSpecifier *specifier) :
+ specifier_(specifier)
+ {
+ }
+
+ virtual CYExpression *Replace(CYContext &context);
+ virtual void Output(CYOutput &out) const;
+};
+
+struct CYTypeLong :
+ CYTypeSpecifier
+{
+ CYTypeSpecifier *specifier_;
+
+ CYTypeLong(CYTypeSpecifier *specifier) :
+ specifier_(specifier)
+ {
+ }
+
+ virtual CYExpression *Replace(CYContext &context);
+ virtual void Output(CYOutput &out) const;
+};
+
+struct CYTypeShort :
+ CYTypeSpecifier
+{
+ CYTypeSpecifier *specifier_;
+
+ CYTypeShort(CYTypeSpecifier *specifier) :
+ specifier_(specifier)
+ {
+ }
+
+ virtual CYExpression *Replace(CYContext &context);
+ virtual void Output(CYOutput &out) const;
+};
+
struct CYTypeModifier :
CYNext<CYTypeModifier>
{
CYThing
{
CYIdentifier *identifier_;
- CYExpression *type_;
+ CYTypeSpecifier *specifier_;
CYTypeModifier *modifier_;
CYTypedIdentifier(CYIdentifier *identifier = NULL) :
identifier_(identifier),
- type_(NULL),
+ specifier_(NULL),
modifier_(NULL)
{
}
- CYTypedIdentifier(CYExpression *type, CYTypeModifier *modifier = NULL) :
+ CYTypedIdentifier(CYTypeSpecifier *specifier, CYTypeModifier *modifier = NULL) :
identifier_(NULL),
- type_(type),
+ specifier_(specifier),
modifier_(modifier)
{
}
return next_->Replace(context, $ CYCall($ CYDirectMember(type, $ CYString("functionWith")), parameters_->Argument(context)));
}
+CYExpression *CYTypeLong::Replace(CYContext &context) {
+ return $ CYCall($ CYDirectMember(specifier_->Replace(context), $ CYString("long")));
+}
+
CYExpression *CYTypePointerTo::Replace_(CYContext &context, CYExpression *type) {
return next_->Replace(context, $ CYCall($ CYDirectMember(type, $ CYString("pointerTo"))));
}
+CYExpression *CYTypeShort::Replace(CYContext &context) {
+ return $ CYCall($ CYDirectMember(specifier_->Replace(context), $ CYString("short")));
+}
+
+CYExpression *CYTypeSigned::Replace(CYContext &context) {
+ return $ CYCall($ CYDirectMember(specifier_->Replace(context), $ CYString("signed")));
+}
+
+CYExpression *CYTypeUnsigned::Replace(CYContext &context) {
+ return $ CYCall($ CYDirectMember(specifier_->Replace(context), $ CYString("unsigned")));
+}
+
+CYExpression *CYTypeVariable::Replace(CYContext &context) {
+ return $V(name_);
+}
+
+CYExpression *CYTypeVoid::Replace(CYContext &context) {
+ return $N1($V("Type"), $ CYString("v"));
+}
+
CYExpression *CYTypeVolatile::Replace_(CYContext &context, CYExpression *type) {
return next_->Replace(context, $ CYCall($ CYDirectMember(type, $ CYString("volatile"))));
}
CYExpression *CYTypedIdentifier::Replace(CYContext &context) {
- return modifier_->Replace(context, type_);
+ return modifier_->Replace(context, specifier_->Replace(context));
}
CYArgument *CYTypedParameter::Argument(CYContext &context) { $T(NULL)
}
CYExpression *CYTypedParameter::TypeSignature(CYContext &context, CYExpression *prefix) { $T(prefix)
- return next_->TypeSignature(context, $ CYAdd(prefix, typed_->type_->Replace(context)));
+ return next_->TypeSignature(context, $ CYAdd(prefix, typed_->specifier_->Replace(context)));
}
CYStatement *CYVar::Replace(CYContext &context) {