Example #1
0
 internal static void ArrayOrHashSet(
     VmApi api, ref Value arrayOrHashOrString, ref Value index, ref Value value)
 {
     if (arrayOrHashOrString.Kind == Value.Kinds.Array)
     {
         if (index.Kind == Value.Kinds.Integer)
         {
             arrayOrHashOrString.ArrayValue [(int)index.IntegerValue] = value;
             arrayOrHashOrString = value;
         }
         else
         {
             api.RaiseShovelError("Setting an array element requires an integer index.");
         }
     }
     else if (arrayOrHashOrString.Kind == Value.Kinds.Hash)
     {
         if (index.Kind == Value.Kinds.String)
         {
             arrayOrHashOrString.HashValue [index] = value;
             arrayOrHashOrString = value;
         }
         else
         {
             api.RaiseShovelError("Setting a hash table value requires a key that is a string.");
         }
     }
     else
     {
         api.RaiseShovelError("First argument must be a hash or an array.");
     }
 }
Example #2
0
        static Value HashConstructor(VmApi api, Value[] args, int start, int length)
        {
            if (args.Length % 2 != 0)
            {
                api.RaiseShovelError("Must provide an even number of arguments.");
            }
            var sizeIncrease = 1 + 2 * args.Length;

            api.CellsIncrementHerald(sizeIncrease);
            var result = new Dictionary <Value, Value> ();

            for (var i = start; i < start + length; i += 2)
            {
                if (args [i].Kind == Value.Kinds.String)
                {
                    result [args [i]] = args [i + 1];
                }
                else
                {
                    api.RaiseShovelError("Keys must be strings");
                }
            }
            api.CellsIncrementer(sizeIncrease);
            return(Value.Make(result));
        }
Example #3
0
 static void AdjustRealStartEnd(VmApi api, ref int realStart, ref int realEnd, int length)
 {
     if (realStart < 0)
     {
         realStart += length;
     }
     if (realEnd < 0)
     {
         realEnd += length + 1;
     }
     if (realStart > realEnd)
     {
         api.RaiseShovelError(String.Format(
                                  "Starting index ({0}) is larger than ending index ({1}).",
                                  realStart, realEnd)
                              );
     }
     if (realStart < 0)
     {
         api.RaiseShovelError(String.Format(
                                  "Starting index ({0}) is less than 0.", realStart)
                              );
     }
     if (realEnd > length)
     {
         api.RaiseShovelError(String.Format(
                                  "End index ({0}) is larger than the length of the sequence ({1}).",
                                  realEnd, length)
                              );
     }
 }
Example #4
0
 static void CheckString(VmApi api, Value str)
 {
     if (str.Kind != Value.Kinds.String)
     {
         api.RaiseShovelError("Argument must be a string.");
     }
 }
Example #5
0
        static Value EncodeTime(VmApi api, Value hash)
        {
            if (hash.Kind != Value.Kinds.Hash)
            {
                api.RaiseShovelError("Argument must be a valid time hash (as returned by 'decodeTime').");
            }
            CheckBoundedInteger(
                api, hash, "second", 0, 59,
                "Argument must be a valid time hash (as returned by 'decodeTime') - invalid second '{0}'.");
            CheckBoundedInteger(
                api, hash, "minute", 0, 59,
                "Argument must be a valid time hash (as returned by 'decodeTime') - invalid minute '{0}'.");
            CheckBoundedInteger(
                api, hash, "hour", 0, 59,
                "Argument must be a valid time hash (as returned by 'decodeTime') - invalid hour '{0}'.");
            CheckBoundedInteger(
                api, hash, "day", 1, 31,
                "Argument must be a valid time hash (as returned by 'decodeTime') - invalid day '{0}'.");
            CheckBoundedInteger(
                api, hash, "month", 1, 12,
                "Argument must be a valid time hash (as returned by 'decodeTime') - invalid month '{0}'.");
            var date = new DateTime(
                (int)hash.HashValue [Value.Make("year")].IntegerValue,
                (int)hash.HashValue [Value.Make("month")].IntegerValue,
                (int)hash.HashValue [Value.Make("day")].IntegerValue,
                (int)hash.HashValue [Value.Make("hour")].IntegerValue,
                (int)hash.HashValue [Value.Make("minute")].IntegerValue,
                (int)hash.HashValue [Value.Make("second")].IntegerValue);

            return(Value.MakeInt((long)(date - unixEpoch).TotalSeconds));
        }
Example #6
0
 static void CheckVector(VmApi api, ref Value vector)
 {
     if (vector.Kind != Value.Kinds.Array)
     {
         api.RaiseShovelError("First argument must be a vector.");
     }
 }
Example #7
0
        internal static Value ShovelStringRepresentation(VmApi api, Value obj)
        {
            var result = Value.Make(ShovelStringRepresentationImpl(api, obj, new HashSet <object> ()));

            api.CellsIncrementer(result.StringValue.Length);
            return(result);
        }
Example #8
0
        static Value ArrayConstructor(VmApi api, Value[] args, int start, int length)
        {
            var result = new List <Value> ();

            for (var i = start; i < start + length; i++)
            {
                result.Add(args [i]);
            }
            return(Value.Make(result));
        }
