2005-07-02 Florian Gross <flgr@ccan.de>
authorCésar Natarén <cesar@mono-cvs.ximian.com>
Sat, 2 Jul 2005 03:39:02 +0000 (03:39 -0000)
committerCésar Natarén <cesar@mono-cvs.ximian.com>
Sat, 2 Jul 2005 03:39:02 +0000 (03:39 -0000)
* ArrayPrototype.cs: Implemented pop, reverse, shift and slice
* StringPrototype.cs: Implemented anchor, big, blink, bold, charAt,
charCodeAt, fixed, fontcolor, fontsize, indexOf, italics, lastIndexOf,
link, localeCompare, slice, small, strike, substring, sup,
toLocaleLowerCase, toLocaleUpperCase, toLowerCase, toString, toUpperCase
and valueOf
* ArrayObject.cs: ArrayObject-ctor works correctly when first argument
isn't length and first element gets assigned to 0 slot correctly
* NumberObject.cs: Basic constructor / double value made internal
* Equality.cs: Added basic logic for TypeCode.Empty, DBNull, Boolean and
Char
* FunctionObject.cs: ToString matches that of MS JS.NET for internal
functions
* Convert.cs: IsNumberTypeCode and IsFloatTypeCode utility methods, basic
implementation of ToInt32 and ToNumber, more cases for ToString
* StrictEquality.cs: Initial working implementation
* LateBindings.cs: Call works for Methods that don't have HasEngine and
support for getting methods (as in "foo".link) in GetNonMissingValue
* Plus.cs: Added support for more types
* GlobalObject.cs: Implemented isNaN, isFinite and parseFloat
* FunctionPrototype.cs: Implemented toString
* NumberPrototype.cs: Implemented valueOf
* Globals.cs: Implemented ConstructArrayLiteral
* TypeOf.cs: Added more cases

svn path=/trunk/mcs/; revision=46869

15 files changed:
mcs/class/Microsoft.JScript/Microsoft.JScript/ArrayObject.cs
mcs/class/Microsoft.JScript/Microsoft.JScript/ArrayPrototype.cs
mcs/class/Microsoft.JScript/Microsoft.JScript/Convert.cs
mcs/class/Microsoft.JScript/Microsoft.JScript/Equality.cs
mcs/class/Microsoft.JScript/Microsoft.JScript/FunctionObject.cs
mcs/class/Microsoft.JScript/Microsoft.JScript/FunctionPrototype.cs
mcs/class/Microsoft.JScript/Microsoft.JScript/GlobalObject.cs
mcs/class/Microsoft.JScript/Microsoft.JScript/Globals.cs
mcs/class/Microsoft.JScript/Microsoft.JScript/LateBinding.cs
mcs/class/Microsoft.JScript/Microsoft.JScript/NumberObject.cs
mcs/class/Microsoft.JScript/Microsoft.JScript/NumberPrototype.cs
mcs/class/Microsoft.JScript/Microsoft.JScript/Plus.cs
mcs/class/Microsoft.JScript/Microsoft.JScript/StrictEquality.cs
mcs/class/Microsoft.JScript/Microsoft.JScript/StringPrototype.cs
mcs/class/Microsoft.JScript/Microsoft.JScript/TypeOf.cs

index 13e92e3911abddb9d9e9be8a74e37a976dae2b52..c960f27028e121480bb898773663ef034b9981b6 100644 (file)
@@ -30,7 +30,7 @@
 
 using System;
 using System.Collections;
