Пример #1
0
 public new void AddAttribute(string name, HassiumObject obj)
 {
     obj.Parent = this;
     Attributes.Add(name, obj);
 }
Пример #2
0
 public void Modify(int index, HassiumObject value)
 {
     Frames.Peek().Modify(index, value);
 }
Пример #3
0
 public void Add(int index, HassiumObject value)
 {
     variables.Add(index, value);
 }
Пример #4
0
 public void Modify(int index, HassiumObject value)
 {
     variables[index] = value;
 }
Пример #5
0
 public void Add(int index, HassiumObject value = null)
 {
     if (Frames.Peek().ContainsVariable(index))
         Frames.Peek().variables.Remove(index);
     Frames.Peek().Add(index, value);
 }
Пример #6
0
 public void AddAttribute(string name, HassiumObject value)
 {
     Attributes.Add(name, value);
 }
Пример #7
0
 public HassiumProperty(HassiumObject get_, HassiumObject set_ = null)
 {
     Get = get_;
     Set = set_;
 }
Пример #8
0
        public HassiumObject ExecuteMethod(HassiumMethod method)
        {
            for (int pos = 0; pos < method.Instructions.Count; pos++)
            {
                if (ExceptionReturns.ContainsKey(method))
                {
                    pos = ExceptionReturns[method];
                    ExceptionReturns.Remove(method);
                }

                HassiumObject left, right, val, list;
                HassiumObject[] elements;
                string attrib;

                int arg = method.Instructions[pos].Argument;
                CurrentSourceLocation = method.Instructions[pos].SourceLocation;
                //Console.WriteLine(method.Instructions[pos].ToString());
                try
                {
                    switch (method.Instructions[pos].InstructionType)
                    {
                        case InstructionType.BinaryOperation:
                            right = Stack.Pop();
                            left = Stack.Pop();
                            interpretBinaryOperation(left, right, arg);
                            break;
                        case InstructionType.BuildClosure:
                            Stack.Push(new HassiumClosure(Stack.Pop() as HassiumMethod, StackFrame.Frames.Peek()));
                            break;
                        case InstructionType.BuildDictionary:
                            List<HassiumKeyValuePair> pairs = new List<HassiumKeyValuePair>();
                            for (int i = 0; i < arg; i++)
                                pairs.Add(Stack.Pop() as HassiumKeyValuePair);
                            Stack.Push(new HassiumDictionary(pairs));
                            break;
                        case InstructionType.BuildKeyValuePair:
                            Stack.Push(new HassiumKeyValuePair(Stack.Pop(), Stack.Pop()));
                            break;
                        case InstructionType.BuildLabel:
                            Stack.Push(new HassiumLabel(arg));
                            break;
                        case InstructionType.BuildList:
                            elements = new HassiumObject[arg];
                            for (int i = elements.Length - 1; i >= 0; i--)
                                elements[i] = Stack.Pop();
                            Stack.Push(new HassiumList(elements));
                            break;
                        case InstructionType.BuildThread:
                            Stack.Push(new HassiumThread(this, CurrentModule.ObjectPool[arg] as HassiumMethod, StackFrame.Frames.Peek()));
                            break;
                        case InstructionType.BuildTuple:
                            HassiumObject[] tupleElements = new HassiumObject[arg];
                            for (int i = 0; i < arg; i++)
                                tupleElements[i] = Stack.Pop();
                            Stack.Push(new HassiumTuple(tupleElements));
                            break;
                        case InstructionType.Call:
                            val = Stack.Pop();
                            elements = new HassiumObject[arg];
                            for (int i = elements.Length - 1; i >= 0; i--)
                                elements[i] = Stack.Pop();
                            Stack.Push(val.Invoke(this, elements));
                            break;
                        case InstructionType.Dereference:
                            Stack.Push(((HassiumPointer)Stack.Pop()).Dereference());
                            break;
                        case InstructionType.Dispose:
                            Stack.Pop().Dispose(this);
                            break;
                        case InstructionType.Duplicate:
                            Stack.Push(Stack.Peek());
                            break;
                        case InstructionType.EnforcedAssignment:
                            var type = Globals[Stack.Pop().ToString(this).String].Type();
                            val = Stack.Pop();
                            if (!val.Types.Contains(type))
                                throw new InternalException(this, "Expcted assignment type {0}, got {1}!", type, val.Type());
                            if (StackFrame.Contains(arg))
                                StackFrame.Modify(arg, val);
                            else
                                StackFrame.Add(arg, val);
                            Stack.Push(val);
                            break;
                        case InstructionType.Goto:
                            pos = (int)Stack.Pop().ToInt(this).Int;
                            break;
                        case InstructionType.Iter:
                            Stack.Push(Stack.Pop().Iter(this));
                            break;
                        case InstructionType.IterableFull:
                            Stack.Push(Stack.Pop().IterableFull(this));
                            break;
                        case InstructionType.IterableNext:
                            Stack.Push(Stack.Pop().IterableNext(this));
                            break;
                        case InstructionType.Jump:
                            pos = method.Labels[arg];
                            break;
                        case InstructionType.JumpIfFalse:
                            if (!Stack.Pop().ToBool(this).Bool)
                                pos = method.Labels[arg];
                            break;
                        case InstructionType.JumpIfTrue:
                            if (Stack.Pop().ToBool(this).Bool)
                                pos = method.Labels[arg];
                            break;
                        case InstructionType.LoadAttribute:
                            val = Stack.Pop();
                            try
                            {
                                var attribute = val.Attributes[CurrentModule.ConstantPool[arg]];
                                if (attribute.IsPrivate)
                                {
                                    if (method.Parent != val)
                                        throw new InternalException(this, InternalException.ATTRIBUTE_ACCESS, CurrentModule.ConstantPool[arg], attribute.Parent.Type());
                                }
                                if (attribute is HassiumProperty)
                                    Stack.Push(((HassiumProperty)attribute).Get.Invoke(this));
                                else
                                    Stack.Push(attribute);
                            }
                            catch (KeyNotFoundException)
                            {
                                throw new InternalException(this, InternalException.ATTRIBUTE_NOT_FOUND, CurrentModule.ConstantPool[arg], val.Type());
                            }
                            break;
                        case InstructionType.LoadGlobal:
                            attrib = CurrentModule.ConstantPool[arg];
                            if (Globals.ContainsKey(attrib))
                                Stack.Push(Globals[attrib]);
                            else if (method.Parent != null)
                            {
                                if (method.Parent.Attributes.ContainsKey(attrib))
                                    Stack.Push(method.Parent.Attributes[attrib]);
                                else
                                    throw new InternalException(this, InternalException.VARIABLE_ERROR, attrib);
                            }
                            else
                                throw new InternalException(this, InternalException.VARIABLE_ERROR, attrib);
                            break;
                        case InstructionType.LoadGlobalVariable:
                            try
                            {
                                Stack.Push(CurrentModule.Globals[arg]);
                            }
                            catch (KeyNotFoundException)
                            {
                                throw new InternalException(this, InternalException.VARIABLE_ERROR, arg);
                            }
                            break;
                        case InstructionType.LoadListElement:
                            list = Stack.Pop();
                            Stack.Push(list.Index(this, Stack.Pop()));
                            break;
                        case InstructionType.LoadLocal:
                            Stack.Push(StackFrame.GetVariable(this, arg));
                            break;
                        case InstructionType.Pop:
                            Stack.Pop();
                            break;
                        case InstructionType.PopHandler:
                            Handlers.Pop();
                            break;
                        case InstructionType.Push:
                            Stack.Push(new HassiumInt(arg));
                            break;
                        case InstructionType.PushConstant:
                            Stack.Push(new HassiumString(CurrentModule.ConstantPool[arg]));
                            break;
                        case InstructionType.PushHandler:
                            var handler = CurrentModule.ObjectPool[arg] as HassiumExceptionHandler;
                            handler.Frame = StackFrame.Frames.Peek();
                            Handlers.Push(handler);
                            break;
                        case InstructionType.PushObject:
                            Stack.Push(CurrentModule.ObjectPool[arg]);
                            break;
                        case InstructionType.Raise:
                            RaiseException(Stack.Pop(), method, ref pos);
                            break;
                        case InstructionType.Reference:
                            Stack.Push(new HassiumPointer(StackFrame.Frames.Peek(), arg));
                            break;
                        case InstructionType.Return:
                            return Stack.Pop();
                        case InstructionType.SelfReference:
                            Stack.Push(method.Parent);
                            break;
                        case InstructionType.SetInitialAttribute:
                            attrib = Stack.Pop().ToString(this).String;
                            val = Stack.Pop();
                            var obj = Stack.Pop();
                            if (obj.Attributes.ContainsKey(attrib))
                                obj.Attributes.Remove(attrib);
                            obj.Attributes.Add(attrib, val);
                            Stack.Push(obj);
                            break;
                        case InstructionType.StoreAttribute:
                            val = Stack.Pop();
                            attrib = CurrentModule.ConstantPool[arg];
                            try
                            {
                                if (val.Attributes.ContainsKey(attrib))
                                {
                                    if (val.Attributes[attrib] is HassiumProperty)
                                    {
                                        if (((HassiumProperty)val.Attributes[attrib]).Set == null)
                                            throw new InternalException(this, InternalException.ATTRIBUTE_NOT_FOUND, string.Format("set_{0}", attrib), val.Type());
                                        ((HassiumProperty)val.Attributes[attrib]).Set.Invoke(this, Stack.Pop());
                                        break;
                                    }
                                    else
                                        val.Attributes.Remove(attrib);
                                }
                                val.Attributes.Add(attrib, Stack.Pop());
                            }
                            catch (KeyNotFoundException)
                            {
                                throw new InternalException(this, InternalException.VARIABLE_ERROR, val.Type());
                            }
                            break;
                        case InstructionType.StoreGlobalVariable:
                            CurrentModule.Globals[arg] = Stack.Pop();
                            break;
                        case InstructionType.StoreListElement:
                            Stack.Push(Stack.Pop().StoreIndex(this, Stack.Pop(), Stack.Pop()));
                            break;
                        case InstructionType.StoreLocal:
                            val = Stack.Pop();
                            if (StackFrame.Contains(arg))
                                StackFrame.Modify(arg, val);
                            else
                                StackFrame.Add(arg, val);
                            break;
                        case InstructionType.StoreReference:
                            Stack.Push(((HassiumPointer)Stack.Pop()).StoreReference(Stack.Pop()));
                            break;
                        case InstructionType.Swap:
                            int index = (int)Stack.Pop().ToInt(this).Int;
                            val = StackFrame.GetVariable(this, index);
                            StackFrame.Modify(index, StackFrame.GetVariable(this, arg));
                            StackFrame.Modify(arg, val);
                            Stack.Push(val);
                            break;
                        case InstructionType.UnaryOperation:
                            interpretUnaryOperation(Stack.Pop(), arg);
                            break;
                    }
                }
                catch (DivideByZeroException ex)
                {
                    RaiseException(new HassiumString(ex.Message), method, ref pos);
                }
                catch (FileNotFoundException ex)
                {
                    RaiseException(new HassiumString(ex.Message), method, ref pos);
                }
                catch (IOException ex)
                {
                    RaiseException(new HassiumString(ex.Message), method, ref pos);
                }
                catch (InternalException ex)
                {
                    RaiseException(new HassiumString(ex.Message), method, ref pos);
                }
                catch (Exception ex)
                {
                    throw ex;
                    RaiseException(new HassiumString(ex.Message), method, ref pos);
                }
            }
            return HassiumObject.Null;
        }