Example #9
0
 internal static void LogicalNot(VmApi api, ref Value argument)
 {
     if (argument.Kind == Value.Kinds.Bool)
     {
         argument.BoolValue = !argument.BoolValue;
     }
     else
     {
         api.RaiseShovelError("Argument must be boolean.");
     }
 }
Example #10
0
 internal static void BitwiseXor(VmApi api, ref Value t1, ref Value t2)
 {
     if (t1.Kind == Value.Kinds.Integer && t2.Kind == Value.Kinds.Integer)
     {
         t1.IntegerValue = t1.IntegerValue ^ t2.IntegerValue;
     }
     else
     {
         api.RaiseShovelError("Both arguments must be integers.");
     }
 }
Example #11
0
        internal static void ArrayPop(VmApi api, ref Value array)
        {
            CheckVector(api, ref array);
            var vector = array.ArrayValue;

            if (vector.Count == 0)
            {
                api.RaiseShovelError("Can't pop from an empty array.");
            }
            array = vector [vector.Count - 1];
            vector.RemoveAt(vector.Count - 1);
        }
Example #12
0
        internal static void Keys(VmApi api, ref Value hash)
        {
            if (hash.Kind != Value.Kinds.Hash)
            {
                api.RaiseShovelError("First argument must be a hash table.");
            }
            var result = new List <Value> ();

            result.AddRange(hash.HashValue.Keys);
            hash.ArrayValue = result;
            hash.Kind       = Value.Kinds.Array;
        }
Example #13
0
 internal static void HasKey(VmApi api, ref Value hash, ref Value key)
 {
     if (hash.Kind != Value.Kinds.Hash)
     {
         api.RaiseShovelError("First argument must be a hash table.");
     }
     if (key.Kind != Value.Kinds.String)
     {
         api.RaiseShovelError("Second argument must be a string.");
     }
     hash.BoolValue = hash.HashValue.ContainsKey(key);
     hash.Kind      = Value.Kinds.Bool;
 }
Example #14
0
        static Value SizedArrayConstructor(VmApi api, Value size)
        {
            if (size.Kind != Value.Kinds.Integer)
            {
                api.RaiseShovelError("Argument must be an integer.");
            }
            var result = new List <Value> ();

            for (var i = 0; i < size.IntegerValue; i++)
            {
                result.Add(Value.Make());
            }
            return(Value.Make(result));
        }
Example #15
0
        static Value DecodeTime(VmApi api, Value timeInSeconds)
        {
            if (timeInSeconds.Kind != Value.Kinds.Integer)
            {
                api.RaiseShovelError("Argument must be an integer.");
            }
            var epochTimeSpan = TimeSpan.FromSeconds(timeInSeconds.IntegerValue);
            var date          = Prim0.unixEpoch + epochTimeSpan;
            var result        = new Dictionary <Value, Value> ();

            result [Value.Make("year")]  = Value.MakeInt(date.Year);
            result [Value.Make("month")] = Value.MakeInt(date.Month);
            result [Value.Make("day")]   = Value.MakeInt(date.Day);
            var dayOfWeekKey = Value.Make("dayOfWeek");

            switch (date.DayOfWeek)
            {
            case DayOfWeek.Monday:
                result [dayOfWeekKey] = Value.MakeInt(1);
                break;

            case DayOfWeek.Tuesday:
                result [dayOfWeekKey] = Value.MakeInt(2);
                break;

            case DayOfWeek.Wednesday:
                result [dayOfWeekKey] = Value.MakeInt(3);
                break;

            case DayOfWeek.Thursday:
                result [dayOfWeekKey] = Value.MakeInt(4);
                break;

            case DayOfWeek.Friday:
                result [dayOfWeekKey] = Value.MakeInt(5);
                break;

            case DayOfWeek.Saturday:
                result [dayOfWeekKey] = Value.MakeInt(6);
                break;

            case DayOfWeek.Sunday:
                result [dayOfWeekKey] = Value.MakeInt(7);
                break;
            }
            result [Value.Make("hour")]   = Value.MakeInt(date.Hour);
            result [Value.Make("minute")] = Value.MakeInt(date.Minute);
            result [Value.Make("second")] = Value.MakeInt(date.Second);
            return(Value.Make(result));
        }
Example #16
0
 internal static void UnaryMinus(VmApi api, ref Value t1)
 {
     if (t1.Kind == Value.Kinds.Integer)
     {
         t1.IntegerValue = -t1.IntegerValue;
     }
     else if (t1.Kind == Value.Kinds.Double)
     {
         t1.DoubleValue = -t1.DoubleValue;
     }
     else
     {
         api.RaiseShovelError("Argument must be number.");
     }
 }
Example #17
0
 internal static void Floor(VmApi api, ref Value t1)
 {
     if (t1.Kind == Value.Kinds.Double)
     {
         t1.Kind         = Value.Kinds.Integer;
         t1.IntegerValue = (long)Math.Floor(t1.DoubleValue);
     }
     else if (t1.Kind == Value.Kinds.Integer)
     {
     }
     else
     {
         api.RaiseShovelError("Argument must be number.");
     }
 }
