public HassiumExceptionHandler(HassiumMethod caller, HassiumMethod handler, int label)
 {
     Caller = caller;
     Handler = handler;
     Label = label;
     AddType(TypeDefinition);
 }
Ejemplo n.º 2
0
        public HassiumThread(VirtualMachine vm, HassiumMethod method, StackFrame.Frame frame)
        {
            VirtualMachine newVM = vm.Clone() as VirtualMachine;
            newVM.ExceptionReturns = new Dictionary<HassiumMethod, int>();
            newVM.Handlers = new Stack<HassiumExceptionHandler>();
            newVM.Stack = new Stack<HassiumObject>();
            newVM.StackFrame = new StackFrame();
            Thread = new Thread(() => ReturnValue = method.Invoke(newVM, frame));

            AddType(TypeDefinition);
            AddAttribute("isAlive",     new HassiumProperty(get_isAlive));
            AddAttribute("returnValue", new HassiumProperty(get_returnValue));
            AddAttribute("start",       start,  0);
            AddAttribute("stop",        stop,   0);
        }
Ejemplo n.º 3
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;
        }
Ejemplo n.º 4
0
 public HassiumClosure(HassiumMethod method, StackFrame.Frame frame)
 {
     Method = method;
     Frame = frame;
     AddType(TypeDefinition);
 }
Ejemplo n.º 5
0
        private HassiumProperty compileProperty(PropertyNode node, HassiumClass parent)
        {
            var temp = method;
            method = new HassiumMethod();
            method.Name = string.Format("get_{0}", node.Variable);
            method.IsPrivate = node.IsPrivate;
            method.SourceRepresentation = string.Format("{0} ()", method.Name);
            table.PushScope();
            node.GetBody.Visit(this);
            table.PopScope();
            HassiumMethod getBody = method;
            getBody.Parent = parent;
            getBody.ReturnType = "";
            method = new HassiumMethod();
            method.Name = string.Format("set_{0}", node.Variable);
            method.IsPrivate = node.IsPrivate;
            method.SourceRepresentation = string.Format("{0} (value)", method.Name);
            table.PushScope();
            if (!table.ContainsSymbol("value"))
                table.AddSymbol("value");
            method.Parameters.Add(new FuncParameter("value"), table.GetSymbol("value"));
            node.SetBody.Visit(this);
            table.PopScope();
            HassiumMethod setBody = method;
            setBody.Parent = parent;
            setBody.ReturnType = "";
            HassiumProperty property = new HassiumProperty(getBody, setBody);
            property.Parent = parent;
            method = temp;

            return property;
        }
Ejemplo n.º 6
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]);
 }
Ejemplo n.º 7
0
        private HassiumMethod compileFunc(FuncNode node)
        {
            if (!module.ConstantPool.ContainsKey(node.Name.GetHashCode()))
                module.ConstantPool.Add(node.Name.GetHashCode(), node.Name);

            method = new HassiumMethod();
            method.Parent = new HassiumClass();
            method.IsPrivate = node.IsPrivate;
            method.Name = node.Name;
            method.ReturnType = node.ReturnType;
            method.SourceRepresentation = node.GetSourceRepresentation();

            table.PushScope();

            foreach (var param in node.Parameters)
                method.Parameters.Add(param, table.AddSymbol(param.Name));
            if (node.Children[0] is CodeBlockNode)
                node.Children[0].VisitChildren(this);
            else
                node.Children[0].Visit(this);
            table.PopScope();
            return method;
        }
Ejemplo n.º 8
0
        private HassiumMethod compileLambda(LambdaNode node)
        {
            var temp = method;
            method = new HassiumMethod();
            method.Name = "lambda";
            method.Parent = temp.Parent;
            table.PushScope();

            foreach (AstNode param in node.Parameters.Children)
            {
                string name = ((IdentifierNode)param).Identifier;
                if (!table.ContainsSymbol(name))
                    table.AddSymbol(name);
                method.Parameters.Add(new FuncParameter(name), table.GetSymbol(name));
            }

            node.Body.VisitChildren(this);
            table.PopScope();

            var ret = method;
            method = temp;
            return ret;
        }