+
 namespace Microsoft.JScript {
 
        public class ArrayObject : JSObject {
@@ -46,22 +46,26 @@ namespace Microsoft.JScript {
                {
                        length = 0;
                }
-               
+
                internal ArrayObject (object o)
                {
                        IConvertible ic = o as IConvertible;
                        TypeCode tc = ic.GetTypeCode ();
 
-                       if (tc == TypeCode.Int32 || ic.ToDouble (null) < Int32.MaxValue) {
-                               int size = ic.ToInt32 (null);
-                               if (size > 0)
-                                       length = o;
-                               else 
-                                       throw new JScriptException (JSError.ArrayLengthConstructIncorrect);
-                       } else {
-                               elems = new Hashtable ();
-                               elems.Add (o, o);
-                       }
+                       try {
+                               if (tc == TypeCode.Int32 || ic.ToDouble (null) < Int32.MaxValue) {
+                                       int size = ic.ToInt32 (null);
+                                       if (size > 0) {
+                                               length = o;
+                                               return;
+                                       } else
+                                               throw new JScriptException (JSError.ArrayLengthConstructIncorrect);
+                               }
+                       } catch (FormatException) { /* OK */ }
+
+                       elems = new Hashtable ();
+                       length = 1;
+                       elems.Add (0, o);
                }
 
                internal ArrayObject (params object [] args)
index 40bd26911e367f29e63f1b887d355756fb762ede..59a250ed2ae3c196e45cc8dad1868e969ab6c5f7 100644 (file)
@@ -53,18 +53,20 @@ namespace Microsoft.JScript {
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Array_join)]
                public static string join (object thisObj, object separator)
                {
+                       // TODO: Shouldn't this be generic!?
                        SemanticAnalyser.assert_type (thisObj, typeof (ArrayObject));
                        ArrayObject array_obj = (ArrayObject) thisObj;
-                       
+
                        string _separator;
                        if (separator == null)
                                _separator = ",";
-                       else 
+                       else
                                _separator = Convert.ToString (separator);
 
                        Hashtable elems = array_obj.Elements;
                        StringBuilder str = new StringBuilder ();
                        bool first = true;
+
                        foreach (DictionaryEntry entry in elems) {
                                if (!first)
                                        str.Append (_separator);
@@ -77,7 +79,21 @@ namespace Microsoft.JScript {
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Array_pop)]
                public static object pop (object thisObj)
                {
-                       throw new NotImplementedException ();
+                       // TODO: Shouldn't this be generic!?
+                       SemanticAnalyser.assert_type (thisObj, typeof (ArrayObject));
+                       ArrayObject array_obj = (ArrayObject) thisObj;
+
+                       int n = (int) array_obj.length;
+                       if (n > 0) {
+                               int new_len = n - 1;
+                               array_obj.length = new_len;
+                               if (array_obj.elems.ContainsKey (new_len)) {
+                                       object result = array_obj.elems [new_len];
+                                       array_obj.elems.Remove (new_len);
+                                       return result;
+                               }
+                       }
+                       return null;
                }
 
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject | JSFunctionAttributeEnum.HasVarArgs, JSBuiltin.Array_push)]
@@ -89,20 +105,83 @@ namespace Microsoft.JScript {
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Array_reverse)]
                public static object reverse (object thisObj)
                {
-                       throw new NotImplementedException ();
+                       // TODO: Shouldn't this be generic!?
+                       SemanticAnalyser.assert_type (thisObj, typeof (ArrayObject));
+                       ArrayObject array_obj = (ArrayObject) thisObj;
+
+                       int n = (int) array_obj.length;
+                       int half_n = n / 2;
+                       int j = n - 1;
+                       object temp;
+                       
+                       for (int i = 0; i < half_n; i++, j--) {
+                               temp = array_obj.elems [i];
+                               array_obj.elems [i] = array_obj.elems [j];
+                               array_obj.elems [j] = temp;
+                       }
+                       return array_obj;
                }
 
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Array_shift)]
                public static object shift (object thisObj)
                {
-                       throw new NotImplementedException ();
+                       // TODO: Shouldn't this be generic!?
+                       SemanticAnalyser.assert_type (thisObj, typeof (ArrayObject));
+                       ArrayObject array_obj = (ArrayObject) thisObj;
+
+                       int n = (int) array_obj.length;
+                       if (n > 0) {
+                               array_obj.length = n - 1;
+                               if (array_obj.elems.ContainsKey (0)) {
+                                       object result = array_obj.elems [0];
+                                       array_obj.elems.Remove (0);
+                                       for (int i = 1; i < n; i++)
+                                               array_obj.elems [i - 1] = array_obj.elems [i];
+                                       array_obj.elems.Remove (n - 1);
+                                       return result;
+                               }
+                       }
+                       return null;
                }
 
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject | JSFunctionAttributeEnum.HasEngine, JSBuiltin.Array_slice)]
-               public static ArrayObject slice (object thisObj, VsaEngine engine,
-                                                double start, object end)
+               public static ArrayObject slice (object thisObj, VsaEngine engine, double start, object end)
                {
-                       throw new NotImplementedException ();
+                       // TODO: Shouldn't this be generic!?
+                       SemanticAnalyser.assert_type (thisObj, typeof (ArrayObject));
+                       ArrayObject array_obj = (ArrayObject) thisObj;
+                       int array_len = (int) array_obj.length;
+                       int _start, _end;
+
+                       if (start > array_len)
+                               _start = array_len;
+                       else {
+                               _start = (int) start;
+                               if (_start < 0)
+                                       _start += array_len;
+                       }
+
+                       if (end == null)
+                               _end = array_len;
+                       else {
+                               _end = (int) (double) end;
+
+                               if (_end < 0)
+                                       _end += array_len;
+                               else if (_end > array_len)
+                                       _end = array_len;
+                       }
+
+                       if (_end < _start)
+                               _end = _start;
+
+                       ArrayObject result = new ArrayObject();
+                       result.length = _end - _start;
+
+                       for (int i = _start; i < _end; i++)
+                               result.elems [i - _start] = array_obj.elems [i];
+
+                       return result;
                }
 
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Array_sort)]
index 02b0407e4743b7cd064d7fd2069038af21c5ae44..c65b368d204aeb4efd5b9741cd4a0da6330ede1f 100644 (file)
@@ -42,6 +42,34 @@ namespace Microsoft.JScript {
                        throw new NotImplementedException ();
                }
 