Example #18
0
        internal static void GreaterThanOrEqual(VmApi api, ref Value t1, ref Value t2)
        {
            switch (t1.Kind)
            {
            case Value.Kinds.Integer:
                if (t2.Kind == Value.Kinds.Integer)
                {
                    t1.BoolValue = t1.IntegerValue >= t2.IntegerValue;
                }
                else if (t2.Kind == Value.Kinds.Double)
                {
                    t1.BoolValue = t1.IntegerValue >= t2.DoubleValue;
                }
                else
                {
                    LessThanError(api);
                }
                break;

            case Value.Kinds.String:
                if (t2.Kind == Value.Kinds.String)
                {
                    var comparison = CompareStrings(t1.StringValue, t2.StringValue);
                    t1.BoolValue = comparison == 1 || comparison == 0;
                }
                else
                {
                    LessThanError(api);
                }
                break;

            case Value.Kinds.Double:
                if (t2.Kind == Value.Kinds.Double)
                {
                    t1.BoolValue = t1.DoubleValue >= t2.DoubleValue;
                }
                else if (t2.Kind == Value.Kinds.Integer)
                {
                    t1.BoolValue = t1.DoubleValue >= t2.IntegerValue;
                }
                else
                {
                    LessThanError(api);
                }
                break;
            }
            t1.Kind = Value.Kinds.Bool;
        }
Example #19
0
 internal static void HashGetDot(VmApi api, ref Value hash, ref Value index)
 {
     if (hash.Kind != Value.Kinds.Hash)
     {
         api.RaiseShovelError("First argument must be a hash table.");
     }
     if (index.Kind != Value.Kinds.String)
     {
         api.RaiseShovelError("Second argument must be a string.");
     }
     if (!hash.HashValue.ContainsKey(index))
     {
         api.RaiseShovelError("Key not found in hash table.");
     }
     hash = hash.HashValue [index];
 }
Example #20
0
        internal static void LessThan(VmApi api, ref Value t1, ref Value t2)
        {
            switch (t1.Kind)
            {
            case Value.Kinds.Integer:
                if (t2.Kind == Value.Kinds.Integer)
                {
                    t1.BoolValue = t1.IntegerValue < t2.IntegerValue;
                }
                else if (t2.Kind == Value.Kinds.Double)
                {
                    t1.BoolValue = t1.IntegerValue < t2.DoubleValue;
                }
                else
                {
                    LessThanError(api);
                }
                break;

            case Value.Kinds.String:
                if (t2.Kind == Value.Kinds.String)
                {
                    t1.BoolValue = CompareStrings(t1.StringValue, t2.StringValue) == -1;
                }
                else
                {
                    LessThanError(api);
                }
                break;

            case Value.Kinds.Double:
                if (t2.Kind == Value.Kinds.Double)
                {
                    t1.BoolValue = t1.DoubleValue < t2.DoubleValue;
                }
                else if (t2.Kind == Value.Kinds.Integer)
                {
                    t1.BoolValue = t1.DoubleValue < t2.IntegerValue;
                }
                else
                {
                    LessThanError(api);
                }
                break;
            }
            t1.Kind = Value.Kinds.Bool;
        }
Example #21
0
 internal static void GetLength(VmApi api, ref Value arrayOrString)
 {
     if (arrayOrString.Kind == Value.Kinds.Array)
     {
         arrayOrString.Kind         = Value.Kinds.Integer;
         arrayOrString.IntegerValue = arrayOrString.ArrayValue.Count;
     }
     else if (arrayOrString.Kind == Value.Kinds.String)
     {
         arrayOrString.Kind         = Value.Kinds.Integer;
         arrayOrString.IntegerValue = (long)arrayOrString.StringValue.Length;
     }
     else
     {
         api.RaiseShovelError("Argument must be a string or an array.");
     }
 }
Example #22
0
 private static string ShovelStringRepresentationImpl(
     VmApi api, Value obj, HashSet <object> visited)
 {
     if (visited.Contains(obj))
     {
         return("[...loop...]");
     }
     else if (obj.Kind == Value.Kinds.String)
     {
         return(String.Format("\"{0}\"", obj.StringValue.Replace("\"", "\\\"")));
     }
     else if (obj.Kind == Value.Kinds.Array)
     {
         visited.Add(obj);
         var stringReps = obj.ArrayValue
                          .Select(elem => ShovelStringRepresentationImpl(api, elem, visited));
         return(String.Format("array({0})", String.Join(", ", stringReps)));
     }
     else if (obj.Kind == Value.Kinds.Hash)
     {
         visited.Add(obj);
         var stringReps = new List <string> ();
         foreach (var key in obj.HashValue.Keys)
         {
             stringReps.Add((string)ShovelStringRepresentationImpl(api, key, visited));
             stringReps.Add((string)ShovelStringRepresentationImpl(api, obj.HashValue [key], visited));
         }
         return(String.Format("hash({0})", String.Join(", ", stringReps)));
     }
     else if (obj.Kind == Value.Kinds.Null ||
              obj.Kind == Value.Kinds.Integer ||
              obj.Kind == Value.Kinds.Double ||
              obj.Kind == Value.Kinds.Bool ||
              obj.Kind == Value.Kinds.Callable)
     {
         return(ShovelStringImpl(api, obj));
     }
     else
     {
         UnknownTypeError(api);
     }
     return(null);
 }
