| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2016 Google Inc. | 2 * Copyright 2016 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "SkSLIRGenerator.h" | 8 #include "SkSLIRGenerator.h" |
| 9 | 9 |
| 10 #include "limits.h" | 10 #include "limits.h" |
| (...skipping 171 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 182 auto var = std::unique_ptr<Variable>(new Variable(decl.fPosition, modifi
ers, varDecl.fName, | 182 auto var = std::unique_ptr<Variable>(new Variable(decl.fPosition, modifi
ers, varDecl.fName, |
| 183 *type, storage)); | 183 *type, storage)); |
| 184 std::unique_ptr<Expression> value; | 184 std::unique_ptr<Expression> value; |
| 185 if (varDecl.fValue) { | 185 if (varDecl.fValue) { |
| 186 value = this->convertExpression(*varDecl.fValue); | 186 value = this->convertExpression(*varDecl.fValue); |
| 187 if (!value) { | 187 if (!value) { |
| 188 return nullptr; | 188 return nullptr; |
| 189 } | 189 } |
| 190 value = this->coerce(std::move(value), *type); | 190 value = this->coerce(std::move(value), *type); |
| 191 } | 191 } |
| 192 if ("sk_FragColor" == varDecl.fName && (*fSymbolTable)[varDecl.fName]) { | 192 if ("gl_FragCoord" == varDecl.fName && (*fSymbolTable)[varDecl.fName]) { |
| 193 // already defined, ignore | |
| 194 } else if ((*fSymbolTable)[varDecl.fName] && | |
| 195 (*fSymbolTable)[varDecl.fName]->fKind == Symbol::kVariable_Ki
nd && | |
| 196 ((Variable*) (*fSymbolTable)[varDecl.fName])->fModifiers.fLay
out.fBuiltin >= 0) { | |
| 197 // already defined, just update the modifiers | 193 // already defined, just update the modifiers |
| 198 Variable* old = (Variable*) (*fSymbolTable)[varDecl.fName]; | 194 Variable* old = (Variable*) (*fSymbolTable)[varDecl.fName]; |
| 199 old->fModifiers = var->fModifiers; | 195 old->fModifiers = var->fModifiers; |
| 200 } else { | 196 } else { |
| 201 variables.emplace_back(var.get(), std::move(sizes), std::move(value)
); | 197 variables.emplace_back(var.get(), std::move(sizes), std::move(value)
); |
| 202 fSymbolTable->add(varDecl.fName, std::move(var)); | 198 fSymbolTable->add(varDecl.fName, std::move(var)); |
| 203 } | 199 } |
| 204 } | 200 } |
| 205 return std::unique_ptr<VarDeclarations>(new VarDeclarations(decl.fPosition, | 201 return std::unique_ptr<VarDeclarations>(new VarDeclarations(decl.fPosition, |
| 206 baseType, | 202 baseType, |
| 207 std::move(variab
les))); | 203 std::move(variab
les))); |
| 208 } | 204 } |
| 209 | 205 |
| 210 std::unique_ptr<ModifiersDeclaration> IRGenerator::convertModifiersDeclaration( | |
| 211 const ASTModifi
ersDeclaration& m) { | |
| 212 Modifiers modifiers = this->convertModifiers(m.fModifiers); | |
| 213 return std::unique_ptr<ModifiersDeclaration>(new ModifiersDeclaration(modifi
ers)); | |
| 214 } | |
| 215 | |
| 216 std::unique_ptr<Statement> IRGenerator::convertIf(const ASTIfStatement& s) { | 206 std::unique_ptr<Statement> IRGenerator::convertIf(const ASTIfStatement& s) { |
| 217 std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*s.f
Test), | 207 std::unique_ptr<Expression> test = this->coerce(this->convertExpression(*s.f
Test), |
| 218 *fContext.fBool_Type); | 208 *fContext.fBool_Type); |
| 219 if (!test) { | 209 if (!test) { |
| 220 return nullptr; | 210 return nullptr; |
| 221 } | 211 } |
| 222 std::unique_ptr<Statement> ifTrue = this->convertStatement(*s.fIfTrue); | 212 std::unique_ptr<Statement> ifTrue = this->convertStatement(*s.fIfTrue); |
| 223 if (!ifTrue) { | 213 if (!ifTrue) { |
| 224 return nullptr; | 214 return nullptr; |
| 225 } | 215 } |
| (...skipping 196 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 422 FunctionDeclaration newDecl(f.fPosition, f.fName, parame
ters, *returnType); | 412 FunctionDeclaration newDecl(f.fPosition, f.fName, parame
ters, *returnType); |
| 423 fErrors.error(f.fPosition, "functions '" + newDecl.descr
iption() + | 413 fErrors.error(f.fPosition, "functions '" + newDecl.descr
iption() + |
| 424 "' and '" + other->descriptio
n() + | 414 "' and '" + other->descriptio
n() + |
| 425 "' differ only in return type
"); | 415 "' differ only in return type
"); |
| 426 return nullptr; | 416 return nullptr; |
| 427 } | 417 } |
| 428 decl = other; | 418 decl = other; |
| 429 for (size_t i = 0; i < parameters.size(); i++) { | 419 for (size_t i = 0; i < parameters.size(); i++) { |
| 430 if (parameters[i]->fModifiers != other->fParameters[i]->
fModifiers) { | 420 if (parameters[i]->fModifiers != other->fParameters[i]->
fModifiers) { |
| 431 fErrors.error(f.fPosition, "modifiers on parameter "
+ | 421 fErrors.error(f.fPosition, "modifiers on parameter "
+ |
| 432 to_string((uint64_t) i +
1) + | 422 to_string(i + 1) + " diff
er between " + |
| 433 " differ between declarat
ion and " | 423 "declaration and definiti
on"); |
| 434 "definition"); | |
| 435 return nullptr; | 424 return nullptr; |
| 436 } | 425 } |
| 437 } | 426 } |
| 438 if (other->fDefined) { | 427 if (other->fDefined) { |
| 439 fErrors.error(f.fPosition, "duplicate definition of " + | 428 fErrors.error(f.fPosition, "duplicate definition of " + |
| 440 other->description()); | 429 other->description()); |
| 441 } | 430 } |
| 442 break; | 431 break; |
| 443 } | 432 } |
| 444 } | 433 } |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 620 return nullptr; | 609 return nullptr; |
| 621 } | 610 } |
| 622 if (type.kind() == Type::kScalar_Kind) { | 611 if (type.kind() == Type::kScalar_Kind) { |
| 623 std::vector<std::unique_ptr<Expression>> args; | 612 std::vector<std::unique_ptr<Expression>> args; |
| 624 args.push_back(std::move(expr)); | 613 args.push_back(std::move(expr)); |
| 625 ASTIdentifier id(Position(), type.description()); | 614 ASTIdentifier id(Position(), type.description()); |
| 626 std::unique_ptr<Expression> ctor = this->convertIdentifier(id); | 615 std::unique_ptr<Expression> ctor = this->convertIdentifier(id); |
| 627 ASSERT(ctor); | 616 ASSERT(ctor); |
| 628 return this->call(Position(), std::move(ctor), std::move(args)); | 617 return this->call(Position(), std::move(ctor), std::move(args)); |
| 629 } | 618 } |
| 630 std::vector<std::unique_ptr<Expression>> args; | 619 ABORT("cannot coerce %s to %s", expr->fType.description().c_str(), |
| 631 args.push_back(std::move(expr)); | 620 type.description().c_str()); |
| 632 return std::unique_ptr<Expression>(new Constructor(Position(), type, std::mo
ve(args))); | |
| 633 } | 621 } |
| 634 | 622 |
| 635 static bool is_matrix_multiply(const Type& left, const Type& right) { | 623 static bool is_matrix_multiply(const Type& left, const Type& right) { |
| 636 if (left.kind() == Type::kMatrix_Kind) { | 624 if (left.kind() == Type::kMatrix_Kind) { |
| 637 return right.kind() == Type::kMatrix_Kind || right.kind() == Type::kVect
or_Kind; | 625 return right.kind() == Type::kMatrix_Kind || right.kind() == Type::kVect
or_Kind; |
| 638 } | 626 } |
| 639 return left.kind() == Type::kVector_Kind && right.kind() == Type::kMatrix_Ki
nd; | 627 return left.kind() == Type::kVector_Kind && right.kind() == Type::kMatrix_Ki
nd; |
| 640 } | 628 } |
| 641 /** | 629 /** |
| 642 * Determines the operand and result types of a binary expression. Returns true
if the expression is | 630 * Determines the operand and result types of a binary expression. Returns true
if the expression is |
| (...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 837 std::move(test), | 825 std::move(test), |
| 838 std::move(ifTrue), | 826 std::move(ifTrue), |
| 839 std::move(ifFalse))
); | 827 std::move(ifFalse))
); |
| 840 } | 828 } |
| 841 | 829 |
| 842 std::unique_ptr<Expression> IRGenerator::call(Position position, | 830 std::unique_ptr<Expression> IRGenerator::call(Position position, |
| 843 const FunctionDeclaration& functio
n, | 831 const FunctionDeclaration& functio
n, |
| 844 std::vector<std::unique_ptr<Expres
sion>> arguments) { | 832 std::vector<std::unique_ptr<Expres
sion>> arguments) { |
| 845 if (function.fParameters.size() != arguments.size()) { | 833 if (function.fParameters.size() != arguments.size()) { |
| 846 std::string msg = "call to '" + function.fName + "' expected " + | 834 std::string msg = "call to '" + function.fName + "' expected " + |
| 847 to_string((uint64_t) function.fParameters.size(
)) + | 835 to_string(function.fParameters.size()) + |
| 848 " argument"; | 836 " argument"; |
| 849 if (function.fParameters.size() != 1) { | 837 if (function.fParameters.size() != 1) { |
| 850 msg += "s"; | 838 msg += "s"; |
| 851 } | 839 } |
| 852 msg += ", but found " + to_string((uint64_t) arguments.size()); | 840 msg += ", but found " + to_string(arguments.size()); |
| 853 fErrors.error(position, msg); | 841 fErrors.error(position, msg); |
| 854 return nullptr; | 842 return nullptr; |
| 855 } | 843 } |
| 856 for (size_t i = 0; i < arguments.size(); i++) { | 844 for (size_t i = 0; i < arguments.size(); i++) { |
| 857 arguments[i] = this->coerce(std::move(arguments[i]), function.fParameter
s[i]->fType); | 845 arguments[i] = this->coerce(std::move(arguments[i]), function.fParameter
s[i]->fType); |
| 858 if (arguments[i] && (function.fParameters[i]->fModifiers.fFlags & Modifi
ers::kOut_Flag)) { | 846 if (arguments[i] && (function.fParameters[i]->fModifiers.fFlags & Modifi
ers::kOut_Flag)) { |
| 859 this->markWrittenTo(*arguments[i]); | 847 this->markWrittenTo(*arguments[i]); |
| 860 } | 848 } |
| 861 } | 849 } |
| 862 return std::unique_ptr<FunctionCall>(new FunctionCall(position, function, | 850 return std::unique_ptr<FunctionCall>(new FunctionCall(position, function, |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 926 } | 914 } |
| 927 return this->call(position, *ref->fFunctions[0], std::move(arguments)); | 915 return this->call(position, *ref->fFunctions[0], std::move(arguments)); |
| 928 } | 916 } |
| 929 | 917 |
| 930 std::unique_ptr<Expression> IRGenerator::convertConstructor( | 918 std::unique_ptr<Expression> IRGenerator::convertConstructor( |
| 931 Position position, | 919 Position position, |
| 932 const Type& type, | 920 const Type& type, |
| 933 std::vector<std::unique_ptr<
Expression>> args) { | 921 std::vector<std::unique_ptr<
Expression>> args) { |
| 934 // FIXME: add support for structs and arrays | 922 // FIXME: add support for structs and arrays |
| 935 Type::Kind kind = type.kind(); | 923 Type::Kind kind = type.kind(); |
| 936 if (!type.isNumber() && kind != Type::kVector_Kind && kind != Type::kMatrix_
Kind && | 924 if (!type.isNumber() && kind != Type::kVector_Kind && kind != Type::kMatrix_
Kind) { |
| 937 kind != Type::kArray_Kind) { | |
| 938 fErrors.error(position, "cannot construct '" + type.description() + "'")
; | 925 fErrors.error(position, "cannot construct '" + type.description() + "'")
; |
| 939 return nullptr; | 926 return nullptr; |
| 940 } | 927 } |
| 941 if (type == *fContext.fFloat_Type && args.size() == 1 && | 928 if (type == *fContext.fFloat_Type && args.size() == 1 && |
| 942 args[0]->fKind == Expression::kIntLiteral_Kind) { | 929 args[0]->fKind == Expression::kIntLiteral_Kind) { |
| 943 int64_t value = ((IntLiteral&) *args[0]).fValue; | 930 int64_t value = ((IntLiteral&) *args[0]).fValue; |
| 944 return std::unique_ptr<Expression>(new FloatLiteral(fContext, position,
(double) value)); | 931 return std::unique_ptr<Expression>(new FloatLiteral(fContext, position,
(double) value)); |
| 945 } | 932 } |
| 946 if (args.size() == 1 && args[0]->fType == type) { | 933 if (args.size() == 1 && args[0]->fType == type) { |
| 947 // argument is already the right type, just return it | 934 // argument is already the right type, just return it |
| 948 return std::move(args[0]); | 935 return std::move(args[0]); |
| 949 } | 936 } |
| 950 if (type.isNumber()) { | 937 if (type.isNumber()) { |
| 951 if (args.size() != 1) { | 938 if (args.size() != 1) { |
| 952 fErrors.error(position, "invalid arguments to '" + type.description(
) + | 939 fErrors.error(position, "invalid arguments to '" + type.description(
) + |
| 953 "' constructor, (expected exactly 1 argument
, but found " + | 940 "' constructor, (expected exactly 1 argument
, but found " + |
| 954 to_string((uint64_t) args.size()) + ")"); | 941 to_string(args.size()) + ")"); |
| 955 } | 942 } |
| 956 if (args[0]->fType == *fContext.fBool_Type) { | 943 if (args[0]->fType == *fContext.fBool_Type) { |
| 957 std::unique_ptr<IntLiteral> zero(new IntLiteral(fContext, position,
0)); | 944 std::unique_ptr<IntLiteral> zero(new IntLiteral(fContext, position,
0)); |
| 958 std::unique_ptr<IntLiteral> one(new IntLiteral(fContext, position, 1
)); | 945 std::unique_ptr<IntLiteral> one(new IntLiteral(fContext, position, 1
)); |
| 959 return std::unique_ptr<Expression>( | 946 return std::unique_ptr<Expression>( |
| 960 new TernaryExpression(position, std::mo
ve(args[0]), | 947 new TernaryExpression(position, std::mo
ve(args[0]), |
| 961 this->coerce(std:
:move(one), type), | 948 this->coerce(std:
:move(one), type), |
| 962 this->coerce(std:
:move(zero), | 949 this->coerce(std:
:move(zero), |
| 963 type
))); | 950 type
))); |
| 964 } else if (!args[0]->fType.isNumber()) { | 951 } else if (!args[0]->fType.isNumber()) { |
| 965 fErrors.error(position, "invalid argument to '" + type.description()
+ | 952 fErrors.error(position, "invalid argument to '" + type.description()
+ |
| 966 "' constructor (expected a number or bool, b
ut found '" + | 953 "' constructor (expected a number or bool, b
ut found '" + |
| 967 args[0]->fType.description() + "')"); | 954 args[0]->fType.description() + "')"); |
| 968 } | 955 } |
| 969 if (args[0]->fKind == Expression::kIntLiteral_Kind && (type == *fContext
.fInt_Type || | |
| 970 type == *fContext.fUInt_Type)) { | |
| 971 return std::unique_ptr<Expression>(new IntLiteral(fContext, | |
| 972 position, | |
| 973 ((IntLiteral&) *ar
gs[0]).fValue, | |
| 974 &type)); | |
| 975 } | |
| 976 } else if (kind == Type::kArray_Kind) { | |
| 977 const Type& base = type.componentType(); | |
| 978 for (size_t i = 0; i < args.size(); i++) { | |
| 979 args[i] = this->coerce(std::move(args[i]), base); | |
| 980 } | |
| 981 } else { | 956 } else { |
| 982 ASSERT(kind == Type::kVector_Kind || kind == Type::kMatrix_Kind); | 957 ASSERT(kind == Type::kVector_Kind || kind == Type::kMatrix_Kind); |
| 983 int actual = 0; | 958 int actual = 0; |
| 984 for (size_t i = 0; i < args.size(); i++) { | 959 for (size_t i = 0; i < args.size(); i++) { |
| 985 if (args[i]->fType.kind() == Type::kVector_Kind || | 960 if (args[i]->fType.kind() == Type::kVector_Kind || |
| 986 args[i]->fType.kind() == Type::kMatrix_Kind) { | 961 args[i]->fType.kind() == Type::kMatrix_Kind) { |
| 987 int columns = args[i]->fType.columns(); | 962 int columns = args[i]->fType.columns(); |
| 988 int rows = args[i]->fType.rows(); | 963 int rows = args[i]->fType.rows(); |
| 989 args[i] = this->coerce(std::move(args[i]), | 964 args[i] = this->coerce(std::move(args[i]), |
| 990 type.componentType().toCompound(fContext,
columns, rows)); | 965 type.componentType().toCompound(fContext,
columns, rows)); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1055 break; | 1030 break; |
| 1056 case Token::MINUSMINUS: | 1031 case Token::MINUSMINUS: |
| 1057 if (!base->fType.isNumber()) { | 1032 if (!base->fType.isNumber()) { |
| 1058 fErrors.error(expression.fPosition, | 1033 fErrors.error(expression.fPosition, |
| 1059 "'" + Token::OperatorName(expression.fOperator) + | 1034 "'" + Token::OperatorName(expression.fOperator) + |
| 1060 "' cannot operate on '" + base->fType.description(
) + "'"); | 1035 "' cannot operate on '" + base->fType.description(
) + "'"); |
| 1061 return nullptr; | 1036 return nullptr; |
| 1062 } | 1037 } |
| 1063 this->markWrittenTo(*base); | 1038 this->markWrittenTo(*base); |
| 1064 break; | 1039 break; |
| 1065 case Token::LOGICALNOT: | 1040 case Token::NOT: |
| 1066 if (base->fType != *fContext.fBool_Type) { | 1041 if (base->fType != *fContext.fBool_Type) { |
| 1067 fErrors.error(expression.fPosition, | 1042 fErrors.error(expression.fPosition, |
| 1068 "'" + Token::OperatorName(expression.fOperator) + | 1043 "'" + Token::OperatorName(expression.fOperator) + |
| 1069 "' cannot operate on '" + base->fType.description(
) + "'"); | 1044 "' cannot operate on '" + base->fType.description(
) + "'"); |
| 1070 return nullptr; | 1045 return nullptr; |
| 1071 } | 1046 } |
| 1072 break; | 1047 break; |
| 1073 case Token::BITWISENOT: | |
| 1074 if (base->fType != *fContext.fInt_Type) { | |
| 1075 fErrors.error(expression.fPosition, | |
| 1076 "'" + Token::OperatorName(expression.fOperator) + | |
| 1077 "' cannot operate on '" + base->fType.description(
) + "'"); | |
| 1078 return nullptr; | |
| 1079 } | |
| 1080 break; | |
| 1081 default: | 1048 default: |
| 1082 ABORT("unsupported prefix operator\n"); | 1049 ABORT("unsupported prefix operator\n"); |
| 1083 } | 1050 } |
| 1084 return std::unique_ptr<Expression>(new PrefixExpression(expression.fOperator
, | 1051 return std::unique_ptr<Expression>(new PrefixExpression(expression.fOperator
, |
| 1085 std::move(base))); | 1052 std::move(base))); |
| 1086 } | 1053 } |
| 1087 | 1054 |
| 1088 std::unique_ptr<Expression> IRGenerator::convertIndex(std::unique_ptr<Expression
> base, | 1055 std::unique_ptr<Expression> IRGenerator::convertIndex(std::unique_ptr<Expression
> base, |
| 1089 const ASTExpression& index
) { | 1056 const ASTExpression& index
) { |
| 1090 if (base->fType.kind() != Type::kArray_Kind && base->fType.kind() != Type::k
Matrix_Kind && | 1057 if (base->fType.kind() != Type::kArray_Kind && base->fType.kind() != Type::k
Matrix_Kind) { |
| 1091 base->fType.kind() != Type::kVector_Kind) { | |
| 1092 fErrors.error(base->fPosition, "expected array, but found '" + base->fTy
pe.description() + | 1058 fErrors.error(base->fPosition, "expected array, but found '" + base->fTy
pe.description() + |
| 1093 "'"); | 1059 "'"); |
| 1094 return nullptr; | 1060 return nullptr; |
| 1095 } | 1061 } |
| 1096 std::unique_ptr<Expression> converted = this->convertExpression(index); | 1062 std::unique_ptr<Expression> converted = this->convertExpression(index); |
| 1097 if (!converted) { | 1063 if (!converted) { |
| 1098 return nullptr; | 1064 return nullptr; |
| 1099 } | 1065 } |
| 1100 if (converted->fType != *fContext.fUInt_Type) { | 1066 converted = this->coerce(std::move(converted), *fContext.fInt_Type); |
| 1101 converted = this->coerce(std::move(converted), *fContext.fInt_Type); | 1067 if (!converted) { |
| 1102 if (!converted) { | 1068 return nullptr; |
| 1103 return nullptr; | |
| 1104 } | |
| 1105 } | 1069 } |
| 1106 return std::unique_ptr<Expression>(new IndexExpression(fContext, std::move(b
ase), | 1070 return std::unique_ptr<Expression>(new IndexExpression(fContext, std::move(b
ase), |
| 1107 std::move(converted))
); | 1071 std::move(converted))
); |
| 1108 } | 1072 } |
| 1109 | 1073 |
| 1110 std::unique_ptr<Expression> IRGenerator::convertField(std::unique_ptr<Expression
> base, | 1074 std::unique_ptr<Expression> IRGenerator::convertField(std::unique_ptr<Expression
> base, |
| 1111 const std::string& field)
{ | 1075 const std::string& field)
{ |
| 1112 auto fields = base->fType.fields(); | 1076 auto fields = base->fType.fields(); |
| 1113 for (size_t i = 0; i < fields.size(); i++) { | 1077 for (size_t i = 0; i < fields.size(); i++) { |
| 1114 if (fields[i].fName == field) { | 1078 if (fields[i].fName == field) { |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1172 return std::unique_ptr<Expression>(new Swizzle(fContext, std::move(base), sw
izzleComponents)); | 1136 return std::unique_ptr<Expression>(new Swizzle(fContext, std::move(base), sw
izzleComponents)); |
| 1173 } | 1137 } |
| 1174 | 1138 |
| 1175 std::unique_ptr<Expression> IRGenerator::convertSuffixExpression( | 1139 std::unique_ptr<Expression> IRGenerator::convertSuffixExpression( |
| 1176 const ASTSuffixExpre
ssion& expression) { | 1140 const ASTSuffixExpre
ssion& expression) { |
| 1177 std::unique_ptr<Expression> base = this->convertExpression(*expression.fBase
); | 1141 std::unique_ptr<Expression> base = this->convertExpression(*expression.fBase
); |
| 1178 if (!base) { | 1142 if (!base) { |
| 1179 return nullptr; | 1143 return nullptr; |
| 1180 } | 1144 } |
| 1181 switch (expression.fSuffix->fKind) { | 1145 switch (expression.fSuffix->fKind) { |
| 1182 case ASTSuffix::kIndex_Kind: { | 1146 case ASTSuffix::kIndex_Kind: |
| 1183 const ASTExpression* expr = ((ASTIndexSuffix&) *expression.fSuffix).
fExpression.get(); | 1147 return this->convertIndex(std::move(base), |
| 1184 if (expr) { | 1148 *((ASTIndexSuffix&) *expression.fSuffix).f
Expression); |
| 1185 return this->convertIndex(std::move(base), *expr); | |
| 1186 } else if (base->fKind == Expression::kTypeReference_Kind) { | |
| 1187 const Type& oldType = ((TypeReference&) *base).fValue; | |
| 1188 Type* newType = new Type(oldType.name() + "[]", Type::kArray_Kin
d, oldType, | |
| 1189 -1); | |
| 1190 fSymbolTable->takeOwnership(newType); | |
| 1191 return std::unique_ptr<Expression>(new TypeReference(fContext, b
ase->fPosition, | |
| 1192 *newType)); | |
| 1193 } else { | |
| 1194 fErrors.error(expression.fPosition, "'[]' must follow a type nam
e"); | |
| 1195 } | |
| 1196 } | |
| 1197 case ASTSuffix::kCall_Kind: { | 1149 case ASTSuffix::kCall_Kind: { |
| 1198 auto rawArguments = &((ASTCallSuffix&) *expression.fSuffix).fArgumen
ts; | 1150 auto rawArguments = &((ASTCallSuffix&) *expression.fSuffix).fArgumen
ts; |
| 1199 std::vector<std::unique_ptr<Expression>> arguments; | 1151 std::vector<std::unique_ptr<Expression>> arguments; |
| 1200 for (size_t i = 0; i < rawArguments->size(); i++) { | 1152 for (size_t i = 0; i < rawArguments->size(); i++) { |
| 1201 std::unique_ptr<Expression> converted = | 1153 std::unique_ptr<Expression> converted = |
| 1202 this->convertExpression(*(*rawArguments)[i]); | 1154 this->convertExpression(*(*rawArguments)[i]); |
| 1203 if (!converted) { | 1155 if (!converted) { |
| 1204 return nullptr; | 1156 return nullptr; |
| 1205 } | 1157 } |
| 1206 arguments.push_back(std::move(converted)); | 1158 arguments.push_back(std::move(converted)); |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1299 case Expression::kIndex_Kind: | 1251 case Expression::kIndex_Kind: |
| 1300 this->markWrittenTo(*((IndexExpression&) expr).fBase); | 1252 this->markWrittenTo(*((IndexExpression&) expr).fBase); |
| 1301 break; | 1253 break; |
| 1302 default: | 1254 default: |
| 1303 fErrors.error(expr.fPosition, "cannot assign to '" + expr.descriptio
n() + "'"); | 1255 fErrors.error(expr.fPosition, "cannot assign to '" + expr.descriptio
n() + "'"); |
| 1304 break; | 1256 break; |
| 1305 } | 1257 } |
| 1306 } | 1258 } |
| 1307 | 1259 |
| 1308 } | 1260 } |
| OLD | NEW |