Browse files

Script.IsTruthy, IsFalsey and Or (to replace Value) to fix issue #358

  • Loading branch information...
1 parent fc264cc commit 18f37b7da8b998c9d7046125baff17470b029ea2 @nikhilk committed Apr 18, 2013
View
22 src/Core/Compiler/Compiler/ExpressionBuilder.cs
@@ -540,12 +540,7 @@ internal sealed class ExpressionBuilder {
}
if (objectExpression is LiteralExpression) {
- object literalValue = ((LiteralExpression)objectExpression).Value;
- if (!((literalValue is Boolean) || (literalValue is String))) {
- // Numeric literals need to be paranthesized in script when followed by a
- // dot member access.
- objectExpression.AddParenthesisHint();
- }
+ objectExpression.AddParenthesisHint();
}
Debug.Assert(objectExpression.EvaluatedType is ISymbolTable);
@@ -1115,9 +1110,22 @@ MethodExpression methodExpression
else if (method.Name.Equals("Boolean", StringComparison.Ordinal)) {
Debug.Assert(args.Count == 1);
+ args[0].AddParenthesisHint();
+ return new UnaryExpression(Operator.LogicalNot, new UnaryExpression(Operator.LogicalNot, args[0]));
+ }
+ else if (method.Name.Equals("IsTruthy", StringComparison.Ordinal)) {
+ Debug.Assert(args.Count == 1);
+
+ args[0].AddParenthesisHint();
return new UnaryExpression(Operator.LogicalNot, new UnaryExpression(Operator.LogicalNot, args[0]));
}
- else if (method.Name.Equals("Value", StringComparison.Ordinal)) {
+ else if (method.Name.Equals("IsFalsey", StringComparison.Ordinal)) {
+ Debug.Assert(args.Count == 1);
+
+ args[0].AddParenthesisHint();
+ return new UnaryExpression(Operator.LogicalNot, args[0]);
+ }
+ else if (method.Name.Equals("Or", StringComparison.Ordinal)) {
Debug.Assert(args.Count >= 2);
Expression expr = args[0];
View
3 src/Core/Compiler/ScriptModel/Expressions/LiteralExpression.cs
@@ -23,6 +23,9 @@ public LiteralExpression(TypeSymbol valueType, object value)
protected override bool IsParenthesisRedundant {
get {
+ // Numeric literals need to be paranthesized in script when followed by a
+ // dot member access, so it is not redundant for numbers.
+
if ((_value is String) || (_value is Boolean)) {
return true;
}
View
44 src/Core/CoreLib/Script.cs
@@ -131,6 +131,16 @@ public static class Script {
return default(T);
}
+ /// <summary>
+ /// Checks if the specified object has a falsey value, i.e. it is null or
+ /// undefined or empty string or false or zero.
+ /// </summary>
+ /// <param name="o">The object to test.</param>
+ /// <returns>true if the object represents a falsey value; false otherwise.</returns>
+ public static bool IsFalsey(object o) {
+ return false;
+ }
+
[ScriptAlias("isFinite")]
public static bool IsFinite(object o) {
return false;
@@ -187,6 +197,16 @@ public static class Script {
}
/// <summary>
+ /// Checks if the specified object has a truthy value, i.e. it is not
+ /// null or undefined or empty string or false or zero.
+ /// </summary>
+ /// <param name="o">The object to test.</param>
+ /// <returns>true if the object represents a truthy value; false otherwise.</returns>
+ public static bool IsTruthy(object o) {
+ return false;
+ }
+
+ /// <summary>
/// Enables you to generate an arbitrary (literal) script expression.
/// The script can contain simple String.Format style tokens (such as
/// {0}, {1}, ...) to be replaced with the specified arguments.
@@ -198,6 +218,18 @@ public static class Script {
return null;
}
+ /// <summary>
+ /// Gets the first truthy (true, non-null, non-undefined, non-empty, non-zero) value.
+ /// </summary>
+ /// <typeparam name="TValue">The type of the value.</typeparam>
+ /// <param name="value">The value to check for validity.</param>
+ /// <param name="alternateValue">The alternate value to use if the first is invalid.</param>
+ /// <param name="alternateValues">Additional alternative values to use if the first is invalid.</param>
+ /// <returns>The first valid value.</returns>
+ public static TValue Or<TValue>(TValue value, TValue alternateValue, params TValue[] alternateValues) {
+ return default(TValue);
+ }
+
public static void SetField(object instance, string name, object value) {
}
@@ -253,17 +285,5 @@ public static class Script {
public static int SetTimeout(Delegate d, int milliseconds, params object[] args) {
return 0;
}
-
- /// <summary>
- /// Gets the first valid (non-null, non-undefined, non-empty) value.
- /// </summary>
- /// <typeparam name="TValue">The type of the value.</typeparam>
- /// <param name="value">The value to check for validity.</param>
- /// <param name="alternateValue">The alternate value to use if the first is invalid.</param>
- /// <param name="alternateValues">Additional alternative values to use if the first is invalid.</param>
- /// <returns>The first valid value.</returns>
- public static TValue Value<TValue>(TValue value, TValue alternateValue, params TValue[] alternateValues) {
- return default(TValue);
- }
}
}
View
20 tests/TestCases/Basic/Metadata/Baseline.txt
@@ -1513,6 +1513,11 @@ Types:
Visibility: Public, Static
Generated Name: invokeMethod
Abstract: False
+ Method: IsFalsey
+ AssociatedType: Boolean
+ Visibility: Public, Static
+ Generated Name: isFalsey
+ Abstract: False
Method: IsFinite
AssociatedType: Boolean
Visibility: Public, Static
@@ -1543,11 +1548,21 @@ Types:
Visibility: Public, Static
Generated Name: ss.isValue
Abstract: False
+ Method: IsTruthy
+ AssociatedType: Boolean
+ Visibility: Public, Static
+ Generated Name: isTruthy
+ Abstract: False
Method: Literal
AssociatedType: Object
Visibility: Public, Static
Generated Name: literal
Abstract: False
+ Method: Or
+ AssociatedType: TValue
+ Visibility: Public, Static
+ Generated Name: or
+ Abstract: False
Method: SetField
AssociatedType: Void
Visibility: Public, Static
@@ -1563,11 +1578,6 @@ Types:
Visibility: Public, Static
Generated Name: setTimeout
Abstract: False
- Method: Value
- AssociatedType: TValue
- Visibility: Public, Static
- Generated Name: value
- Abstract: False
Method: Enumerate
AssociatedType: Object
Visibility: Public, Static
View
5 tests/TestCases/Expression/Script/Baseline.txt
@@ -27,6 +27,11 @@ define('test', ['ss'], function(ss) {
b = ss.isValue(i);
b = isNaN(0);
b = isFinite(3);
+ b = !!(0);
+ b = !!b;
+ b = !!(b && b);
+ b = !(1);
+ b = !(b && b);
var addition = eval('2 + 2');
addition = 2 + 2;
addition = 2 + 3;
View
11 tests/TestCases/Expression/Script/Code.cs
@@ -8,9 +8,9 @@ namespace ExpressionTests {
public class App {
public void Test(int arg) {
- arg = Script.Value(arg, 10);
- arg = Script.Value(arg, 10, 100);
- string s = Script.Value(arg, 10).ToString(10);
+ arg = Script.Or(arg, 10);
+ arg = Script.Or(arg, 10, 100);
+ string s = Script.Or(arg, 10).ToString(10);
bool b = Script.Boolean(arg);
StringBuilder sb = (StringBuilder)Script.CreateInstance(typeof(StringBuilder));
@@ -29,6 +29,11 @@ public class App {
b = Script.IsValue(i);
b = Script.IsNaN(0);
b = Script.IsFinite(3);
+ b = Script.IsTruthy(0);
+ b = Script.IsTruthy(b);
+ b = Script.IsTruthy(b && b);
+ b = Script.IsFalsey(1);
+ b = Script.IsFalsey(b && b);
int addition = (int)Script.Eval("2 + 2");
View
2 tests/TestCases/Library/Node/Code.cs
@@ -23,6 +23,6 @@ internal static class App {
response.WriteHead(HttpStatusCode.OK,
new Dictionary<string, string>("Content-Type", "text/html"));
response.End("Hello Node World, from Script#!");
- }).Listen(Script.Value(Node.Process.Environment["port"], 8888));
+ }).Listen(Script.Or(Node.Process.Environment["port"], 8888));
}
}

0 comments on commit 18f37b7

Please sign in to comment.