Example #23
0
 internal static void Divide(VmApi api, ref Value t1, ref Value t2)
 {
     if (t1.Kind == Value.Kinds.Integer)
     {
         if (t2.Kind == Value.Kinds.Integer)
         {
             t1.Kind         = Value.Kinds.Integer;
             t1.IntegerValue = t1.IntegerValue / t2.IntegerValue;
         }
         else if (t2.Kind == Value.Kinds.Double)
         {
             t1.Kind        = Value.Kinds.Double;
             t1.DoubleValue = t1.IntegerValue / t2.DoubleValue;
         }
         else
         {
             BothNumbersError(api);
         }
     }
     else if (t1.Kind == Value.Kinds.Double)
     {
         if (t2.Kind == Value.Kinds.Double)
         {
             t1.Kind        = Value.Kinds.Double;
             t1.DoubleValue = t1.DoubleValue / t2.DoubleValue;
         }
         else if (t2.Kind == Value.Kinds.Integer)
         {
             t1.Kind        = Value.Kinds.Double;
             t1.DoubleValue = t1.DoubleValue / t2.IntegerValue;
         }
         else
         {
             BothNumbersError(api);
         }
     }
     else
     {
         BothNumbersError(api);
     }
 }
Example #24
0
 internal static void Pow(VmApi api, ref Value t1, ref Value t2)
 {
     if (t1.Kind == Value.Kinds.Integer)
     {
         if (t2.Kind == Value.Kinds.Integer)
         {
             t1.Kind         = Value.Kinds.Integer;
             t1.IntegerValue = Expt(t1.IntegerValue, t2.IntegerValue);
         }
         else if (t2.Kind == Value.Kinds.Double)
         {
             t1.Kind        = Value.Kinds.Double;
             t1.DoubleValue = Math.Pow(t1.IntegerValue, t2.DoubleValue);
         }
         else
         {
             BothNumbersError(api);
         }
     }
     else if (t1.Kind == Value.Kinds.Double)
     {
         if (t2.Kind == Value.Kinds.Double)
         {
             t1.Kind        = Value.Kinds.Double;
             t1.DoubleValue = Math.Pow(t1.DoubleValue, t2.DoubleValue);
         }
         else if (t2.Kind == Value.Kinds.Integer)
         {
             t1.Kind        = Value.Kinds.Double;
             t1.DoubleValue = Math.Pow(t1.DoubleValue, t2.IntegerValue);
         }
         else
         {
             BothNumbersError(api);
         }
     }
     else
     {
         BothNumbersError(api);
     }
 }
Example #25
0
        static void CheckBoundedInteger(
            VmApi api,
            Value hash, string key,
            long min, long max, string errorMessageFormat)
        {
            var shKey = Value.Make(key);

            if (!hash.HashValue.ContainsKey(shKey))
            {
                api.RaiseShovelError(String.Format(errorMessageFormat, "NIL"));
            }
            var value   = hash.HashValue [shKey];
            var isValid = (value.Kind == Value.Kinds.Integer) &&
                          (value.IntegerValue >= min) &&
                          (value.IntegerValue <= max);

            if (!isValid)
            {
                api.RaiseShovelError(String.Format(errorMessageFormat, value));
            }
        }
Example #26
0
 static string ShovelStringImpl(VmApi api, Value obj)
 {
     if (obj.Kind == Value.Kinds.String)
     {
         return(obj.StringValue);
     }
     else if (obj.Kind == Value.Kinds.Array)
     {
         return("[...array...]");
     }
     else if (obj.Kind == Value.Kinds.Integer)
     {
         return(obj.IntegerValue.ToString(CultureInfo.InvariantCulture));
     }
     else if (obj.Kind == Value.Kinds.Double)
     {
         return(obj.DoubleValue.ToString(CultureInfo.InvariantCulture));
     }
     else if (obj.Kind == Value.Kinds.Hash)
     {
         return("[...hash...]");
     }
     else if (obj.Kind == Value.Kinds.Callable)
     {
         return("[...callable...]");
     }
     else if (obj.Kind == Value.Kinds.Bool)
     {
         return(obj.BoolValue.ToString().ToLower());
     }
     else if (obj.Kind == Value.Kinds.Null)
     {
         return("null");
     }
     else
     {
         UnknownTypeError(api);
     }
     throw new InvalidOperationException();
 }