+               internal static bool IsNumberTypeCode (TypeCode tc)
+               {
+                       switch (tc) {
+                       case TypeCode.Byte:
+                       case TypeCode.Char:
+                       case TypeCode.Double:
+                       case TypeCode.Int16:
+                       case TypeCode.Int32:
+                       case TypeCode.SByte:
+                       case TypeCode.Single:
+                       case TypeCode.UInt16:
+                       case TypeCode.UInt32:
+                               return true;
+                       default:
+                               return false;
+                       }
+               }
+
+               internal static bool IsFloatTypeCode (TypeCode tc)
+               {
+                       switch (tc) {
+                       case TypeCode.Double:
+                       case TypeCode.Single:
+                               return true;
+                       default:
+                               return false;
+                       }
+               }
 
                public static double CheckIfDoubleIsInteger (double d)
                {
@@ -71,8 +99,8 @@ namespace Microsoft.JScript {
                }
 
 
-               public static object Coerce2 (object value, TypeCode target, 
-                                             bool truncationPermitted)
+               public static object Coerce2 (object value, TypeCode target,
+                                                 bool truncationPermitted)
                {
                        throw new NotImplementedException ();
                }
@@ -112,12 +140,58 @@ namespace Microsoft.JScript {
 
                public static int ToInt32 (object value)
                {
+                       IConvertible ic = value as IConvertible;
+                       TypeCode tc = Convert.GetTypeCode (value, ic);
+
+                       switch (tc) {
+                       case TypeCode.Char:
+                       case TypeCode.Byte:
+                       case TypeCode.SByte:
+                       case TypeCode.UInt16:
+                       case TypeCode.UInt32:
+                       case TypeCode.Int16:
+                       case TypeCode.Int32:
+                               return (int) value;
+
+                       case TypeCode.Single:
+                       case TypeCode.Double:
+                               return (int) Math.Floor ((double) value);
+
+                       default:
+                               Console.WriteLine ("\nToInt32: value.GetType = {0}", value.GetType ());
+                               break;
+                       }
                        throw new NotImplementedException ();
                }
 
 
                public static double ToNumber (object value)
                {
+                       IConvertible ic = value as IConvertible;
+                       TypeCode tc = Convert.GetTypeCode (value, ic);
+
+                       switch (tc) {
+                       case TypeCode.Char:
+                       case TypeCode.Byte:
+                       case TypeCode.SByte:
+                       case TypeCode.UInt16:
+                       case TypeCode.UInt32:
+                       case TypeCode.Int16:
+                       case TypeCode.Int32:
+                               return (double) value;
+
+                       case TypeCode.Single:
+                       case TypeCode.Double:
+                               return (double) value;
+
+                       case TypeCode.String:
+                               return GlobalObject.parseFloat (value);
+
+                       default:
+                               Console.WriteLine ("\nToNumber: value.GetType = {0}", value.GetType ());
+                               break;
+                       }
+
                        throw new NotImplementedException ();
                }
 
@@ -135,13 +209,23 @@ namespace Microsoft.JScript {
 
 
                public static object ToObject (object value, VsaEngine engine)
-               {                       
+               {
                        IConvertible ic = value as IConvertible;
                        TypeCode tc = Convert.GetTypeCode (value, ic);
 
                        switch (tc) {
                        case TypeCode.String:
                                return new StringObject (ic.ToString (null));
+                       case TypeCode.Single:
+                       case TypeCode.Double:
+                       case TypeCode.Char:
+                       case TypeCode.Byte:
+                       case TypeCode.SByte:
+                       case TypeCode.UInt16:
+                       case TypeCode.UInt32:
+                       case TypeCode.Int16:
+                       case TypeCode.Int32:
+                               return new NumberObject (ic.ToDouble (null));
                        case TypeCode.Object:
                                return value;
                        default:
@@ -171,6 +255,9 @@ namespace Microsoft.JScript {
                        TypeCode tc = Convert.GetTypeCode (value, ic);
 
                        switch (tc) {
+                       case TypeCode.Empty:
+                               return "";
+
                        case TypeCode.DBNull:
                                return "null";
 
@@ -180,7 +267,16 @@ namespace Microsoft.JScript {
                                        return "true";
                                else
                                        return "false";
-                               
+
+                       case TypeCode.Char:
+                               return ic.ToInt16 (null).ToString ();
+
+                       case TypeCode.Byte:
+                       case TypeCode.SByte:
+                       case TypeCode.UInt16:
+                       case TypeCode.UInt32:
+                       case TypeCode.Int16:
+                       case TypeCode.Int32:
                        case TypeCode.String:
                        case TypeCode.Double:
                                return ic.ToString (null);
@@ -204,6 +300,8 @@ namespace Microsoft.JScript {
                                        return RegExpPrototype.toString (value);
                                else if (value is StringObject)
                                        return StringPrototype.toString (value);
+                               else if (value is FunctionWrapper)
+                                       return FunctionPrototype.toString (value);
                                Console.WriteLine ("value.GetType = {0}", value.GetType ());
                                throw new NotImplementedException ();
                        default:
@@ -220,7 +318,7 @@ namespace Microsoft.JScript {
 
 
                public static string ToString (double d)
-               {       
+               {
                        IConvertible ic = d as IConvertible;
                        return ic.ToString (null);
                }
@@ -234,8 +332,8 @@ namespace Microsoft.JScript {
                                return TypeCode.Empty;
                        else if (ic == null)
                                return TypeCode.Object;
-                       else 
-                               return  ic.GetTypeCode ();
+                       else
+                               return ic.GetTypeCode ();
                }
        }
 }
index c5a36f0b4a7042764d9266735bdaee4e8547025c..902ff438b1e2db00796758b73c90c57ddbd109b3 100644 (file)
@@ -59,6 +59,40 @@ namespace Microsoft.JScript {
                        TypeCode tc2 = Convert.GetTypeCode (v2, ic2);
 
                        switch (tc1) {
+                       case TypeCode.Empty:
+                               switch (tc2) {
+                               case TypeCode.Empty:
+                                       return true;
+                               case TypeCode.DBNull:
+                                       return true;
+                               }
+                               break;
+
+                       case TypeCode.DBNull:
+                               switch (tc1) {
+                               case TypeCode.DBNull:
+                                       return true;
+                               case TypeCode.Empty:
+                                       return true;
+                               }
+                               break;
+
+                       case TypeCode.Boolean:
+                               switch (tc1) {
+                               case TypeCode.Boolean:
+                                       return ic1.ToBoolean (null) == ic2.ToBoolean (null);
+                               }
+                               break;
+
+                       case TypeCode.Char:
+                               switch (tc2) {
+                               case TypeCode.Char:
+                                       return ic1.ToChar (null) == ic2.ToChar (null);
+                               case TypeCode.Double:
+                                       return (double) ic1.ToChar (null) == ic2.ToDouble (null);
+                               }
+                               break;
+
                        case TypeCode.Double:
                                switch (tc2) {
                                case TypeCode.Double:
@@ -108,8 +142,8 @@ namespace Microsoft.JScript {
                internal override bool Resolve (IdentificationTable context, bool no_effect)
                {
                        this.no_effect = no_effect;
-                       return  Resolve (context);
-               }              
+                       return Resolve (context);
+               }
 
                internal override void Emit (EmitContext ec)
                {
@@ -117,13 +151,13 @@ namespace Microsoft.JScript {
                        LocalBuilder local_builder;
 
                        if (op != JSToken.None) {
-                               Type t = typeof (Equality);                             
+                               Type t = typeof (Equality);
                                local_builder = ig.DeclareLocal (t);
                                if (op == JSToken.Equal)
                                        ig.Emit (OpCodes.Ldc_I4_S, (byte) 53);
                                else if (op == JSToken.NotEqual)
                                        ig.Emit (OpCodes.Ldc_I4_S, (byte) 54);
-                               ig.Emit (OpCodes.Newobj, t.GetConstructor (new Type [] {typeof (int)}));
+                               ig.Emit (OpCodes.Newobj, t.GetConstructor (new Type [] { typeof (int) }));
                                ig.Emit (OpCodes.Stloc, local_builder);
                                ig.Emit (OpCodes.Ldloc, local_builder);
                        }
@@ -131,8 +165,8 @@ namespace Microsoft.JScript {
                        if (left != null)
                                left.Emit (ec);
                        if (right != null)
-                               right.Emit (ec);                               
-                       
+                               right.Emit (ec);
+
                        if (op == JSToken.Equal || op == JSToken.NotEqual) {
                                ig.Emit (OpCodes.Call, typeof (Equality).GetMethod ("EvaluateEquality"));
 
@@ -144,14 +178,14 @@ namespace Microsoft.JScript {
                                                ig.Emit (OpCodes.Brtrue_S, t_lbl);
                                        else if (op == JSToken.NotEqual)
                                                ig.Emit (OpCodes.Brfalse_S, t_lbl);
-                                       
+
                                        ig.Emit (OpCodes.Ldc_I4_0);
                                        ig.Emit (OpCodes.Br_S, f_lbl);
                                        ig.MarkLabel (t_lbl);
                                        ig.Emit (OpCodes.Ldc_I4_1);
                                        ig.MarkLabel (f_lbl);
                                        ig.Emit (OpCodes.Pop);
-                               }                               
+                               }
                        }
                }
        }
index 332ce4286fc5679b15152863dd5cc16d95d95225..bbc82b46a5ea17d3de997d99d7aa53b25b7fd6e2 100644 (file)
@@ -82,20 +82,23 @@ namespace Microsoft.JScript {
                        StringBuilder sb = new StringBuilder ();
 
                        sb.Append ("function ");
-                       sb.Append (name + " ");
+                       sb.Append (name);
                        sb.Append ("(");
 
                        if (parameters != null)
                                sb.Append (this.parameters.ToString ());
                                        
                        sb.Append (")");
-                       sb.Append (" : " + return_type);
-                       sb.Append ("{");
+                       if (return_type != null)
+                               sb.Append (" : " + return_type);
+                       sb.Append (" {\n");
 
                        if (body != null)
                                sb.Append (body.ToString ());
+                       else
+                               sb.Append ("    [native code]");
 
-                       sb.Append ("}");
+                       sb.Append ("\n}");
 
                        return sb.ToString ();          
                }
index 3ebdc8a14be47732e1844aa424c849d6c6a2d1d4..177eb34e2f292a6fae7317c8e8b6dd9098993ec8 100644 (file)
@@ -54,6 +54,8 @@ namespace Microsoft.JScript {
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Function_toString)]
                public static string toString (object thisObj)
                {
+                       if (thisObj is FunctionObject)
+                               return (((FunctionObject) thisObj).ToString ());
                        throw new NotImplementedException ();
                }
        }
index c9f7539d66e6136c69216a0ac31bb94084c3556d..77b11bf7c22521098abbd50d784403724464cea2 100644 (file)
@@ -29,6 +29,7 @@
 
 using System;
 using System.Text;
+using System.Globalization;
 
 namespace Microsoft.JScript {
 
@@ -393,13 +394,14 @@ namespace Microsoft.JScript {
                [JSFunctionAttribute (0, JSBuiltin.Global_isNaN)]
                public static bool isNaN (Object num)
                {
-                       throw new NotImplementedException ();
+                       double number = Convert.ToNumber (num);
+                       return Double.IsNaN (number);
                }
 
                [JSFunctionAttribute(0, JSBuiltin.Global_isFinite)]
                public static bool isFinite (double number)
                {
-                       throw new NotImplementedException ();
+                       return !Double.IsInfinity (number) && !Double.IsNaN (number);
                }
 
                public static Type @long {
@@ -421,7 +423,17 @@ namespace Microsoft.JScript {
                [JSFunctionAttribute (0, JSBuiltin.Global_parseFloat)]
                public static double parseFloat (Object @string)
                {
-                       throw new NotImplementedException ();
+                       string string_obj = Convert.ToString (@string);
+                       double result;
+
+                       if (Double.TryParse (string_obj, NumberStyles.Float, null, out result))
+                               return result;
+                       else if (string_obj.StartsWith ("Infinity") || string_obj.StartsWith ("+Infinity"))
+                               return Double.PositiveInfinity;
+                       else if (string_obj.StartsWith ("-Infinity"))
+                               return Double.NegativeInfinity;
+                       else
+                               return Double.NaN;
                }
 
                [JSFunctionAttribute (0, JSBuiltin.Global_parseInt)]
index 8b4626d8fe53969d52b20a6136bde797eead55a0..68a0f5f7fc8a1d0884e3188342f9bee7a311999f 100644 (file)
@@ -33,9 +33,7 @@ using Microsoft.JScript.Vsa;
 
 namespace Microsoft.JScript {
 
-
-       public sealed class Globals
-       {
+       public sealed class Globals {
                public static VsaEngine contextEngine;
 
        
@@ -47,7 +45,7 @@ namespace Microsoft.JScript {
 
                public static ArrayObject ConstructArrayLiteral (object [] args)
                {
-                       throw new NotImplementedException ();
+                       return new ArrayObject (args);
                }
        }
 }
index 511892095cd988165716eb697c0d4d83b7d1627d..e8b0a26d61adff69cb6c0f93aef0085d59ca95be 100644 (file)
@@ -42,7 +42,7 @@ namespace Microsoft.JScript {
                public object obj;
                private static BindingFlags bind_flags = BindingFlags.Public;
                private string right_hand_side;
-                       
+
                public LateBinding (string name)
                {
                        this.right_hand_side = name;
@@ -58,10 +58,10 @@ namespace Microsoft.JScript {
                [DebuggerStepThroughAttribute]
                [DebuggerHiddenAttribute]
                public object Call (object [] arguments, bool construct, bool brackets,
-                                   VsaEngine engine)
+                                       VsaEngine engine)
                {
                        if (construct) {
-                               if (brackets) {                                 
+                               if (brackets) {
                                } else {
                                }
                        } else {
@@ -73,7 +73,29 @@ namespace Microsoft.JScript {
                                                type = SemanticAnalyser.map_to_prototype ((JSObject) obj);
 
                                        MethodInfo method = type.GetMethod (right_hand_side, BindingFlags.Public | BindingFlags.Static);
-                                       object [] args = build_args (arguments, engine);
+                                       JSFunctionAttribute [] custom_attrs = (JSFunctionAttribute [])
+                                               method.GetCustomAttributes (typeof (JSFunctionAttribute), true);
+                                       //
+                                       // We need to iterate through the JSFunctionAttributes to find out whether the function wants
+                                       // to get passed the vsaEngine or not so we can pass the right arguments to it.
+                                       //
+                                       object [] args = null;
+                                       foreach (JSFunctionAttribute attr in custom_attrs)
+                                               if ((attr.GetAttributeValue () & JSFunctionAttributeEnum.HasEngine) != 0) {
+                                                       args = build_args (arguments, engine);
+                                                       break;
+                                               }
+
+                                       if (args == null)
+                                               args = build_args (arguments, null);
+
+                                       // TODO: Debug logging should be removed
+                                       string arg_str = "";
+                                       foreach (object arg in args)
+                                               arg_str += arg.GetType ().ToString () + ", ";
+
+                                       //System.Console.WriteLine("\nInvoking {0}.{1} with args {2}", obj.GetType(), method.Name, arg_str);
+
                                        return method.Invoke (type, args);
                                }
                        }
@@ -91,7 +113,7 @@ namespace Microsoft.JScript {
                                args.Add (o);
                        return args.ToArray ();
                }
-               
+
                [DebuggerStepThroughAttribute]
                [DebuggerHiddenAttribute]
                public static object CallValue (object thisObj, object val, object [] arguments,
@@ -100,7 +122,7 @@ namespace Microsoft.JScript {
                        if (construct) {
                                if (brackets) {
                                        return null;
-                               } 
+                               }
                                return null;
                        } else if (brackets) {
                                if (!(val is JSObject))
@@ -108,9 +130,9 @@ namespace Microsoft.JScript {
 
                                JSObject js_val = (JSObject) val;
                                object res = js_val.GetField (Convert.ToString (arguments [0]));
-                               if (res is JSFieldInfo) 
+                               if (res is JSFieldInfo)
                                        return ((JSFieldInfo) res).GetValue (arguments [0]);
-                               else 
+                               else
                                        throw new NotImplementedException ();
                        } else {
                                return null;
@@ -142,6 +164,9 @@ namespace Microsoft.JScript {
                public object GetNonMissingValue ()
                {
                        Type type = obj.GetType ();
+                       if (obj is JSObject)
+                               type = SemanticAnalyser.map_to_prototype ((JSObject) obj);
+
                        MemberInfo [] members = type.GetMember (right_hand_side);
                        if (members.Length > 0) {
                                MemberInfo member = members [0];
@@ -150,7 +175,12 @@ namespace Microsoft.JScript {
                                switch (member_type) {
                                case MemberTypes.Property:
                                        MethodInfo method = ((PropertyInfo) member).GetGetMethod ();
-                                       return method.Invoke (obj, new object [] {});
+                                       return method.Invoke (obj, new object [] { });
+                               case MemberTypes.Method:
+                                       return new FunctionObject (((MethodInfo) member).Name);
+                               default:
+                                       System.Console.WriteLine ("GetNonMissingValue: type = {0}, member_type = {1}", type, member_type);
+                                       break;
                                }
                        }
                        throw new NotImplementedException ();
index f15039718155610e5694c211891748719c2cf7f3..e2811b4b57b82707ecff1398f65b24d7d465b27d 100644 (file)
@@ -32,8 +32,8 @@ using System;
 namespace Microsoft.JScript {
        
        public class NumberObject : JSObject {
-               
-               double value;
+
+               internal double value;
 
                internal NumberObject ()
                {
@@ -41,7 +41,7 @@ namespace Microsoft.JScript {
 
                internal NumberObject (object value)
                {
-                       throw new NotImplementedException ();
+                       this.value = (double) value;
                }
 
                public new Type GetType ()
index 15483e886df7ce6e2ad16289a76d108580077290..c1d559dcf1ddff9e8de182188851ef2e6b4b8813 100644 (file)
@@ -71,7 +71,9 @@ namespace Microsoft.JScript {
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject, JSBuiltin.Number_valueOf)]
                public static object valueOf (object thisObj)
                {
-                       throw new NotImplementedException ();
+                       SemanticAnalyser.assert_type (thisObj, typeof (NumberObject));
+                       NumberObject no = thisObj as NumberObject;
+                       return no.value;
                }
        }
 }
index f86d420835bb00dd9d851cc0140d8ac909031d16..2dbc1f3e2b00ff4afc176432bbb4bfd3d120e627 100644 (file)
@@ -67,9 +67,23 @@ namespace Microsoft.JScript {
                                case TypeCode.Boolean:
                                        return ic1.ToString (null) + Convert.ToString (ic2.ToBoolean (null));
 
+                               case TypeCode.Single:
                                case TypeCode.Double:
+                               case TypeCode.Char:
+                               case TypeCode.Byte:
+                               case TypeCode.SByte:
+                               case TypeCode.Int16:
+                               case TypeCode.UInt16:
+                               case TypeCode.Int32:
+                               case TypeCode.UInt32:
                                case TypeCode.String:
                                        return ic1.ToString (null) + ic2.ToString (null);
+
+                               case TypeCode.Empty:
+                                       return ic1.ToString (null);
+
+                               case TypeCode.DBNull:
+                                       return ic1.ToString (null) + "null";
                                }
                                break;
                                
@@ -88,6 +102,8 @@ namespace Microsoft.JScript {
                        default:
                                return EvaluatePlus (v2, v1);
                        }
+
+                       System.Console.WriteLine ("EvaluatePlus: tc1 = {0}, tc2 = {1}", tc1, tc2);
                        throw new NotImplementedException ();
                }
 
index 09df706cbd62cb2ccc01c35481bc925dbbf67f1b..87ce0f06d00e0b2c67889fa0b6dd5b982bdb0fb3 100644 (file)
@@ -43,6 +43,46 @@ namespace Microsoft.JScript {
 
                public static bool JScriptStrictEquals (object v1, object v2)
                {
+                       IConvertible ic1 = v1 as IConvertible;
+                       IConvertible ic2 = v2 as IConvertible;
+
+                       TypeCode tc1 = Convert.GetTypeCode (v1, ic1);
+                       TypeCode tc2 = Convert.GetTypeCode (v2, ic2);
+
+                       bool both_numbers = Convert.IsNumberTypeCode (tc1) && Convert.IsNumberTypeCode (tc2);
+                       if (tc1 != tc2 && !both_numbers)
+                               return false;
+
+                       switch (tc1) {
+                       case TypeCode.DBNull:
+                       case TypeCode.Empty:
+                               return true;
+
+                       case TypeCode.Boolean:
+                               return ic1.ToBoolean (null) == ic2.ToBoolean (null);
+
+                       case TypeCode.String:
+                               return ic1.ToString (null) == ic2.ToString (null);
+
+                       default:
+                               if (both_numbers) {
+                                       double num1;
+                                       if (Convert.IsFloatTypeCode (tc1))
+                                               num1 = ic1.ToDouble (null);
+                                       else
+                                               num1 = (double) ic1.ToInt32 (null);
+
+                                       double num2;
+                                       if (Convert.IsFloatTypeCode (tc2))
+                                               num2 = ic2.ToDouble (null);
+                                       else
+                                               num2 = (double) ic2.ToInt32 (null);
+
+                                       return num1 == num2;
+                               }
+                               Console.WriteLine ("StrictEquality, tc1 = {0}, tc2 = {1}", tc1, tc2);
+                               break;
+                       }
                        throw new NotImplementedException ();
                }
 
index 53ea90bb427d07d7ce114c80c7fec1d2745e91ae..ffa0f7f00cfb82cb631649187d5c465280d25b94 100644 (file)
 
 using System;
 using Microsoft.JScript.Vsa;
+using System.Globalization;
 
 namespace Microsoft.JScript {
        
        public class StringPrototype : StringObject {
 
+               /* Note that the implementation of this HTML tag stuff is pretty dumb.
+                * It does not do any escaping of HTML characters like '<', '>' or '"' which means that you can do
+                * HTML injection via for example "foo".anchor("NAME\" style=\"font-size: 500pt;") which will result
+                * in <A NAME="NAME" style="font-size: 500pt;">, however Mozilla, Internet Explorer and Opera all do
+                * the same thing and I could not find any standard against this behavior. */
+
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject, JSBuiltin.String_anchor)]
                public static string anchor (object thisObj, object anchorName)
                {
-                       throw new NotImplementedException ();
+                       return "<A NAME=\"" + Convert.ToString (anchorName) + "\">" + Convert.ToString (thisObj) + "</A>";
                }
 
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject, JSBuiltin.String_big)]
                public static string big (object thisObj)
                {
-                       throw new NotImplementedException ();
+                       return "<BIG>" + Convert.ToString (thisObj) + "</BIG>";
                }
 
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject, JSBuiltin.String_blink)]
                public static string blink (object thisObj)
                {
-                       throw new NotImplementedException ();
+                       return "<BLINK>" + Convert.ToString (thisObj) + "</BLINK>";
                }
 
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject, JSBuiltin.String_bold)]
                public static string bold (object thisObj)
                {
-                       throw new NotImplementedException ();
+                       return "<B>" + Convert.ToString (thisObj) + "</B>";
                }
 
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject, JSBuiltin.String_charAt)]
                public static string charAt (object thisObj, double pos)
                {
-                       throw new NotImplementedException ();
+                       int _pos = Convert.ToInt32 (pos);
+                       string string_obj = Convert.ToString (thisObj);
+
+                       if (_pos < 0 || _pos >= string_obj.Length)
+                               return "";
+
+                       return string_obj.Substring (_pos, 1);
                }
 
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject, JSBuiltin.String_charCodeAt)]
-               public static object charCodeAt (object thisObj, double pos)
+               public static object charCodeAt (object thisObj, double arg)
                {
-                       throw new NotImplementedException ();
+                       int pos = Convert.ToInt32 (arg);
+                       string string_obj = Convert.ToString (thisObj);
+
+                       if (pos < 0 || pos >= string_obj.Length)
+                               return Double.NaN;
+
+                       return string_obj [pos];
                }
 
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject | JSFunctionAttributeEnum.HasVarArgs, JSBuiltin.String_concat)]
@@ -85,49 +104,83 @@ namespace Microsoft.JScript {
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject, JSBuiltin.String_fixed)]
                public static string @fixed (object thisObj)
                {
-                       throw new NotImplementedException ();
+                       return "<TT>" + Convert.ToString (thisObj) + "</TT>";
                }
 
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject, JSBuiltin.String_fontcolor)]
                public static string fontcolor (object thisObj, object colorName)
                {
-                       throw new NotImplementedException ();
+                       return "<FONT COLOR=\"" + Convert.ToString (colorName) + "\">" + Convert.ToString (thisObj) + "</FONT>";
                }
 
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject, JSBuiltin.String_fontsize)]
                public static string fontsize (object thisObj, object fontsize)
                {
-                       throw new NotImplementedException ();
+                       return "<FONT SIZE=\"" + Convert.ToString (fontsize) + "\">" + Convert.ToString (thisObj) + "</FONT>";
                }
 
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject, JSBuiltin.String_indexOf)]
                public static int indexOf (object thisObj, object searchString, double position)
                {
-                       throw new NotImplementedException ();
+                       string string_obj = Convert.ToString (thisObj);
+                       string search_obj = Convert.ToString (searchString);
+                       int pos = (int) position;
+                       if (pos < 0)
+                               pos = 0;
+                       else if (pos > string_obj.Length)
+                               pos = string_obj.Length;
+                       return string_obj.IndexOf (search_obj, pos);
                }
 
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject, JSBuiltin.String_italics)]
                public static string italics (object thisObj)
                {
-                       throw new NotImplementedException ();
+                       return "<I>" + Convert.ToString (thisObj) + "</I>";
                }
 
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject, JSBuiltin.String_lastIndexOf)]
-               public static int lastIndexOf (object thisobj, object searchString, double position)
-               {
-                       throw new NotImplementedException ();
+               public static int lastIndexOf (object thisObj, object searchString, object position)
+               {
+                       string string_obj = Convert.ToString (thisObj);
+                       string search_obj = Convert.ToString (searchString);
+                       int pos;
+                       if (position == null)
+                               pos = string_obj.Length;
+                       else {
+                               pos = Convert.ToInt32 (position);
+                               if (pos < 0)
+                                       pos = 0;
+                               else if (pos > string_obj.Length)
+                                       pos = string_obj.Length;
+                       }
+                       int result = string_obj.LastIndexOf (search_obj, pos);
+                       // string:LastIndexOf ignores matches at string start if pos is 0
+                       if (result == -1 && pos == 0 && string_obj.StartsWith (search_obj))
+                               return 0;
+                       return result;
                }
 
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject, JSBuiltin.String_link)]
                public static string link (object thisObj, object linkRef)
                {
-                       throw new NotImplementedException ();
+                       return "<A HREF=\"" + Convert.ToString (linkRef) + "\">" + Convert.ToString (thisObj) + "</A>";
                }
 
+               [MonoTODO ("I18N Needs checking -- contact flgr@ccan.de for details")]
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject, JSBuiltin.String_localeCompare)]
                public static int localeCompare (object thisObj, object thatObj)
                {
-                       throw new NotImplementedException ();
+                       // TODO FIXME I18N: Verify that we do the right thing even in border cases.
+                       string string_a = Convert.ToString (thisObj);
+                       string string_b = Convert.ToString (thatObj);
+                       int caseless_result = String.Compare (string_a, string_b, true);
+                       /* I have no idea if this is enough to fix the behavior in all cases, but it at least makes
+                        * localeCompare("abc", "ABC") work as in MS JS.NET -- this will likely be revised after
+                        * more testing. */
+                       if (caseless_result == 0)
+                               return -String.Compare (string_a, string_b, false);
+                       else
+                               return String.Compare (string_a, string_b, false);
                }
 
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject | JSFunctionAttributeEnum.HasEngine, JSBuiltin.String_match)]
@@ -151,13 +204,39 @@ namespace Microsoft.JScript {
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject, JSBuiltin.String_slice)]
                public static string slice (object thisObj, double start, object end)
                {
-                       throw new NotImplementedException ();
+                       string string_obj = Convert.ToString (thisObj);
+                       int string_len = string_obj.Length;
+                       int _start, _end;
+
+                       if (start > string_len)
+                               _start = string_len;
+                       else {
+                               _start = (int) start;
+                               if (_start < 0)
+                                       _start += string_len;
+                       }
+
+                       if (end == null)
+                               _end = string_len;
+                       else {
+                               _end = (int) (double) end;
+
+                               if (_end < 0)
+                                       _end += string_len;
+                               else if (_end > string_len)
+                                       _end = string_len;
+                       }
+
+                       if (_end < _start)
+                               _end = _start;
+
+                       return string_obj.Substring (_start, _end - _start);
                }
 
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject, JSBuiltin.String_small)]
                public static string small (object thisObj)
                {
-                       throw new NotImplementedException ();
+                       return "<SMALL>" + Convert.ToString (thisObj) + "</SMALL>";
                }
 
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject | JSFunctionAttributeEnum.HasEngine, JSBuiltin.String_split)]
@@ -168,15 +247,15 @@ namespace Microsoft.JScript {
                }
 
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject, JSBuiltin.String_strike)]
-               public static string strike (object thisOBj)
+               public static string strike (object thisObj)
                {
-                       throw new NotImplementedException ();
+                       return "<STRIKE>" + Convert.ToString (thisObj) + "</STRIKE>";
                }
 
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject, JSBuiltin.String_sub)]
                public static string sub (object thisObj)
                {
-                       throw new NotImplementedException ();
+                       return "<SUB>" + Convert.ToString (thisObj) + "</SUB>";
                }
 
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject, JSBuiltin.String_substr)]
@@ -188,31 +267,67 @@ namespace Microsoft.JScript {
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject, JSBuiltin.String_substring)]
                public static string substring (object thisObj, double start, object end)
                {
-                       throw new NotImplementedException ();
+                       string string_obj = Convert.ToString (thisObj);
+                       int string_len = string_obj.Length;
+                       int _start, _end;
+
+                       if (start == Double.NaN || start < 0)
+                               _start = 0;
+                       else if (start > string_len)
+                               _start = string_len;
+                       else
+                               _start = (int) start;
+
+                       if (end == null)
+                               _end = string_len;
+                       else {
+                               _end = (int) (double) end;
+
+                               if (_end == Double.NaN || _end < 0)
+                                       _end = 0;
+                               else if (_end > string_len)
+                                       _end = string_len;
+                       }
+
+                       if (_end < _start) {
+                               int temp = _start;
+                               _start = _end;
+                               _end = temp;
+                       }
+                       return string_obj.Substring (_start, _end - _start);
                }
 
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject, JSBuiltin.String_sup)]
                public static string sup (object thisObj)
                {
-                       throw new NotImplementedException ();
+                       return "<SUP>" + Convert.ToString (thisObj) + "</SUP>";
                }
 
