| 1085 | return expr; |
| 1086 | } |
| 1087 | virtual RefPtr<ExpressionSyntaxNode> VisitMemberExpression(MemberExpressionSyntaxNode * expr) override |
| 1088 | { |
| 1089 | RefPtr<Object> refObj; |
| 1090 | if (expr->Tags.TryGetValue("ComponentReference", refObj)) |
| 1091 | { |
| 1092 | if (auto refComp = refObj.As<StringObject>()) |
| 1093 | { |
| 1094 | ILOperand * op; |
| 1095 | if (variables.TryGetValue(refComp->Content, op)) |
| 1096 | PushStack(op); |
| 1097 | else |
| 1098 | throw InvalidProgramException("referencing undefined component/variable. probable cause: unchecked circular reference."); |
| 1099 | } |
| 1100 | } |
| 1101 | else |
| 1102 | { |
| 1103 | expr->BaseExpression->Access = expr->Access; |
| 1104 | expr->BaseExpression->Accept(this); |
| 1105 | auto base = PopStack(); |
| 1106 | auto generateSingleMember = [&](char memberName) |
| 1107 | { |
| 1108 | int idx = 0; |
| 1109 | if (memberName == 'y' || memberName == 'g') |
| 1110 | idx = 1; |
| 1111 | else if (memberName == 'z' || memberName == 'b') |
| 1112 | idx = 2; |
| 1113 | else if (memberName == 'w' || memberName == 'a') |
| 1114 | idx = 3; |
| 1115 | |
| 1116 | GenerateIndexExpression(base, result.Program->ConstantPool->CreateConstant(idx), |
| 1117 | expr->Access == ExpressionAccess::Read); |
| 1118 | }; |
| 1119 | if (expr->BaseExpression->Type->IsVectorType()) |
| 1120 | { |
| 1121 | if (expr->MemberName.Length() == 1) |
| 1122 | { |
| 1123 | generateSingleMember(expr->MemberName[0]); |
| 1124 | } |
| 1125 | else |
| 1126 | { |
| 1127 | auto rs = new SwizzleInstruction(); |
| 1128 | rs->Type = TranslateExpressionType(expr->Type.Ptr()); |
| 1129 | rs->SwizzleString = expr->MemberName; |
| 1130 | rs->Operand = base; |
| 1131 | codeWriter.Insert(rs); |
| 1132 | PushStack(rs); |
| 1133 | } |
| 1134 | } |
| 1135 | else if (expr->BaseExpression->Type->IsStruct()) |
| 1136 | { |
| 1137 | int id = expr->BaseExpression->Type->AsBasicType()->structDecl->FindFieldIndex(expr->MemberName); |
| 1138 | GenerateIndexExpression(base, result.Program->ConstantPool->CreateConstant(id), |
| 1139 | expr->Access == ExpressionAccess::Read); |
| 1140 | } |
| 1141 | else |
| 1142 | throw NotImplementedException("member expression codegen"); |
| 1143 | } |
| 1144 | return expr; |
nothing calls this directly
no test coverage detected