Example #27
0
 static Value GetSlice(VmApi api, Value arrayOrString, Value start, Value end)
 {
     if (start.Kind != Value.Kinds.Integer)
     {
         api.RaiseShovelError("The start index must be an integer.");
         throw new InvalidOperationException();
     }
     if (end.Kind != Value.Kinds.Integer)
     {
         api.RaiseShovelError("The end index must be an integer.");
         throw new InvalidOperationException();
     }
     if (arrayOrString.Kind == Value.Kinds.Array)
     {
         var length    = arrayOrString.ArrayValue.Count;
         var realStart = (int)start.IntegerValue;
         var realEnd   = (int)end.IntegerValue;
         AdjustRealStartEnd(api, ref realStart, ref realEnd, length);
         return(Value.Make(
                    arrayOrString.ArrayValue.GetRange(realStart, realEnd - realStart)));
     }
     else if (arrayOrString.Kind == Value.Kinds.String)
     {
         var length    = arrayOrString.StringValue.Length;
         var realStart = (int)start.IntegerValue;
         var realEnd   = (int)end.IntegerValue;
         AdjustRealStartEnd(api, ref realStart, ref realEnd, length);
         return(Value.Make(
                    arrayOrString.StringValue.Substring(realStart, realEnd - realStart)));
     }
     else
     {
         api.RaiseShovelError("Argument must be a string or an array.");
         throw new InvalidOperationException();
     }
 }
Example #28
0
 static void CheckBoundedInteger(
     VmApi api, 
     Value hash, string key, 
     long min, long max, string errorMessageFormat)
 {
     var shKey = Value.Make (key);
     if (!hash.hashValue.ContainsKey (shKey)) {
         api.RaiseShovelError (String.Format (errorMessageFormat, "NIL"));
     }
     var value = hash.hashValue [shKey];
     var isValid = (value.Kind == Value.Kinds.Integer)
         && (value.integerValue >= min)
         && (value.integerValue <= max);
     if (!isValid) {
         api.RaiseShovelError (String.Format (errorMessageFormat, value));
     }
 }
Example #29
0
 static void AreEqualError(VmApi api)
 {
     api.RaiseShovelError (
                 "Arguments must have the same type (numbers or strings), or at least one must be null.");
 }
Example #30
0
 static void BothNumbersError(VmApi api)
 {
     api.RaiseShovelError ("Both arguments must be numbers.");
 }
Example #31
0
 internal static void IsCallable(VmApi api, ref Value obj)
 {
     obj.boolValue = obj.Kind == Value.Kinds.Callable;
     obj.Kind = Value.Kinds.Bool;
 }
Example #32
0
        internal static void Add(VmApi api, ref Value t1, ref Value t2)
        {
            switch (t1.Kind)
            {
            case Value.Kinds.Integer:
                switch (t2.Kind)
                {
                case Value.Kinds.Integer:
                    t1.Kind         = Value.Kinds.Integer;
                    t1.IntegerValue = t1.IntegerValue + t2.IntegerValue;
                    break;

                case Value.Kinds.Double:
                    t1.Kind        = Value.Kinds.Double;
                    t1.DoubleValue = t1.IntegerValue + t2.DoubleValue;
                    break;

                default:
                    AddError(api);
                    break;
                }
                break;

            case Value.Kinds.Double:
                switch (t2.Kind)
                {
                case Value.Kinds.Integer:
                    t1.Kind        = Value.Kinds.Double;
                    t1.DoubleValue = t1.DoubleValue + t2.IntegerValue;
                    break;

                case Value.Kinds.Double:
                    t1.Kind        = Value.Kinds.Double;
                    t1.DoubleValue = t1.DoubleValue + t2.DoubleValue;
                    break;

                default:
                    AddError(api);
                    break;
                }
                break;

            case Value.Kinds.String:
                if (t2.Kind == Value.Kinds.String)
                {
                    t1.Kind        = Value.Kinds.String;
                    t1.StringValue = t1.StringValue + t2.StringValue;
                }
                else
                {
                    AddError(api);
                }
                break;

            case Value.Kinds.Array:
                if (t2.Kind == Value.Kinds.Array)
                {
                    var result = new List <Value> ();
                    result.AddRange(t1.ArrayValue);
                    result.AddRange(t2.ArrayValue);
                    t1.Kind       = Value.Kinds.Array;
                    t1.ArrayValue = result;
                }
                else
                {
                    AddError(api);
                }
                break;

            default:
                AddError(api);
                break;
            }
        }
Example #33
0
 static void CheckVector(VmApi api, ref Value vector)
 {
     if (vector.Kind != Value.Kinds.Array) {
         api.RaiseShovelError ("First argument must be a vector.");
     }
 }
Example #34
0
 internal static void LogicalNot(VmApi api, ref Value argument)
 {
     if (argument.Kind == Value.Kinds.Bool) {
         argument.boolValue = !argument.boolValue;
     } else {
         api.RaiseShovelError ("Argument must be boolean.");
     }
 }
Example #35
0
 internal static void Keys(VmApi api, ref Value hash)
 {
     if (hash.Kind != Value.Kinds.Hash) {
         api.RaiseShovelError ("First argument must be a hash table.");
     }
     var result = new ArrayInstance ();
     var sizeIncrease = 1 + hash.hashValue.Count;
     api.CellsIncrementHerald (sizeIncrease);
     result.AddRange (hash.hashValue.Keys);
     hash.arrayValue = result;
     hash.Kind = Value.Kinds.Array;
     api.CellsIncrementer (sizeIncrease);
 }