+               /* TODO FIXME I18N: Somebody who is familar with locales should check if the definition of these really is
+                * this simple. */
+
+               [MonoTODO ("I18N Needs checking -- contact flgr@ccan.de for details")]
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject, JSBuiltin.String_toLocaleLowerCase)]
                public static string toLocaleLowerCase (object thisObj)
                {
-                       throw new NotImplementedException ();
+                       string string_obj = Convert.ToString (thisObj);
+                       return string_obj.ToLower ();
                }
 
+               [MonoTODO ("I18N Needs checking -- contact flgr@ccan.de for details")]
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject, JSBuiltin.String_toLocaleUpperCase)]
                public static string toLocaleUpperCase (object thisObj)
                {
-                       throw new NotImplementedException ();
+                       string string_obj = Convert.ToString (thisObj);
+                       return string_obj.ToUpper ();
                }
 
+               [MonoTODO ("I18N Needs checking -- contact flgr@ccan.de for details")]
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject, JSBuiltin.String_toLowerCase)]
                public static string toLowerCase (object thisObj)
                {
-                       throw new NotImplementedException ();
+                       string string_obj = Convert.ToString (thisObj);
+                       return string_obj.ToLower (CultureInfo.InvariantCulture);
                }
 
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject, JSBuiltin.String_toString)]
@@ -223,16 +338,18 @@ namespace Microsoft.JScript {
                        return str_obj.value;
                }
 
