MCPcopy Create free account
hub / github.com/compilets/compilets / castExpression

Function castExpression

src/cpp-syntax-utils.ts:73–145  ·  view source on GitHub ↗
(expr: Expression, target: Type, source?: Type)

Source from the content-addressed store, hash-verified

71 * Convert the expression of source type to target type if necessary.
72 */
73export function castExpression(expr: Expression, target: Type, source?: Type): Expression {
74 if (target.category == 'any')
75 return expr;
76 // The operands of ?: do not necessarily have same type.
77 if (expr instanceof ConditionalExpression) {
78 expr.whenTrue = strictCastExpression(expr.whenTrue, target);
79 expr.whenFalse = strictCastExpression(expr.whenFalse, target);
80 return expr;
81 }
82 // The array literal's type depends on the target type.
83 if (expr instanceof ArrayLiteralExpression && target.category == 'array') {
84 // Change array type to target type if:
85 // 1. This is an empty array, i.e. [].
86 // 2. The element type is directly assignable to target type.
87 if (expr.elements.length == 0 ||
88 target.getElementType().assignableWith(expr.type.getElementType())) {
89 expr.type.types[0] = target.getElementType().clone();
90 expr.elements = expr.elements.map(e => castExpression(e, expr.type.getElementType()));
91 return expr;
92 }
93 }
94 // The numeric literal's type is dynamic, it could be the target type if it
95 // is a direct assignment, otherwise it requires a explicit conversion.
96 if (expr instanceof NumericLiteral) {
97 if (target.category == 'primitive')
98 return expr;
99 return new CustomExpression(target, (ctx) => {
100 return `static_cast<double>(${expr.print(ctx)})`;
101 });
102 }
103 source = source ?? expr.type;
104 // Parse composited types.
105 if (source.category == 'union' || target.category == 'union') {
106 expr = castUnion(expr, target, source);
107 source = expr.type;
108 } else if (source.isOptional || target.isOptional) {
109 expr = castOptional(expr, target, source);
110 source = expr.type;
111 }
112 // We don't support using methods as functors yet.
113 if (source.category == 'method' && target.category == 'functor')
114 throw new Error('Can not use method as function');
115 // Convert function pointer to functor object.
116 if (source.category == 'function' && target.category == 'functor') {
117 return new CustomExpression(target, (ctx) => {
118 ctx.features.add('function');
119 const signature = (target as FunctionType).getSignature();
120 return `compilets::MakeFunction<${signature}>(${expr.print(ctx)})`;
121 });
122 }
123 // Convert between primitive types.
124 if (source.category == 'primitive' && target.category == 'primitive') {
125 if (source.name == target.name)
126 return expr;
127 return new CustomExpression(target, (ctx) => {
128 return `static_cast<${target.name}>(${expr.print(ctx)})`;
129 });
130 }

Callers 10

constructorMethod · 0.90
constructorMethod · 0.90
constructorMethod · 0.90
constructorMethod · 0.90
constructorMethod · 0.90
constructorMethod · 0.90
constructorMethod · 0.90
strictCastExpressionFunction · 0.85
castArgumentsFunction · 0.85
castUnionFunction · 0.85

Calls 9

strictCastExpressionFunction · 0.85
castUnionFunction · 0.85
castOptionalFunction · 0.85
assignableWithMethod · 0.80
getElementTypeMethod · 0.80
getSignatureMethod · 0.80
cloneMethod · 0.45
printMethod · 0.45
equalMethod · 0.45

Tested by

no test coverage detected