Example #36
0
 internal static void UnaryMinus(VmApi api, ref Value t1)
 {
     if (t1.Kind == Value.Kinds.Integer) {
         t1.integerValue = -t1.integerValue;
     } else if (t1.Kind == Value.Kinds.Double) {
         t1.doubleValue = -t1.doubleValue;
     } else {
         api.RaiseShovelError ("Argument must be number.");
     }
 }
Example #37
0
 static void AddError(VmApi api)
 {
     api.RaiseShovelError (
             "Arguments must have the same type (numbers or strings or arrays).");
 }
Example #38
0
 internal static bool HashOrStructDotSet(
     Vm vm, VmApi api, ref Value obj, ref Value index, ref Value value)
 {
     if (obj.Kind == Value.Kinds.StructInstance) {
         var cache = vm.GetCurrentCache ();
         var structInstance = obj.structInstanceValue;
         var ztruct = structInstance.Struct;
         if (cache != null) {
             var info = (Tuple<Struct, int>)cache;
             if (info.Item1 == ztruct) {
                 structInstance.Values [info.Item2] = value;
                 return true;
             }
         }
         int location = FindLocationInStruct (api, ztruct, index.stringValue);
         structInstance.Values [location] = value;
         vm.SetCurrentCache (Tuple.Create (ztruct, location));
     } else if (obj.Kind == Value.Kinds.Hash) {
         return HashSet(api, ref obj, ref index, ref value);
     } else {
         api.RaiseShovelError ("First argument must be a hash or a struct instance.");
     }
     return true;
 }
Example #39
0
File: Vm.cs Project: mbrezu/Shovel
 static string DumpShovelValue(VmApi api, Value obj)
 {
     if (obj.Kind == Value.Kinds.String) {
         return Prim0.ShovelStringRepresentation (api, obj).stringValue;
     } else if (obj.Kind == Value.Kinds.Array) {
         return Prim0.ShovelStringRepresentation (api, obj).stringValue;
     } else if (obj.Kind == Value.Kinds.Integer) {
         return Prim0.ShovelStringRepresentation (api, obj).stringValue;
     } else if (obj.Kind == Value.Kinds.Double) {
         return Prim0.ShovelStringRepresentation (api, obj).stringValue;
     } else if (obj.Kind == Value.Kinds.Hash) {
         return Prim0.ShovelStringRepresentation (api, obj).stringValue;
     } else if (obj.Kind == Value.Kinds.Callable) {
         return Prim0.ShovelStringRepresentation (api, obj).stringValue;
     } else if (obj.Kind == Value.Kinds.Bool) {
         return Prim0.ShovelStringRepresentation (api, obj).stringValue;
     } else if (obj.Kind == Value.Kinds.Null) {
         return Prim0.ShovelStringRepresentation (api, obj).stringValue;
     } else if (obj.Kind == Value.Kinds.ReturnAddress) {
         return String.Format ("Return to {0}", obj.ReturnAddressValue.ProgramCounter);
     } else if (obj.Kind == Value.Kinds.NamedBlock) {
         return String.Format ("Named block {0} to {0}", obj.NamedBlockValue.Name, obj.NamedBlockValue.BlockEnd);
     } else {
         throw new InvalidOperationException ();
     }
 }
Example #40
0
 static Value DecodeTime(VmApi api, Value timeInSeconds)
 {
     if (timeInSeconds.Kind != Value.Kinds.Integer) {
         api.RaiseShovelError ("Argument must be an integer.");
     }
     var epochTimeSpan = TimeSpan.FromSeconds (timeInSeconds.integerValue);
     var date = Prim0.unixEpoch + epochTimeSpan;
     var result = new HashInstance ();
     result [Value.Make ("year")] = Value.MakeInt (date.Year);
     result [Value.Make ("month")] = Value.MakeInt (date.Month);
     result [Value.Make ("day")] = Value.MakeInt (date.Day);
     var dayOfWeekKey = Value.Make ("dayOfWeek");
     switch (date.DayOfWeek) {
     case DayOfWeek.Monday:
         result [dayOfWeekKey] = Value.MakeInt (1);
         break;
     case DayOfWeek.Tuesday:
         result [dayOfWeekKey] = Value.MakeInt (2);
         break;
     case DayOfWeek.Wednesday:
         result [dayOfWeekKey] = Value.MakeInt (3);
         break;
     case DayOfWeek.Thursday:
         result [dayOfWeekKey] = Value.MakeInt (4);
         break;
     case DayOfWeek.Friday:
         result [dayOfWeekKey] = Value.MakeInt (5);
         break;
     case DayOfWeek.Saturday:
         result [dayOfWeekKey] = Value.MakeInt (6);
         break;
     case DayOfWeek.Sunday:
         result [dayOfWeekKey] = Value.MakeInt (7);
         break;
     }
     result [Value.Make ("hour")] = Value.MakeInt (date.Hour);
     result [Value.Make ("minute")] = Value.MakeInt (date.Minute);
     result [Value.Make ("second")] = Value.MakeInt (date.Second);
     api.CellsIncrementer (8);
     return Value.Make (result);
 }