Ejemplo n.º 9
0
        public HassiumModule Compile(AstNode ast, SymbolTable table)
        {
            this.table = table;
            module = new HassiumModule();
            method = new HassiumMethod();

            var globalParent = new HassiumClass();
            foreach (AstNode child in ast.Children)
            {
                if (child is FuncNode)
                {
                    compileFunc(child as FuncNode);
                    method.Parent = new HassiumClass();
                    if (module.Attributes.ContainsKey(method.Name))
                    {
                        if (module.Attributes[method.Name] is HassiumMultiFunc)
                            ((HassiumMultiFunc)module.Attributes[method.Name]).Methods.Add(method);
                        else if (module.Attributes[method.Name] is HassiumMethod)
                            module.Attributes[method.Name] = new HassiumMultiFunc(new List<HassiumMethod>() { method, (HassiumMethod)module.Attributes[method.Name] });
                    }
                    else
                        module.Attributes.Add(method.Name, method);
                }
                else if (child is ClassNode)
                {
                    var clazz = compileClass(child as ClassNode);
                    clazz.Parent = globalParent;
                    module.Attributes.Add(clazz.Name, clazz);
                }
                else if (child is ExpressionStatementNode)
                {
                    if (child.Children[0] is BinaryOperationNode)
                    {
                        var binop = child.Children[0] as BinaryOperationNode;
                        if (binop.BinaryOperation == BinaryOperation.Assignment)
                        {
                            string variable = ((IdentifierNode)binop.Left).Identifier;
                            table.AddGlobalSymbol(variable);
                            var temp = method;
                            method = new HassiumMethod();
                            method.Name = variable;
                            method.SourceRepresentation = string.Format("set_{0}", variable);
                            binop.Right.Visit(this);
                            method.Emit(child.SourceLocation, InstructionType.Return);
                            module.InitialVariables.Add(table.GetGlobalSymbol(variable), method);
                            method = temp;
                        }
                    }
                }
                else if (child is TraitNode || child is PropertyNode || child is UseNode || child is EnumNode)
                    child.Visit(this);
            }
            preformInherits(module);
            return module;
        }
Ejemplo n.º 10
0
 public void Accept(TryCatchNode node)
 {
     var endLabel = nextLabel();
     var temp = method;
     method = new HassiumMethod();
     method.Name = "catch";
     table.PushScope();
     if (!table.ContainsSymbol("value"))
         table.AddSymbol("value");
     method.Parameters.Add(new FuncParameter("value"), table.GetSymbol("value"));
     node.CatchBody.VisitChildren(this);
     var handler = new HassiumExceptionHandler(temp, method, endLabel);
     if (!module.ObjectPool.ContainsKey(handler.GetHashCode()))
         module.ObjectPool.Add(handler.GetHashCode(), handler);
     method = temp;
     method.Emit(node.SourceLocation, InstructionType.PushHandler, handler.GetHashCode());
     node.TryBody.Visit(this);
     method.Emit(node.SourceLocation, InstructionType.PopHandler);
     method.EmitLabel(node.SourceLocation, endLabel);
 }
Ejemplo n.º 11
0
 public void Accept(ThreadNode node)
 {
     var temp = method;
     method = new HassiumMethod();
     method.Name = "thread";
     node.Body.Visit(this);
     if (!module.ObjectPool.ContainsKey(method.GetHashCode()))
         module.ObjectPool.Add(method.GetHashCode(), method);
     temp.Emit(node.SourceLocation, InstructionType.BuildThread, method.GetHashCode());
     if (node.RunImmediately)
     {
         int hash = "start".GetHashCode();
         if (!module.ConstantPool.ContainsKey(hash))
             module.ConstantPool.Add(hash, "start");
         temp.Emit(node.SourceLocation, InstructionType.LoadAttribute, hash);
         temp.Emit(node.SourceLocation, InstructionType.Call);
     }
     method = temp;
 }
Ejemplo n.º 12
0
 public void Accept(FuncNode node)
 {
     var temp = method;
     compileFunc(node);
     if (!module.ObjectPool.ContainsKey(method.GetHashCode()))
         module.ObjectPool.Add(method.GetHashCode(), method);
     if (!table.ContainsSymbol(method.Name))
         table.AddSymbol(method.Name);
     temp.Emit(node.SourceLocation, InstructionType.PushObject, method.GetHashCode());
     temp.Emit(node.SourceLocation, InstructionType.StoreLocal, table.GetSymbol(method.Name));
     method = temp;
 }
Ejemplo n.º 13
0
 public void Accept(ClassNode node)
 {
     var temp = method;
     var clazz = compileClass(node);
     if (!module.ObjectPool.ContainsKey(clazz.GetHashCode()))
         module.ObjectPool.Add(clazz.GetHashCode(), clazz);
     temp.Emit(node.SourceLocation, InstructionType.PushObject, clazz.GetHashCode());
     if (!table.ContainsSymbol(node.Name))
         table.AddSymbol(node.Name);
     temp.Emit(node.SourceLocation, InstructionType.StoreLocal, table.GetSymbol(node.Name));
     method = temp;
 }