+               [MonoTODO ("I18N Needs checking -- contact flgr@ccan.de for details")]
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject, JSBuiltin.String_toUpperCase)]
                public static string toUpperCase (object thisObj)
                {
-                       throw new NotImplementedException ();
+                       string string_obj = Convert.ToString (thisObj);
+                       return string_obj.ToUpper (CultureInfo.InvariantCulture);
                }
 
                [JSFunctionAttribute (JSFunctionAttributeEnum.HasThisObject, JSBuiltin.String_valueOf)]
                public static object valueOf (object thisObj)
                {
-                       throw new NotImplementedException ();
+                       return toString (thisObj);
                }
        }
 }
index 5cf2a9c4e094389d40570c74f10b3f18107ec5c4..239e64b29da43492ab509f3c13613369c57415fc 100644 (file)
@@ -40,6 +40,7 @@ namespace Microsoft.JScript {
                        TypeCode tc = Convert.GetTypeCode (value, ic);
                        
                        switch (tc) {
+                       case TypeCode.Char:
                        case TypeCode.Int32:
                        case TypeCode.Double:
                                return "number";
@@ -48,7 +49,14 @@ namespace Microsoft.JScript {
                                return "string";
 
                        case TypeCode.Object:
+                       case TypeCode.DBNull:
                                return "object";
+
+                       case TypeCode.Empty:
+                               return "undefined";
+
+                       case TypeCode.Boolean:
+                               return "boolean";
                                
                        default:
                                Console.WriteLine ("TypeOf, tc = {0}", tc);