Example #41
0
 internal static void ShiftRight(VmApi api, ref Value t1, ref Value t2)
 {
     if (t1.Kind == Value.Kinds.Integer && t2.Kind == Value.Kinds.Integer) {
         t1.integerValue = t1.integerValue >> (int)t2.integerValue;
     } else {
         api.RaiseShovelError ("Both arguments must be integers.");
     }
 }
Example #42
0
 static void AddError(VmApi api)
 {
     api.RaiseShovelError(
         "Arguments must have the same type (numbers or strings or arrays).");
 }
Example #43
0
 internal static void Pow(VmApi api, ref Value t1, ref Value t2)
 {
     if (t1.Kind == Value.Kinds.Integer) {
         if (t2.Kind == Value.Kinds.Integer) {
             t1.Kind = Value.Kinds.Integer;
             t1.integerValue = Expt (t1.integerValue, t2.integerValue);
         } else if (t2.Kind == Value.Kinds.Double) {
             t1.Kind = Value.Kinds.Double;
             t1.doubleValue = Math.Pow (t1.integerValue, t2.doubleValue);
         } else {
             BothNumbersError (api);
         }
     } else if (t1.Kind == Value.Kinds.Double) {
         if (t2.Kind == Value.Kinds.Double) {
             t1.Kind = Value.Kinds.Double;
             t1.doubleValue = Math.Pow (t1.doubleValue, t2.doubleValue);
         } else if (t2.Kind == Value.Kinds.Integer) {
             t1.Kind = Value.Kinds.Double;
             t1.doubleValue = Math.Pow (t1.doubleValue, t2.integerValue);
         } else {
             BothNumbersError (api);
         }
     } else {
         BothNumbersError (api);
     }
 }
Example #44
0
 internal static void IsNumber(VmApi api, ref Value obj)
 {
     obj.boolValue =
         obj.Kind == Value.Kinds.Integer || obj.Kind == Value.Kinds.Double;
     obj.Kind = Value.Kinds.Bool;
 }
Example #45
0
 internal static void LessThanOrEqual(VmApi api, ref Value t1, ref Value t2)
 {
     switch (t1.Kind) {
     case Value.Kinds.Integer:
         if (t2.Kind == Value.Kinds.Integer) {
             t1.boolValue = t1.integerValue <= t2.integerValue;
         } else if (t2.Kind == Value.Kinds.Double) {
             t1.boolValue = t1.integerValue <= t2.doubleValue;
         } else {
             RelationalError (api);
         }
         break;
     case Value.Kinds.String:
         if (t2.Kind == Value.Kinds.String) {
             var comparison = CompareStrings (t1.stringValue, t2.stringValue);
             t1.boolValue = comparison == -1 || comparison == 0;
         } else {
             RelationalError (api);
         }
         break;
     case Value.Kinds.Double:
         if (t2.Kind == Value.Kinds.Double) {
             t1.boolValue = t1.doubleValue <= t2.doubleValue;
         } else if (t2.Kind == Value.Kinds.Integer) {
             t1.boolValue = t1.doubleValue <= t2.integerValue;
         } else {
             RelationalError (api);
         }
         break;
     default:
         RelationalError(api);
         break;
     }
     t1.Kind = Value.Kinds.Bool;
 }
Example #46
0
 static void CheckString(VmApi api, Value str)
 {
     if (str.Kind != Value.Kinds.String) {
         api.RaiseShovelError ("Argument must be a string.");
     }
 }
Example #47
0
 internal static void IsStructInstance(VmApi api, ref Value obj, ref Value str)
 {
     if (str.Kind != Value.Kinds.Struct) {
         api.RaiseShovelError ("Second argument must be a struct.");
     }
     var result = obj.Kind == Value.Kinds.StructInstance && obj.structInstanceValue.Struct == str.StructValue;
     obj.boolValue = result;
     obj.Kind = Value.Kinds.Bool;
 }
Example #48
0
 internal static void Subtract(VmApi api, ref Value t1, ref Value t2)
 {
     if (t1.Kind == Value.Kinds.Integer) {
         if (t2.Kind == Value.Kinds.Integer) {
             t1.Kind = Value.Kinds.Integer;
             t1.integerValue = t1.integerValue - t2.integerValue;
         } else if (t2.Kind == Value.Kinds.Double) {
             t1.Kind = Value.Kinds.Double;
             t1.doubleValue = t1.integerValue - t2.doubleValue;
         } else {
             BothNumbersError (api);
         }
     } else if (t1.Kind == Value.Kinds.Double) {
         if (t2.Kind == Value.Kinds.Double) {
             t1.Kind = Value.Kinds.Double;
             t1.doubleValue = t1.doubleValue - t2.doubleValue;
         } else if (t2.Kind == Value.Kinds.Integer) {
             t1.Kind = Value.Kinds.Double;
             t1.doubleValue = t1.doubleValue - t2.integerValue;
         } else {
             BothNumbersError (api);
         }
     } else {
         BothNumbersError (api);
     }
 }