Пример #9
0
 private void interpretUnaryOperation(HassiumObject target, int op)
 {
     switch (op)
     {
         case (int)UnaryOperation.BitwiseNot:
             Stack.Push(target.BitwiseNot(this));
             break;
         case (int)UnaryOperation.LogicalNot:
             Stack.Push(target.LogicalNot(this));
             break;
         case (int)UnaryOperation.Negate:
             Stack.Push(target.Negate(this));
             break;
     }
 }
Пример #10
0
 private void interpretBinaryOperation(HassiumObject left, HassiumObject right, int op)
 {
     switch (op)
     {
         case (int)BinaryOperation.Addition:
             Stack.Push(left.Add(this, right));
             break;
         case (int)BinaryOperation.BitshiftLeft:
             Stack.Push(left.BitshiftLeft(this, right));
             break;
         case (int)BinaryOperation.BitshiftRight:
             Stack.Push(left.BitshiftRight(this, right));
             break;
         case (int)BinaryOperation.BitwiseAnd:
             Stack.Push(left.BitwiseAnd(this, right));
             break;
         case (int)BinaryOperation.BitwiseOr:
             Stack.Push(left.BitwiseOr(this, right));
             break;
         case (int)BinaryOperation.BitwiseXor:
             Stack.Push(left.BitwiseXor(this, right));
             break;
         case (int)BinaryOperation.Division:
             Stack.Push(left.Divide(this, right));
             break;
         case (int)BinaryOperation.EqualTo:
             Stack.Push(left.EqualTo(this, right));
             break;
         case (int)BinaryOperation.GreaterThan:
             Stack.Push(left.GreaterThan(this, right));
             break;
         case (int)BinaryOperation.GreaterThanOrEqual:
             Stack.Push(left.GreaterThanOrEqual(this, right));
             break;
         case (int)BinaryOperation.IntegerDivision:
             Stack.Push(left.IntegerDivision(this, right));
             break;
         case (int)BinaryOperation.Is:
             if (right is HassiumTrait)
                 Stack.Push(((HassiumTrait)right).Is(this, left));
             else
                 Stack.Push(new HassiumBool(left.Types.Contains(right.Type())));
             break;
         case (int)BinaryOperation.LesserThan:
             Stack.Push(left.LesserThan(this, right));
             break;
         case (int)BinaryOperation.LesserThanOrEqual:
             Stack.Push(left.LesserThanOrEqual(this, right));
             break;
         case (int)BinaryOperation.LogicalAnd:
             Stack.Push(left.LogicalAnd(this, right));
             break;
         case (int)BinaryOperation.LogicalOr:
             Stack.Push(left.LogicalOr(this, right));
             break;
         case (int)BinaryOperation.Modulus:
             Stack.Push(left.Modulus(this, right));
             break;
         case (int)BinaryOperation.Multiplication:
             Stack.Push(left.Multiply(this, right));
             break;
         case (int)BinaryOperation.NotEqualTo:
             Stack.Push(left.NotEqualTo(this, right));
             break;
         case (int)BinaryOperation.NullCoalescing:
             if (left == HassiumObject.Null || left == null)
                 Stack.Push(right);
             else
                 Stack.Push(left);
             break;
         case (int)BinaryOperation.Power:
             Stack.Push(left.Power(this, right));
             break;
         case (int)BinaryOperation.Subraction:
             Stack.Push(left.Subtract(this, right));
             break;
     }
 }
