Пример #1
0
        public override AstNode Visit(LockStatement node)
        {
            // Begin the node.
            builder.BeginNode(node);

            // Push the scope.
            PushScope(node.GetScope());

            // Visit the children.
            VisitList(node.GetChildren());

            // Pop the scope.
            PopScope();

            return builder.EndNode();
        }
Пример #2
0
        public override AstNode Visit(LockStatement node)
        {
            // Push the scope.
            PushScope(node.GetScope());

            // Visit the children.
            VisitList(node.GetChildren());

            // Pop the scope.
            PopScope();

            return node;
        }
Пример #3
0
        public override AstNode Visit(LockStatement node)
        {
            // Create the block lexical scope.
            LexicalScope blockScope = CreateLexicalScope(node);
            node.SetScope(blockScope);

            // Push the scope.
            PushScope(blockScope);

            // Visit the mutex expression.
            Expression mutexExpr = node.GetMutexExpression();
            mutexExpr.Accept(this);

            // Make sure its a reference object
            IChelaType mutexType = mutexExpr.GetNodeType();
            if(!mutexType.IsReference())
                Error(mutexExpr, "expected an object expression.");
            mutexType = DeReferenceType(mutexType);

            // Remove the variable layer.
            if(mutexType.IsReference())
                mutexType = DeReferenceType(mutexType);

            // Must be a class or an interface.
            if(!mutexType.IsClass() && !mutexType.IsInterface())
                Error(mutexExpr, "expected a class/interface instance.");

            // Create the mutex local.
            TokenPosition position = node.GetPosition();
            string mutexName = GenSym();
            AstNode decl = new LocalVariablesDeclaration(new TypeNode(TypeKind.Object, position),
                    new VariableDeclaration(mutexName, node.GetMutexExpression(), position),
                        position);

            // Chela.Threading.Monitor variable.
            TypeNode monitor = new TypeNode(TypeKind.Other, position);
            Structure threadingMonitor = (Structure)currentModule.GetThreadingMember("Monitor", true);
            if(threadingMonitor == null)
                Error(node, "couldn't use lock when the runtime doesn't define Chela.Threading.Monitor" );
            monitor.SetOtherType(threadingMonitor);

            // Enter into the mutex.
            AstNode enterMutex = new CallExpression(new MemberAccess(monitor, "Enter", position),
                                    new VariableReference(mutexName, position), position);
            decl.SetNext(enterMutex);

            // Try finally
            AstNode exitMutex = new CallExpression(new MemberAccess(monitor, "Exit", position),
                                    new VariableReference(mutexName, position), position);
            FinallyStatement finallyStmnt = new FinallyStatement(exitMutex, position);

            // Try statement.
            TryStatement tryStmnt = new TryStatement(node.GetChildren(), null, finallyStmnt, position);
            enterMutex.SetNext(tryStmnt);

            // Replace my children.
            node.SetChildren(decl);

            // Visit the block children.
            VisitList(node.GetChildren());

            // Restore the scope.
            PopScope();

            return node;
        }