Example #49
0
 internal static void IsStruct(VmApi api, ref Value obj)
 {
     obj.boolValue = obj.Kind == Value.Kinds.Struct;
     obj.Kind = Value.Kinds.Bool;
 }
Example #50
0
 internal static Value ShovelStringRepresentation(VmApi api, Value obj)
 {
     var result = Value.Make (ShovelStringRepresentationImpl (api, obj, new HashSet<object> ()));
     api.CellsIncrementer (result.stringValue.Length);
     return result;
 }
Example #51
0
 internal static void IsInteger(VmApi api, ref Value obj)
 {
     obj.boolValue = obj.Kind == Value.Kinds.Integer;
     obj.Kind = Value.Kinds.Bool;
 }
Example #52
0
 internal static void IsArray(VmApi api, ref Value obj)
 {
     obj.boolValue = obj.Kind == Value.Kinds.Array;
     obj.Kind = Value.Kinds.Bool;
 }
Example #53
0
 internal static void IsHash(VmApi api, ref Value obj)
 {
     obj.boolValue = obj.Kind == Value.Kinds.Hash;
     obj.Kind = Value.Kinds.Bool;
 }
Example #54
0
 internal static bool HashOrStructGetDot(Vm vm, VmApi api, ref Value obj, ref Value index)
 {
     if (index.Kind != Value.Kinds.String) {
         api.RaiseShovelError ("Second argument must be a string.");
     }
     if (obj.Kind == Value.Kinds.StructInstance) {
         var cache = vm.GetCurrentCache ();
         var structInstance = obj.structInstanceValue;
         var ztruct = structInstance.Struct;
         if (cache != null) {
             var info = (Tuple<Struct, int>)cache;
             if (info.Item1 == ztruct) {
                 obj = structInstance.Values [info.Item2];
                 return true;
             }
         }
         int location = FindLocationInStruct (api, ztruct, index.stringValue);
         obj = structInstance.Values [location];
         vm.SetCurrentCache (Tuple.Create (ztruct, location));
     } else if (obj.Kind == Value.Kinds.Hash) {
         if (!obj.hashValue.ContainsKey (index)) {
             if (obj.hashValue.IndirectGet.Kind == Value.Kinds.Callable) {
                 return false;
             }
             else {
                 api.RaiseShovelError("Key not found in hash table.");
             }
         }
         obj = obj.hashValue [index];
     } else {
         api.RaiseShovelError ("First argument must be a struct instance or a hash table.");
     }
     return true;
 }
Example #55
0
 internal static void ArrayPush(VmApi api, ref Value array, ref Value value)
 {
     CheckVector(api, ref array);
     array.ArrayValue.Add(value);
     array = value;
 }
Example #56
0
 static Value ArrayConstructor(VmApi api, Value[] args, int start, int length)
 {
     var result = new ArrayInstance ();
     var sizeIncrease = 1 + length;
     api.CellsIncrementHerald (sizeIncrease);
     for (var i = start; i < start+length; i++) {
         result.Add (args [i]);
     }
     api.CellsIncrementer (sizeIncrease);
     return Value.Make (result);
 }
Example #57
0
 internal static void HasKey(VmApi api, ref Value hash, ref Value key)
 {
     if (hash.Kind != Value.Kinds.Hash) {
         api.RaiseShovelError ("First argument must be a hash table.");
     }
     if (key.Kind != Value.Kinds.String) {
         api.RaiseShovelError ("Second argument must be a string.");
     }
     hash.boolValue = hash.hashValue.ContainsKey (key);
     hash.Kind = Value.Kinds.Bool;
 }
Example #58
0
 internal static Value ShovelString(VmApi api, Value obj)
 {
     var result = ShovelStringImpl (api, obj);
     api.CellsIncrementer (result.Length);
     return Value.Make (result);
 }
Example #59
0
 internal static void GetLength(VmApi api, ref Value arrayOrString)
 {
     if (arrayOrString.Kind == Value.Kinds.Array) {
         arrayOrString.Kind = Value.Kinds.Integer;
         arrayOrString.integerValue = arrayOrString.arrayValue.Count;
     } else if (arrayOrString.Kind == Value.Kinds.String) {
         arrayOrString.Kind = Value.Kinds.Integer;
         arrayOrString.integerValue = (long)arrayOrString.stringValue.Length;
     } else {
         api.RaiseShovelError ("Argument must be a string or an array.");
     }
 }
Example #60
0
 static void AdjustRealStartEnd(VmApi api, ref int realStart, ref int realEnd, int length)
 {
     if (realStart < 0) {
         realStart += length;
     }
     if (realEnd < 0) {
         realEnd += length + 1;
     }
     if (realStart > realEnd) {
         api.RaiseShovelError (String.Format (
                 "Starting index ({0}) is larger than ending index ({1}).",
                 realStart, realEnd)
         );
     }
     if (realStart < 0) {
         api.RaiseShovelError (String.Format (
                 "Starting index ({0}) is less than 0.", realStart)
         );
     }
     if (realEnd > length) {
         api.RaiseShovelError (String.Format (
             "End index ({0}) is larger than the length of the sequence ({1}).",
                 realEnd, length)
         );
     }
 }