Пример #11
0
 public void RaiseException(HassiumObject message, HassiumMethod method, ref int pos)
 {
     if (Handlers.Count == 0)
         throw new InternalException(this, message.ToString(this).String);
     var handler = Handlers.Peek();
     handler.Invoke(this, message);
     ExceptionReturns.Add(handler.Caller, handler.Caller.Labels[handler.Label]);
 }
Пример #12
0
 private void preformInherits(HassiumObject obj)
 {
     foreach (var attrib in obj.Attributes.Values)
     {
         if (attrib is HassiumClass)
         {
             var clazz = attrib as HassiumClass;
             foreach (string inherit in clazz.Inherits)
                 if (module.Attributes.ContainsKey(inherit))
                 {
                     foreach (var pair in module.Attributes[inherit].Attributes)
                         if (!clazz.Attributes.ContainsKey(pair.Key))
                         {
                             var val = pair.Value.Clone() as HassiumObject;
                             val.Parent = clazz;
                             clazz.Attributes.Add(pair.Key, val);
                         }
                 }
                 else if (clazz.Parent.Attributes.ContainsKey(inherit))
                 {
                     foreach (var pair in clazz.Parent.Attributes[inherit].Attributes)
                         if (!clazz.Attributes.ContainsKey(pair.Key))
                         {
                             var val = pair.Value.Clone() as HassiumObject;
                             val.Parent = clazz;
                             clazz.Attributes.Add(pair.Key, val);
                         }
                 }
             preformInherits(clazz);
         }
     }
 }