Skip to content

Commit

Permalink
Script.IsTruthy, IsFalsey and Or (to replace Value) to fix issue #358
Browse files Browse the repository at this point in the history
  • Loading branch information
nikhilk committed Apr 18, 2013
1 parent fc264cc commit 18f37b7
Show file tree
Hide file tree
Showing 7 changed files with 79 additions and 28 deletions.
22 changes: 15 additions & 7 deletions src/Core/Compiler/Compiler/ExpressionBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -540,12 +540,7 @@ private Expression ProcessDotExpressionNode(BinaryExpressionNode node, SymbolFil
}

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);
Expand Down Expand Up @@ -1115,9 +1110,22 @@ private Expression ProcessOpenParenExpressionNode(BinaryExpressionNode node) {
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];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
44 changes: 32 additions & 12 deletions src/Core/CoreLib/Script.cs
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,16 @@ public static T InvokeMethod<T>(Type type, string name, params object[] args) {
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;
Expand Down Expand Up @@ -186,6 +196,16 @@ public static bool IsValue(object o) {
return false;
}

/// <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
Expand All @@ -198,6 +218,18 @@ public static object Literal(string script, params object[] args) {
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) {
}

Expand Down Expand Up @@ -253,17 +285,5 @@ public static int SetTimeout<T1, T2>(Action<T1, T2> callback, int milliseconds,
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);
}
}
}
20 changes: 15 additions & 5 deletions tests/TestCases/Basic/Metadata/Baseline.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down
5 changes: 5 additions & 0 deletions tests/TestCases/Expression/Script/Baseline.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
11 changes: 8 additions & 3 deletions tests/TestCases/Expression/Script/Code.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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));
Expand All @@ -29,6 +29,11 @@ public void Test(int arg) {
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");

Expand Down
2 changes: 1 addition & 1 deletion tests/TestCases/Library/Node/Code.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@ static 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.