diff options
-rw-r--r-- | tools/gn/args.cc | 18 | ||||
-rw-r--r-- | tools/gn/function_toolchain.cc | 6 | ||||
-rw-r--r-- | tools/gn/functions.cc | 10 | ||||
-rw-r--r-- | tools/gn/operators.cc | 49 | ||||
-rw-r--r-- | tools/gn/parse_tree.cc | 14 | ||||
-rw-r--r-- | tools/gn/parser.cc | 2 | ||||
-rw-r--r-- | tools/gn/secondary/build/config/BUILDCONFIG.gn | 18 | ||||
-rw-r--r-- | tools/gn/secondary/build/toolchain/nacl/BUILD.gn | 14 | ||||
-rw-r--r-- | tools/gn/string_utils_unittest.cc | 3 | ||||
-rw-r--r-- | tools/gn/token.h | 2 | ||||
-rw-r--r-- | tools/gn/tokenizer.cc | 6 | ||||
-rw-r--r-- | tools/gn/value.cc | 40 | ||||
-rw-r--r-- | tools/gn/value.h | 20 |
13 files changed, 127 insertions, 75 deletions
diff --git a/tools/gn/args.cc b/tools/gn/args.cc index d60f1e7..d340713 100644 --- a/tools/gn/args.cc +++ b/tools/gn/args.cc @@ -25,7 +25,7 @@ const char kBuildArgs_Help[] = " applied. These can override the system default ones, and add new ones.\n" " These are whitespace-separated. For example:\n" "\n" - " gn --args=\"teleportation_level=3 is_win=1 is_evil=0\"\n" + " gn --args=\"is_win=true enable_doom_melon=false\"\n" "\n" " Third, toolchain overrides are applied. These are specified in the\n" " toolchain_args section of a toolchain definition. The use-case for\n" @@ -145,11 +145,11 @@ bool Args::VerifyAllOverridesUsed(Err* err) const { void Args::SetSystemVars(Scope* dest) const { #if defined(OS_WIN) - Value is_win(NULL, 1); - Value is_posix(NULL, 0); + Value is_win(NULL, true); + Value is_posix(NULL, false); #else - Value is_win(NULL, 0); - Value is_posix(NULL, 1); + Value is_win(NULL, false); + Value is_posix(NULL, true); #endif dest->SetValue(variables::kIsWin, is_win, NULL); dest->SetValue(variables::kIsPosix, is_posix, NULL); @@ -157,17 +157,17 @@ void Args::SetSystemVars(Scope* dest) const { declared_arguments_[variables::kIsPosix] = is_posix; #if defined(OS_MACOSX) - Value is_mac(NULL, 1); + Value is_mac(NULL, true); #else - Value is_mac(NULL, 0); + Value is_mac(NULL, false); #endif dest->SetValue(variables::kIsMac, is_mac, NULL); declared_arguments_[variables::kIsMac] = is_mac; #if defined(OS_LINUX) - Value is_linux(NULL, 1); + Value is_linux(NULL, true); #else - Value is_linux(NULL, 0); + Value is_linux(NULL, false); #endif dest->SetValue(variables::kIsLinux, is_linux, NULL); declared_arguments_[variables::kIsLinux] = is_linux; diff --git a/tools/gn/function_toolchain.cc b/tools/gn/function_toolchain.cc index 8bb3065..63aa3c2 100644 --- a/tools/gn/function_toolchain.cc +++ b/tools/gn/function_toolchain.cc @@ -166,11 +166,11 @@ extern const char kToolchainArgs_Help[] = " ...\n" " toolchain_args() {\n" " # Override the system values for a generic Posix system.\n" - " is_win = 0\n" - " is_posix = 1\n" + " is_win = false\n" + " is_posix = true\n" "\n" " # Pass this new value for specific setup for my toolchain.\n" - " is_my_weird_system = 1\n" + " is_my_weird_system = true\n" " }\n" " }\n"; diff --git a/tools/gn/functions.cc b/tools/gn/functions.cc index 2da5ef5..11608ef 100644 --- a/tools/gn/functions.cc +++ b/tools/gn/functions.cc @@ -166,7 +166,9 @@ Value RunAssert(Scope* scope, *err = Err(function->function(), "Wrong number of arguments.", "assert() takes one argument, " "were you expecting somethig else?"); - } else if (args[0].InterpretAsInt() == 0) { + } else if (args[0].type() != Value::BOOLEAN) { + *err = Err(function->function(), "Assertion value not a bool."); + } else if (!args[0].boolean_value()) { *err = Err(function->function(), "Assertion failed."); if (args[0].origin()) { // If you do "assert(foo)" we'd ideally like to show you where foo was @@ -248,12 +250,12 @@ const char kDeclareArgs_Help[] = "\n" "Example:\n" " declare_args() {\n" - " enable_teleporter = 1\n" - " enable_doom_melon = 0\n" + " enable_teleporter = true\n" + " enable_doom_melon = false\n" " }\n" "\n" " If you want to override the (default disabled) Doom Melon:\n" - " gn --args=\"enable_doom_melon=1 enable-teleporter=1\"\n" + " gn --args=\"enable_doom_melon=true enable_teleporter=false\"\n" " This also sets the teleporter, but it's already defaulted to on so\n" " it will have no effect.\n"; diff --git a/tools/gn/operators.cc b/tools/gn/operators.cc index 9cc0de3..0e91f6b 100644 --- a/tools/gn/operators.cc +++ b/tools/gn/operators.cc @@ -56,6 +56,7 @@ void RemoveMatchesFromList(const BinaryOpNode* op_node, Err* err) { std::vector<Value>& v = list->list_value(); switch (to_remove.type()) { + case Value::BOOLEAN: case Value::INTEGER: // Filter out the individual int/string. case Value::STRING: { bool found_match = false; @@ -342,8 +343,8 @@ Value ExecuteEqualsEquals(Scope* scope, const Value& right, Err* err) { if (left == right) - return Value(op_node, 1); - return Value(op_node, 0); + return Value(op_node, true); + return Value(op_node, false); } Value ExecuteNotEquals(Scope* scope, @@ -357,10 +358,10 @@ Value ExecuteNotEquals(Scope* scope, return result; } -Value FillNeedsToIntegersError(const BinaryOpNode* op_node, - const Value& left, - const Value& right, - Err* err) { +Value FillNeedsTwoIntegersError(const BinaryOpNode* op_node, + const Value& left, + const Value& right, + Err* err) { *err = Err(op_node, "Comparison requires two integers.", "This operator can only compare two integers."); err->AppendRange(left.origin()->GetRange()); @@ -374,7 +375,7 @@ Value ExecuteLessEquals(Scope* scope, const Value& right, Err* err) { if (left.type() != Value::INTEGER || right.type() != Value::INTEGER) - return FillNeedsToIntegersError(op_node, left, right, err); + return FillNeedsTwoIntegersError(op_node, left, right, err); return Value(op_node, left.int_value() <= right.int_value()); } @@ -384,7 +385,7 @@ Value ExecuteGreaterEquals(Scope* scope, const Value& right, Err* err) { if (left.type() != Value::INTEGER || right.type() != Value::INTEGER) - return FillNeedsToIntegersError(op_node, left, right, err); + return FillNeedsTwoIntegersError(op_node, left, right, err); return Value(op_node, left.int_value() >= right.int_value()); } @@ -394,7 +395,7 @@ Value ExecuteGreater(Scope* scope, const Value& right, Err* err) { if (left.type() != Value::INTEGER || right.type() != Value::INTEGER) - return FillNeedsToIntegersError(op_node, left, right, err); + return FillNeedsTwoIntegersError(op_node, left, right, err); return Value(op_node, left.int_value() > right.int_value()); } @@ -404,7 +405,7 @@ Value ExecuteLess(Scope* scope, const Value& right, Err* err) { if (left.type() != Value::INTEGER || right.type() != Value::INTEGER) - return FillNeedsToIntegersError(op_node, left, right, err); + return FillNeedsTwoIntegersError(op_node, left, right, err); return Value(op_node, left.int_value() < right.int_value()); } @@ -415,8 +416,14 @@ Value ExecuteOr(Scope* scope, const Value& left, const Value& right, Err* err) { - return Value(op_node, - static_cast<int64>(left.InterpretAsInt() || right.InterpretAsInt())); + if (left.type() != Value::BOOLEAN) { + *err = Err(left, "Left side of || operator is not a boolean."); + err->AppendRange(op_node->GetRange()); + } else if (right.type() != Value::BOOLEAN) { + *err = Err(right, "Right side of || operator is not a boolean."); + err->AppendRange(op_node->GetRange()); + } + return Value(op_node, left.boolean_value() || right.boolean_value()); } Value ExecuteAnd(Scope* scope, @@ -424,8 +431,14 @@ Value ExecuteAnd(Scope* scope, const Value& left, const Value& right, Err* err) { - return Value(op_node, - static_cast<int64>(left.InterpretAsInt() && right.InterpretAsInt())); + if (left.type() != Value::BOOLEAN) { + *err = Err(left, "Left side of && operator is not a boolean."); + err->AppendRange(op_node->GetRange()); + } else if (right.type() != Value::BOOLEAN) { + *err = Err(right, "Right side of && operator is not a boolean."); + err->AppendRange(op_node->GetRange()); + } + return Value(op_node, left.boolean_value() && right.boolean_value()); } } // namespace @@ -473,8 +486,14 @@ Value ExecuteUnaryOperator(Scope* scope, const Value& expr, Err* err) { DCHECK(op_node->op().type() == Token::BANG); + + if (expr.type() != Value::BOOLEAN) { + *err = Err(expr, "Operand of ! operator is not a boolean."); + err->AppendRange(op_node->GetRange()); + return Value(); + } // TODO(scottmg): Why no unary minus? - return Value(op_node, !expr.InterpretAsInt()); + return Value(op_node, !expr.boolean_value()); } Value ExecuteBinaryOperator(Scope* scope, diff --git a/tools/gn/parse_tree.cc b/tools/gn/parse_tree.cc index 613c797..24c477d 100644 --- a/tools/gn/parse_tree.cc +++ b/tools/gn/parse_tree.cc @@ -218,15 +218,17 @@ Value ConditionNode::Execute(Scope* scope, Err* err) const { Value condition_result = condition_->Execute(scope, err); if (err->has_error()) return Value(); - if (condition_result.type() == Value::NONE) { + if (condition_result.type() != Value::BOOLEAN) { *err = condition_->MakeErrorDescribing( - "This does not evaluate to a value.", - "Please give me something to work with for the if statement."); + "Condition does not evaluate to a boolean value.", + std::string("This is a value of type \"") + + Value::DescribeType(condition_result.type()) + + "\" instead."); err->AppendRange(if_token_.range()); return Value(); } - if (condition_result.InterpretAsInt()) { + if (condition_result.boolean_value()) { if_true_->ExecuteBlockInScope(scope, err); } else if (if_false_) { // The else block is optional. It's either another condition (for an @@ -402,6 +404,10 @@ const LiteralNode* LiteralNode::AsLiteral() const { Value LiteralNode::Execute(Scope* scope, Err* err) const { switch (value_.type()) { + case Token::TRUE_TOKEN: + return Value(this, true); + case Token::FALSE_TOKEN: + return Value(this, false); case Token::INTEGER: { int64 result_int; if (!base::StringToInt64(value_.value(), &result_int)) { diff --git a/tools/gn/parser.cc b/tools/gn/parser.cc index 567d846..e507dfb 100644 --- a/tools/gn/parser.cc +++ b/tools/gn/parser.cc @@ -57,6 +57,8 @@ ParserHelper Parser::expressions_[] = { {NULL, NULL, -1}, // INVALID {&Parser::Literal, NULL, -1}, // INTEGER {&Parser::Literal, NULL, -1}, // STRING + {&Parser::Literal, NULL, -1}, // TRUE_TOKEN + {&Parser::Literal, NULL, -1}, // FALSE_TOKEN {NULL, &Parser::Assignment, PRECEDENCE_ASSIGNMENT}, // EQUAL {NULL, &Parser::BinaryOperator, PRECEDENCE_SUM}, // PLUS {NULL, &Parser::BinaryOperator, PRECEDENCE_SUM}, // MINUS diff --git a/tools/gn/secondary/build/config/BUILDCONFIG.gn b/tools/gn/secondary/build/config/BUILDCONFIG.gn index 2bca156..78df4e7 100644 --- a/tools/gn/secondary/build/config/BUILDCONFIG.gn +++ b/tools/gn/secondary/build/config/BUILDCONFIG.gn @@ -18,29 +18,29 @@ # "use_*" names for optional features libraries, and configurations. declare_args() { # Set to build the Android version. - is_android = 0 + is_android = false # Component build. - is_component_build = 1 + is_component_build = true # ChromeOS build. - is_chromeos = 0 + is_chromeos = false # Debug build. - is_debug = 1 + is_debug = true # Hello, world # IOS build. - is_ios = 0 + is_ios = false # Set when building with the "untrusted" Native Client toolchain. # # Do not set directly, this will be set automatically when compiling targets # with a NaCl toolchain. - is_nacl = 0 + is_nacl = false # ASH is enabled. - use_ash = 0 + use_ash = false # Aura is enabled. - use_aura = 0 + use_aura = false # Ozone is enabled. - use_ozone = 0 + use_ozone = false } # ============================================================================= diff --git a/tools/gn/secondary/build/toolchain/nacl/BUILD.gn b/tools/gn/secondary/build/toolchain/nacl/BUILD.gn index 75c132b..2e2fc7f 100644 --- a/tools/gn/secondary/build/toolchain/nacl/BUILD.gn +++ b/tools/gn/secondary/build/toolchain/nacl/BUILD.gn @@ -39,17 +39,17 @@ toolchain("x86_newlib") { } toolchain_args() { - is_nacl = 1 + is_nacl = true # Component build not supported in NaCl, since it does not support shared # libraries. - is_component_build = 0 + is_component_build = false # Override the default OS detection. - is_android = 0 - is_mac = 0 - is_posix = 1 - is_linux = 0 - is_win = 0 + is_android = false + is_mac = false + is_posix = true + is_linux = false + is_win = false } } diff --git a/tools/gn/string_utils_unittest.cc b/tools/gn/string_utils_unittest.cc index 81181d2..9e69d40 100644 --- a/tools/gn/string_utils_unittest.cc +++ b/tools/gn/string_utils_unittest.cc @@ -14,7 +14,8 @@ namespace { bool CheckExpansionCase(const char* input, const char* expected, bool success) { Scope scope(static_cast<const Settings*>(NULL)); - scope.SetValue("one", Value(NULL, 1), NULL); + int64 one = 1; + scope.SetValue("one", Value(NULL, one), NULL); scope.SetValue("onestring", Value(NULL, "one"), NULL); // Construct the string token, which includes the quotes. diff --git a/tools/gn/token.h b/tools/gn/token.h index 4af7e62..25f176b 100644 --- a/tools/gn/token.h +++ b/tools/gn/token.h @@ -14,6 +14,8 @@ class Token { INVALID, INTEGER, // 123 STRING, // "blah" + TRUE_TOKEN, // Not "TRUE" to avoid collisions with #define in windows.h. + FALSE_TOKEN, // Various operators. EQUAL, diff --git a/tools/gn/tokenizer.cc b/tools/gn/tokenizer.cc index 6051e1b..6771927 100644 --- a/tools/gn/tokenizer.cc +++ b/tools/gn/tokenizer.cc @@ -115,8 +115,12 @@ std::vector<Token> Tokenizer::Run() { if (type == Token::IDENTIFIER) { if (token_value == "if") type = Token::IF; - if (token_value == "else") + else if (token_value == "else") type = Token::ELSE; + else if (token_value == "true") + type = Token::TRUE_TOKEN; + else if (token_value == "false") + type = Token::FALSE_TOKEN; } // TODO(brettw) This just strips comments from the token stream. This diff --git a/tools/gn/value.cc b/tools/gn/value.cc index 5a595d0..a8abee4 100644 --- a/tools/gn/value.cc +++ b/tools/gn/value.cc @@ -18,15 +18,31 @@ Value::Value(const ParseNode* origin, Type t) origin_(origin) { } +Value::Value(const ParseNode* origin, bool bool_val) + : type_(BOOLEAN), + boolean_value_(bool_val), + int_value_(0), + origin_(origin) { +} + Value::Value(const ParseNode* origin, int64 int_val) : type_(INTEGER), + boolean_value_(false), int_value_(int_val), origin_(origin) { } -Value::Value(const ParseNode* origin, const base::StringPiece& str_val) +Value::Value(const ParseNode* origin, std::string str_val) + : type_(STRING), + string_value_(), + int_value_(0), + origin_(origin) { + string_value_.swap(str_val); +} + +Value::Value(const ParseNode* origin, const char* str_val) : type_(STRING), - string_value_(str_val.as_string()), + string_value_(str_val), int_value_(0), origin_(origin) { } @@ -39,6 +55,8 @@ const char* Value::DescribeType(Type t) { switch (t) { case NONE: return "none"; + case BOOLEAN: + return "boolean"; case INTEGER: return "integer"; case STRING: @@ -51,24 +69,12 @@ const char* Value::DescribeType(Type t) { } } -int64 Value::InterpretAsInt() const { - switch (type_) { - case NONE: - return 0; - case INTEGER: - return int_value_; - case STRING: - return string_value_.empty() ? 0 : 1; - case LIST: - return list_value_.empty() ? 0 : 1; - } - return 0; -} - std::string Value::ToString(bool quote_string) const { switch (type_) { case NONE: return "<void>"; + case BOOLEAN: + return boolean_value_ ? "true" : "false"; case INTEGER: return base::Int64ToString(int_value_); case STRING: @@ -102,6 +108,8 @@ bool Value::operator==(const Value& other) const { return false; switch (type_) { + case Value::BOOLEAN: + return boolean_value() == other.boolean_value(); case Value::INTEGER: return int_value() == other.int_value(); case Value::STRING: diff --git a/tools/gn/value.h b/tools/gn/value.h index c987b6c..952f52a 100644 --- a/tools/gn/value.h +++ b/tools/gn/value.h @@ -17,6 +17,7 @@ class Value { public: enum Type { NONE = 0, + BOOLEAN, INTEGER, STRING, LIST @@ -24,8 +25,10 @@ class Value { Value(); Value(const ParseNode* origin, Type t); + Value(const ParseNode* origin, bool bool_val); Value(const ParseNode* origin, int64 int_val); - Value(const ParseNode* origin, const base::StringPiece& str_val); + Value(const ParseNode* origin, std::string str_val); + Value(const ParseNode* origin, const char* str_val); ~Value(); Type type() const { return type_; } @@ -37,6 +40,15 @@ class Value { const ParseNode* origin() const { return origin_; } void set_origin(const ParseNode* o) { origin_ = o; } + bool& boolean_value() { + DCHECK(type_ == BOOLEAN); + return boolean_value_; + } + const bool& boolean_value() const { + DCHECK(type_ == BOOLEAN); + return boolean_value_; + } + int64& int_value() { DCHECK(type_ == INTEGER); return int_value_; @@ -64,11 +76,6 @@ class Value { return list_value_; } - // Returns the current value converted to an int, normally used for - // boolean operations. Undefined variables, empty lists, and empty strings - // are all interpreted as 0, otherwise 1. - int64 InterpretAsInt() const; - // Converts the given value to a string. Returns true if strings should be // quoted or the ToString of a string should be the string itself. std::string ToString(bool quote_strings) const; @@ -84,6 +91,7 @@ class Value { private: Type type_; std::string string_value_; + bool boolean_value_; int64 int_value_; std::vector<Value> list_value_; const ParseNode* origin_; |